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