github.com/golang/dep@v0.5.4/cmd/dep/integration_test.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "io" 10 "io/ioutil" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "runtime" 15 "strings" 16 "testing" 17 18 "github.com/golang/dep" 19 "github.com/golang/dep/internal/test" 20 "github.com/golang/dep/internal/test/integration" 21 ) 22 23 func TestIntegration(t *testing.T) { 24 t.Parallel() 25 26 test.NeedsExternalNetwork(t) 27 test.NeedsGit(t) 28 29 wd, err := os.Getwd() 30 if err != nil { 31 t.Fatal(err) 32 } 33 34 relPath := filepath.Join("testdata", "harness_tests") 35 filepath.Walk(relPath, func(path string, info os.FileInfo, err error) error { 36 if err != nil { 37 t.Fatal("error walking filepath") 38 } 39 40 if filepath.Base(path) != "testcase.json" { 41 return nil 42 } 43 44 parse := strings.Split(path, string(filepath.Separator)) 45 testName := strings.Join(parse[2:len(parse)-1], "/") 46 t.Run(testName, func(t *testing.T) { 47 t.Parallel() 48 49 t.Run("external", testIntegration(testName, relPath, wd, execCmd)) 50 t.Run("internal", testIntegration(testName, relPath, wd, runMain)) 51 }) 52 53 return nil 54 }) 55 } 56 57 func TestDepCachedir(t *testing.T) { 58 if runtime.GOOS == "windows" { 59 // This test is unreliable on Windows and fails at random which makes it very 60 // difficult to debug. It might have something to do with parallel execution. 61 // Since the test doesn't test any specific behavior of Windows, it should be okay 62 // to skip. 63 t.Skip("skipping on windows") 64 } 65 t.Parallel() 66 67 test.NeedsExternalNetwork(t) 68 test.NeedsGit(t) 69 70 wd, err := os.Getwd() 71 if err != nil { 72 t.Fatal(err) 73 } 74 75 initPath := filepath.Join("testdata", "cachedir") 76 77 t.Run("env-invalid-cachedir", func(t *testing.T) { 78 t.Parallel() 79 testProj := integration.NewTestProject(t, initPath, wd, runMain) 80 defer testProj.Cleanup() 81 82 var d []byte 83 tmpFp := testProj.Path("tmp-file") 84 ioutil.WriteFile(tmpFp, d, 0644) 85 cases := []string{ 86 // invalid path 87 "\000", 88 // parent directory does not exist 89 testProj.Path("non-existent-fldr", "cachedir"), 90 // path is a regular file 91 tmpFp, 92 // invalid path, tmp-file is a regular file 93 testProj.Path("tmp-file", "cachedir"), 94 } 95 96 wantErr := "dep: $DEPCACHEDIR set to an invalid or inaccessible path" 97 for _, c := range cases { 98 testProj.Setenv("DEPCACHEDIR", c) 99 100 err = testProj.DoRun([]string{"ensure"}) 101 102 if err == nil { 103 // Log the output from running `dep ensure`, could be useful. 104 t.Logf("test run output: \n%s\n%s", testProj.GetStdout(), testProj.GetStderr()) 105 t.Error("unexpected result: \n\t(GOT) nil\n\t(WNT) exit status 1") 106 } else if stderr := testProj.GetStderr(); !strings.Contains(stderr, wantErr) { 107 t.Errorf( 108 "unexpected error output: \n\t(GOT) %s\n\t(WNT) %s", 109 strings.TrimSpace(stderr), wantErr, 110 ) 111 } 112 } 113 }) 114 115 } 116 117 // execCmd is a test.RunFunc which runs the program in another process. 118 func execCmd(prog string, args []string, stdout, stderr io.Writer, dir string, env []string) error { 119 cmd := exec.Command(prog, args...) 120 cmd.Stdout = stdout 121 cmd.Stderr = stderr 122 cmd.Env = env 123 cmd.Dir = dir 124 return cmd.Run() 125 } 126 127 // runMain is a test.RunFunc which runs the program in-process. 128 func runMain(prog string, args []string, stdout, stderr io.Writer, dir string, env []string) (err error) { 129 defer func() { 130 if r := recover(); r != nil { 131 switch r := r.(type) { 132 case error: 133 err = r 134 default: 135 err = fmt.Errorf("%v", r) 136 } 137 } 138 }() 139 m := &Config{ 140 Args: append([]string{prog}, args...), 141 Stdout: stdout, 142 Stderr: stderr, 143 WorkingDir: dir, 144 Env: env, 145 } 146 if exitCode := m.Run(); exitCode != 0 { 147 err = fmt.Errorf("exit status %d", exitCode) 148 } 149 return 150 } 151 152 // testIntegration runs the test specified by <wd>/<relPath>/<name>/testcase.json 153 func testIntegration(name, relPath, wd string, run integration.RunFunc) func(t *testing.T) { 154 return func(t *testing.T) { 155 t.Parallel() 156 157 testCase := integration.NewTestCase(t, filepath.Join(wd, relPath), name) 158 159 // Skip tests for disabled features 160 if testCase.RequiredFeatureFlag != "" { 161 featureEnabled, err := readFeatureFlag(testCase.RequiredFeatureFlag) 162 if err != nil { 163 t.Fatal(err) 164 } 165 166 if !featureEnabled { 167 t.Skipf("skipping %s, %s feature flag not enabled", name, testCase.RequiredFeatureFlag) 168 } 169 } 170 171 // Set up environment 172 testProj := integration.NewTestProject(t, testCase.InitialPath(), wd, run) 173 defer testProj.Cleanup() 174 175 // Create and checkout the vendor revisions 176 for ip, rev := range testCase.VendorInitial { 177 testProj.GetVendorGit(ip) 178 testProj.RunGit(testProj.VendorPath(ip), "checkout", rev) 179 } 180 181 // Create and checkout the import revisions 182 for ip, rev := range testCase.GopathInitial { 183 testProj.RunGo("get", ip) 184 testProj.RunGit(testProj.Path("src", ip), "checkout", rev) 185 } 186 187 // Run commands 188 testProj.RecordImportPaths() 189 190 var err error 191 for i, args := range testCase.Commands { 192 err = testProj.DoRun(args) 193 if err != nil && i < len(testCase.Commands)-1 { 194 t.Fatalf("cmd %s raised an unexpected error: %s", args[0], err.Error()) 195 } 196 } 197 198 if err != nil { 199 t.Log(err) 200 } 201 202 // Check error raised in final command 203 testCase.CompareCmdFailure(err != nil) 204 testCase.CompareError(err, testProj.GetStderr()) 205 206 if *test.UpdateGolden { 207 testCase.UpdateOutput(testProj.GetStdout()) 208 } else { 209 // Check output 210 testCase.CompareOutput(testProj.GetStdout()) 211 } 212 213 // Check vendor paths 214 testProj.CompareImportPaths() 215 testCase.CompareVendorPaths(testProj.GetVendorPaths()) 216 217 if *test.UpdateGolden { 218 // Update manifest and lock 219 testCase.UpdateFile(dep.ManifestName, testProj.ProjPath(dep.ManifestName)) 220 testCase.UpdateFile(dep.LockName, testProj.ProjPath(dep.LockName)) 221 } else { 222 // Check final manifest and lock 223 testCase.CompareFile(dep.ManifestName, testProj.ProjPath(dep.ManifestName)) 224 testCase.CompareFile(dep.LockName, testProj.ProjPath(dep.LockName)) 225 } 226 } 227 }