github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/testlib/resources.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package testlib 5 6 import ( 7 "fmt" 8 "io/ioutil" 9 "os" 10 "path" 11 "path/filepath" 12 13 "github.com/pkg/errors" 14 15 "github.com/mattermost/mattermost-server/v5/model" 16 "github.com/mattermost/mattermost-server/v5/services/filesstore" 17 "github.com/mattermost/mattermost-server/v5/utils" 18 "github.com/mattermost/mattermost-server/v5/utils/fileutils" 19 ) 20 21 const ( 22 resourceTypeFile = iota 23 resourceTypeFolder 24 ) 25 26 const ( 27 actionCopy = iota 28 actionSymlink 29 ) 30 31 const root = "___mattermost-server" 32 33 type testResourceDetails struct { 34 src string 35 dest string 36 resType int8 37 action int8 38 } 39 40 // getCommonBaseSearchPaths() is a custom version of what fileutils exposes. At some point, consolidate. 41 func getCommonBaseSearchPaths() []string { 42 paths := []string{ 43 ".", 44 "..", 45 "../..", 46 "../../..", 47 "../../../..", 48 } 49 50 // this enables the server to be used in tests from a different repository 51 if mmPath := os.Getenv("MM_SERVER_PATH"); mmPath != "" { 52 paths = append(paths, mmPath) 53 } 54 55 return paths 56 } 57 58 func findFile(path string) string { 59 return fileutils.FindPath(path, getCommonBaseSearchPaths(), func(fileInfo os.FileInfo) bool { 60 return !fileInfo.IsDir() 61 }) 62 } 63 64 func findDir(dir string) (string, bool) { 65 if dir == root { 66 srcPath := findFile("go.mod") 67 if srcPath == "" { 68 return "./", false 69 } 70 71 return path.Dir(srcPath), true 72 } 73 74 found := fileutils.FindPath(dir, getCommonBaseSearchPaths(), func(fileInfo os.FileInfo) bool { 75 return fileInfo.IsDir() 76 }) 77 if found == "" { 78 return "./", false 79 } 80 81 return found, true 82 } 83 84 func getTestResourcesToSetup() []testResourceDetails { 85 var srcPath string 86 var found bool 87 88 var testResourcesToSetup = []testResourceDetails{ 89 {root, "mattermost-server", resourceTypeFolder, actionSymlink}, 90 {"i18n", "i18n", resourceTypeFolder, actionSymlink}, 91 {"templates", "templates", resourceTypeFolder, actionSymlink}, 92 {"tests", "tests", resourceTypeFolder, actionSymlink}, 93 {"fonts", "fonts", resourceTypeFolder, actionSymlink}, 94 {"utils/policies-roles-mapping.json", "utils/policies-roles-mapping.json", resourceTypeFile, actionSymlink}, 95 } 96 97 // Finding resources and setting full path to source to be used for further processing 98 for i, testResource := range testResourcesToSetup { 99 if testResource.resType == resourceTypeFile { 100 srcPath = findFile(testResource.src) 101 if srcPath == "" { 102 panic(fmt.Sprintf("Failed to find file %s", testResource.src)) 103 } 104 105 testResourcesToSetup[i].src = srcPath 106 } else if testResource.resType == resourceTypeFolder { 107 srcPath, found = findDir(testResource.src) 108 if !found { 109 panic(fmt.Sprintf("Failed to find folder %s", testResource.src)) 110 } 111 112 testResourcesToSetup[i].src = srcPath 113 } else { 114 panic(fmt.Sprintf("Invalid resource type: %d", testResource.resType)) 115 } 116 } 117 118 return testResourcesToSetup 119 } 120 121 func CopyFile(src, dst string) error { 122 fileBackend, err := filesstore.NewFileBackend(filesstore.FileBackendSettings{DriverName: "local", Directory: ""}) 123 if err != nil { 124 return errors.Wrapf(err, "failed to copy file %s to %s", src, dst) 125 } 126 if err = fileBackend.CopyFile(src, dst); err != nil { 127 return errors.Wrapf(err, "failed to copy file %s to %s", src, dst) 128 } 129 return nil 130 } 131 132 func SetupTestResources() (string, error) { 133 testResourcesToSetup := getTestResourcesToSetup() 134 135 tempDir, err := ioutil.TempDir("", "testlib") 136 if err != nil { 137 return "", errors.Wrap(err, "failed to create temporary directory") 138 } 139 140 pluginsDir := path.Join(tempDir, "plugins") 141 err = os.Mkdir(pluginsDir, 0700) 142 if err != nil { 143 return "", errors.Wrapf(err, "failed to create plugins directory %s", pluginsDir) 144 } 145 146 clientDir := path.Join(tempDir, "client") 147 err = os.Mkdir(clientDir, 0700) 148 if err != nil { 149 return "", errors.Wrapf(err, "failed to create client directory %s", clientDir) 150 } 151 152 err = setupConfig(path.Join(tempDir, "config")) 153 if err != nil { 154 return "", errors.Wrap(err, "failed to setup config") 155 } 156 157 var resourceDestInTemp string 158 159 // Setting up test resources in temp. 160 // Action in each resource tells whether it needs to be copied or just symlinked 161 for _, testResource := range testResourcesToSetup { 162 resourceDestInTemp = filepath.Join(tempDir, testResource.dest) 163 164 if testResource.action == actionCopy { 165 if testResource.resType == resourceTypeFile { 166 if err = CopyFile(testResource.src, resourceDestInTemp); err != nil { 167 return "", err 168 } 169 } else if testResource.resType == resourceTypeFolder { 170 err = utils.CopyDir(testResource.src, resourceDestInTemp) 171 if err != nil { 172 return "", errors.Wrapf(err, "failed to copy folder %s to %s", testResource.src, resourceDestInTemp) 173 } 174 } 175 } else if testResource.action == actionSymlink { 176 destDir := path.Dir(resourceDestInTemp) 177 if destDir != "." { 178 err = os.MkdirAll(destDir, os.ModePerm) 179 if err != nil { 180 return "", errors.Wrapf(err, "failed to make dir %s", destDir) 181 } 182 } 183 184 err = os.Symlink(testResource.src, resourceDestInTemp) 185 if err != nil { 186 return "", errors.Wrapf(err, "failed to symlink %s to %s", testResource.src, resourceDestInTemp) 187 } 188 } else { 189 return "", errors.Wrapf(err, "Invalid action: %d", testResource.action) 190 } 191 192 } 193 194 return tempDir, nil 195 } 196 197 func setupConfig(configDir string) error { 198 var err error 199 var config model.Config 200 201 config.SetDefaults() 202 203 err = os.Mkdir(configDir, 0700) 204 if err != nil { 205 return errors.Wrapf(err, "failed to create config directory %s", configDir) 206 } 207 208 configJSON := path.Join(configDir, "config.json") 209 err = ioutil.WriteFile(configJSON, []byte(config.ToJson()), 0644) 210 if err != nil { 211 return errors.Wrapf(err, "failed to write config to %s", configJSON) 212 } 213 214 return nil 215 }