github.com/goplus/gop@v1.2.6/env/path_test.go (about) 1 /* 2 * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package env 18 19 import ( 20 "os" 21 "path/filepath" 22 "testing" 23 24 "github.com/goplus/mod" 25 ) 26 27 func findGoModFile(dir string) (modfile string, noCacheFile bool, err error) { 28 modfile, err = mod.GOMOD(dir) 29 if err != nil { 30 gopRoot, err := findGopRoot() 31 if err == nil { 32 modfile = filepath.Join(gopRoot, "go.mod") 33 return modfile, true, nil 34 } 35 } 36 return 37 } 38 39 // Common testing directory structure: 40 // testing_root/ 41 // 42 // src/ 43 // subdir/ 44 // valid_goproot/ 45 // go.mod 46 // go.sum 47 // cmd/gop/ 48 func makeTestDir(t *testing.T) (root string, src string, gopRoot string) { 49 root, _ = filepath.EvalSymlinks(t.TempDir()) 50 src = filepath.Join(root, "src") 51 gopRoot = filepath.Join(root, "valid_goproot") 52 makeValidGopRoot(gopRoot) 53 os.Mkdir(src, 0755) 54 return 55 } 56 57 func makeValidGopRoot(root string) { 58 os.Mkdir(root, 0755) 59 os.MkdirAll(filepath.Join(root, "cmd/gop"), 0755) 60 os.WriteFile(filepath.Join(root, "go.mod"), []byte(""), 0644) 61 os.WriteFile(filepath.Join(root, "go.sum"), []byte(""), 0644) 62 } 63 64 func writeDummyFile(path string) { 65 os.WriteFile(path, []byte(""), 0644) 66 } 67 68 func cleanup() { 69 os.Setenv("GOPROOT", "") 70 os.Setenv(envHOME, "") 71 defaultGopRoot = "" 72 } 73 74 func TestBasic(t *testing.T) { 75 defaultGopRoot = ".." 76 if GOPROOT() == "" { 77 t.Fatal("TestBasic failed") 78 } 79 defaultGopRoot = "" 80 } 81 82 func TestFindGoModFileInGoModDir(t *testing.T) { 83 cleanup() 84 85 t.Run("the src/ is a valid mod dir", func(tt *testing.T) { 86 tt.Cleanup(cleanup) 87 _, src, _ := makeTestDir(tt) 88 subdir := filepath.Join(src, "subdir") 89 writeDummyFile(filepath.Join(src, "go.mod")) 90 os.Mkdir(subdir, 0755) 91 92 { 93 modfile, noCacheFile, err := findGoModFile(src) 94 95 if err != nil || modfile != filepath.Join(src, "go.mod") || noCacheFile { 96 tt.Fatal("got:", modfile, noCacheFile, err) 97 } 98 } 99 100 { 101 // Should found go.mod in parent dir 102 modfile, noCacheFile, err := findGoModFile(subdir) 103 104 if err != nil || modfile != filepath.Join(src, "go.mod") || noCacheFile { 105 tt.Fatal("got:", modfile, noCacheFile, err) 106 } 107 } 108 }) 109 110 t.Run("the src/ is not a valid mod dir", func(tt *testing.T) { 111 tt.Cleanup(cleanup) 112 _, src, _ := makeTestDir(tt) 113 114 modfile, noCacheFile, err := findGoModFile(src) 115 116 if err == nil { 117 tt.Fatal("should not found the mod file, but got:", modfile, noCacheFile) 118 } 119 }) 120 } 121 122 func TestFindGoModFileInGopRoot(t *testing.T) { 123 originDir, _ := os.Getwd() 124 origiExecutable := executable 125 home := filepath.Join(os.TempDir(), "test_home") 126 os.Mkdir(home, 0755) 127 t.Cleanup(func() { 128 os.Chdir(originDir) 129 os.RemoveAll(home) 130 executable = origiExecutable 131 }) 132 133 bin := filepath.Join(home, "bin") 134 135 // Don't find go.mod in gop source dir when testing 136 os.Chdir(home) 137 138 cleanupAll := func() { 139 cleanup() 140 executable = func() (string, error) { 141 return filepath.Join(bin, "run"), nil 142 } 143 } 144 cleanupAll() 145 146 t.Run("without gop root", func(tt *testing.T) { 147 tt.Cleanup(cleanupAll) 148 root, _, _ := makeTestDir(tt) 149 150 modfile, noCacheFile, err := findGoModFile(root) 151 152 if err == nil || noCacheFile || modfile != "" { 153 tt.Fatal("should not found go.mod without gop root, got:", modfile, noCacheFile, err) 154 } 155 }) 156 157 t.Run("set GOPROOT to a valid goproot path", func(tt *testing.T) { 158 tt.Cleanup(cleanupAll) 159 _, src, gopRoot := makeTestDir(tt) 160 161 os.Setenv("GOPROOT", gopRoot) 162 modfile, noCacheFile, err := findGoModFile(src) 163 164 if err != nil || modfile != filepath.Join(gopRoot, "go.mod") || !noCacheFile { 165 tt.Fatal("should found mod file in GOPROOT, got:", modfile, noCacheFile, err) 166 } 167 }) 168 169 t.Run("set GOPROOT to an invalid goproot path", func(tt *testing.T) { 170 tt.Cleanup(cleanupAll) 171 root, src, _ := makeTestDir(tt) 172 invalidGopRoot := filepath.Join(root, "invalid_goproot") 173 174 defer func() { 175 r := recover() 176 if r == nil { 177 tt.Fatal("should panic, but not") 178 } 179 }() 180 181 os.Setenv("GOPROOT", invalidGopRoot) 182 findGoModFile(src) 183 }) 184 185 t.Run("set defaultGopRoot to a valid goproot path", func(tt *testing.T) { 186 tt.Cleanup(cleanupAll) 187 _, src, gopRoot := makeTestDir(tt) 188 189 defaultGopRoot = gopRoot 190 modfile, noCacheFile, err := findGoModFile(src) 191 192 if err != nil || modfile != filepath.Join(gopRoot, "go.mod") || !noCacheFile { 193 tt.Fatal("should found go.mod in the dir of defaultGopRoot, got:", modfile, noCacheFile, err) 194 } 195 }) 196 197 t.Run("set defaultGopRoot to an invalid path", func(tt *testing.T) { 198 tt.Cleanup(cleanupAll) 199 root, src, _ := makeTestDir(tt) 200 invalidGopRoot := filepath.Join(root, "invalid_goproot") 201 202 defaultGopRoot = invalidGopRoot 203 { 204 modfile, noCacheFile, err := findGoModFile(src) 205 206 if err == nil || noCacheFile || modfile != "" { 207 tt.Fatal("should not found go.mod when defaultGopRoot isn't exists, got:", modfile, noCacheFile, err) 208 } 209 } 210 211 { 212 os.Mkdir(invalidGopRoot, 0755) 213 modfile, noCacheFile, err := findGoModFile(src) 214 215 if err == nil || noCacheFile || modfile != "" { 216 tt.Fatal("should not found go.mod when defaultGopRoot isn't an valid gop root dir, got:", modfile, noCacheFile, err) 217 } 218 } 219 }) 220 221 t.Run("use $HOME/gop or $HOME/goplus", func(tt *testing.T) { 222 tt.Cleanup(cleanupAll) 223 root, src, _ := makeTestDir(tt) 224 home := filepath.Join(root, "home") 225 os.Mkdir(home, 0755) 226 os.Setenv(envHOME, home) 227 228 { 229 gopRoot := filepath.Join(home, "goplus") 230 makeValidGopRoot(gopRoot) 231 232 modfile, noCacheFile, err := findGoModFile(src) 233 234 if err != nil || !noCacheFile || modfile != filepath.Join(gopRoot, "go.mod") { 235 tt.Fatal("should found go.mod in $HOME/goplus, but got:", modfile, noCacheFile, err) 236 } 237 } 238 239 { 240 gopRoot := filepath.Join(home, "gop") 241 makeValidGopRoot(gopRoot) 242 243 modfile, noCacheFile, err := findGoModFile(src) 244 245 if err != nil || !noCacheFile || modfile != filepath.Join(gopRoot, "go.mod") { 246 tt.Fatal("should found go.mod in $HOME/gop, but got:", modfile, noCacheFile, err) 247 } 248 } 249 }) 250 251 t.Run("check if parent dir of the executable is valid gop root", func(tt *testing.T) { 252 tt.Cleanup(cleanupAll) 253 _, src, gopRoot := makeTestDir(tt) 254 bin := filepath.Join(gopRoot, "bin") 255 exePath := filepath.Join(bin, "run") 256 os.Mkdir(bin, 0755) 257 writeDummyFile(exePath) 258 259 // Mock executable location 260 executable = func() (string, error) { 261 return exePath, nil 262 } 263 264 modfile, noCacheFile, err := findGoModFile(src) 265 266 if err != nil || !noCacheFile || modfile != filepath.Join(gopRoot, "go.mod") { 267 tt.Fatal("should found go.mod in gopRoot, but got:", modfile, noCacheFile, err) 268 } 269 }) 270 271 t.Run("test gop root priority", func(tt *testing.T) { 272 tt.Cleanup(cleanupAll) 273 root, src, _ := makeTestDir(tt) 274 275 tt.Run("without gop root", func(tt *testing.T) { 276 modfile, noCacheFile, err := findGoModFile(src) 277 278 if err == nil || noCacheFile || modfile != "" { 279 tt.Fatal("should not found go.mod without gop root, got:", modfile, noCacheFile, err) 280 } 281 }) 282 283 tt.Run("set HOME but hasn't $HOME/gop/ and $HOME/goplus/", func(tt *testing.T) { 284 os.Setenv(envHOME, root) 285 286 modfile, noCacheFile, err := findGoModFile(src) 287 288 if err == nil || noCacheFile || modfile != "" { 289 tt.Fatal("should not found go.mod without gop root, got:", modfile, noCacheFile, err) 290 } 291 }) 292 293 tt.Run("set HOME, and has valid $HOME/goplus/", func(tt *testing.T) { 294 gopRoot := filepath.Join(root, "goplus") 295 makeValidGopRoot(gopRoot) 296 297 modfile, noCacheFile, err := findGoModFile(src) 298 299 if err != nil || !noCacheFile || modfile != filepath.Join(gopRoot, "go.mod") { 300 tt.Fatal("should found go.mod in $HOME/goplus, but got:", modfile, noCacheFile, err) 301 } 302 }) 303 304 tt.Run("set HOME, and has valid $HOME/gop/", func(tt *testing.T) { 305 gopRoot := filepath.Join(root, "gop") 306 makeValidGopRoot(gopRoot) 307 308 modfile, noCacheFile, err := findGoModFile(src) 309 310 if err != nil || !noCacheFile || modfile != filepath.Join(gopRoot, "go.mod") { 311 tt.Fatal("should found go.mod in $HOME/gop, but got:", modfile, noCacheFile, err) 312 } 313 }) 314 315 tt.Run("set defaultGopRoot to an invalid gop root dir", func(tt *testing.T) { 316 gopRoot := filepath.Join(root, "gop") 317 318 defaultGopRoot = filepath.Join(root, "invalid_goproot") 319 modfile, noCacheFile, err := findGoModFile(src) 320 321 if err != nil || !noCacheFile || modfile != filepath.Join(gopRoot, "go.mod") { 322 tt.Fatal("should found go.mod in $HOME/gop, but got:", modfile, noCacheFile, err) 323 } 324 }) 325 326 tt.Run("set defaultGopRoot to a valid gop root dir", func(tt *testing.T) { 327 newGopRoot := filepath.Join(root, "new_gop_root") 328 makeValidGopRoot(newGopRoot) 329 330 defaultGopRoot = newGopRoot 331 modfile, noCacheFile, err := findGoModFile(src) 332 333 if err != nil || !noCacheFile || modfile != filepath.Join(newGopRoot, "go.mod") { 334 tt.Fatal("should found go.mod in new_gop_root/, but got:", modfile, noCacheFile, err) 335 } 336 }) 337 338 tt.Run("the executable's parent dir is a valid gop root dir", func(tt *testing.T) { 339 newGopRoot2 := filepath.Join(root, "new_gop_root2") 340 makeValidGopRoot(newGopRoot2) 341 bin := filepath.Join(newGopRoot2, "bin") 342 exePath := filepath.Join(bin, "run") 343 os.Mkdir(bin, 0755) 344 writeDummyFile(exePath) 345 // Mock executable location 346 executable = func() (string, error) { 347 return exePath, nil 348 } 349 350 modfile, noCacheFile, err := findGoModFile(src) 351 352 if err != nil || !noCacheFile || modfile != filepath.Join(newGopRoot2, "go.mod") { 353 tt.Fatal("should found go.mod in new_gop_root2/, but got:", modfile, noCacheFile, err) 354 } 355 }) 356 357 tt.Run("set GOPROOT to an invalid gop root dir", func(tt *testing.T) { 358 newGopRoot3 := filepath.Join(root, "new_gop_root3") 359 360 defer func() { 361 r := recover() 362 if r == nil { 363 tt.Fatal("should panic, but not") 364 } 365 }() 366 367 os.Setenv("GOPROOT", newGopRoot3) 368 findGoModFile(src) 369 }) 370 371 tt.Run("set GOPROOT to a valid gop root dir", func(tt *testing.T) { 372 newGopRoot4 := filepath.Join(root, "new_gop_root4") 373 makeValidGopRoot(newGopRoot4) 374 375 os.Setenv("GOPROOT", newGopRoot4) 376 modfile, noCacheFile, err := findGoModFile(src) 377 378 if err != nil || !noCacheFile || modfile != filepath.Join(newGopRoot4, "go.mod") { 379 tt.Fatal("should found go.mod in new_gop_root3/, but got:", modfile, noCacheFile, err) 380 } 381 }) 382 }) 383 }