github.com/jdhenke/godel@v0.0.0-20161213181855-abeb3861bf0d/apps/gunit/integration_test/integration_test.go (about) 1 // Copyright 2016 Palantir Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package integration_test 16 17 import ( 18 "io/ioutil" 19 "os" 20 "os/exec" 21 "path" 22 "regexp" 23 "strings" 24 "testing" 25 26 "github.com/nmiyake/pkg/dirs" 27 "github.com/nmiyake/pkg/gofiles" 28 "github.com/palantir/pkg/pkgpath" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 32 "github.com/palantir/godel/pkg/products" 33 ) 34 35 func TestRun(t *testing.T) { 36 cli, err := products.Bin("gunit") 37 require.NoError(t, err) 38 39 wd, err := os.Getwd() 40 require.NoError(t, err) 41 42 tmpDir, cleanup, err := dirs.TempDir(wd, "") 43 defer cleanup() 44 require.NoError(t, err) 45 46 originalWd, err := os.Getwd() 47 require.NoError(t, err) 48 defer func() { 49 if err := os.Chdir(originalWd); err != nil { 50 require.NoError(t, err) 51 } 52 }() 53 54 for i, currCase := range []struct { 55 name string 56 filesToCreate []gofiles.GoFileSpec 57 config string 58 args []string 59 wantMatch func(currCaseTmpDir string) string 60 wantError string 61 }{ 62 { 63 name: "passing tests", 64 filesToCreate: []gofiles.GoFileSpec{ 65 { 66 RelPath: "foo.go", 67 Src: `package foo 68 import "fmt" 69 func Foo() { 70 fmt.Println("Foo") 71 }`, 72 }, 73 { 74 RelPath: "foo_test.go", 75 Src: `package foo 76 import "testing" 77 func TestFoo(t *testing.T) { 78 Foo() 79 }`, 80 }, 81 { 82 RelPath: "vendor/bar/bar.go", 83 Src: `package bar 84 import "fmt" 85 func Bar() { 86 fmt.Println("Bar") 87 }`, 88 }, 89 }, 90 config: unindent(`exclude: 91 paths: 92 - "vendor" 93 `), 94 wantMatch: func(currCaseTmpDir string) string { 95 return "ok \t" + pkgName(t, currCaseTmpDir) + "\t[0-9.]+s" 96 }, 97 }, 98 { 99 name: "failing tests", 100 filesToCreate: []gofiles.GoFileSpec{ 101 { 102 RelPath: "foo.go", 103 Src: `package foo 104 import "fmt" 105 func Foo() { 106 fmt.Println("Foo") 107 }`, 108 }, 109 { 110 RelPath: "foo_test.go", 111 Src: `package foo 112 import "testing" 113 func TestFoo(t *testing.T) { 114 Foo() 115 t.Errorf("myFail") 116 }`, 117 }, 118 }, 119 wantMatch: func(currCaseTmpDir string) string { 120 return `(?s)Foo\n--- FAIL: TestFoo (.+)\n.+foo_test.go:[0-9]+: myFail.+FAIL\t` + pkgName(t, currCaseTmpDir) + "\t[0-9.]+s" 121 }, 122 wantError: "(?s).+1 package had failing tests:.+", 123 }, 124 { 125 name: "fails if there are no packages to test (no buildable Go files)", 126 wantMatch: func(currCaseTmpDir string) string { 127 return "^no packages to test\n$" 128 }, 129 wantError: "^no packages to test\n$", 130 }, 131 { 132 name: "test that does not compile fails", 133 filesToCreate: []gofiles.GoFileSpec{ 134 { 135 RelPath: "foo.go", 136 Src: `package foo 137 import "fmt" 138 func Foo() { 139 fmt.Println("Foo") 140 }`, 141 }, 142 { 143 RelPath: "foo_test.go", 144 Src: `package foo 145 import "testing" 146 import "github.com/palantir/godel/apps/gunit/blah/foo" 147 func TestFoo(t *testing.T) { 148 foo.Foo() 149 t.Errorf("myFail") 150 }`, 151 }, 152 }, 153 wantMatch: func(currCaseTmpDir string) string { 154 return `(?s)foo_test.go:[0-9]+:[0-9]+: cannot find package.+\nFAIL\t` + pkgName(t, currCaseTmpDir) + `\t\[setup failed\]` 155 }, 156 wantError: "(?s).+1 package had failing tests:.+", 157 }, 158 { 159 name: "running with a tag runs only tagged tests", 160 filesToCreate: []gofiles.GoFileSpec{ 161 { 162 RelPath: "foo_test.go", 163 Src: `package foo 164 import "testing" 165 func TestFoo(t *testing.T) { 166 t.Errorf("fooFail") 167 }`, 168 }, 169 { 170 RelPath: "integration/bar_test.go", 171 Src: `package bar 172 import "testing" 173 func TestBar(t *testing.T) { 174 t.Errorf("barFail") 175 }`, 176 }, 177 }, 178 config: unindent(`tags: 179 integration: 180 names: 181 - "integration" 182 exclude: 183 paths: 184 - "vendor" 185 `), 186 args: []string{ 187 "--tags", "integration", 188 }, 189 wantMatch: func(currCaseTmpDir string) string { 190 return `(?s)--- FAIL: TestBar (.+)\n.+bar_test.go:[0-9]+: barFail.+FAIL\t` + pkgName(t, currCaseTmpDir) + "/integration\t[0-9.]+s" 191 }, 192 wantError: "(?s).+1 package had failing tests:.+", 193 }, 194 { 195 name: "fails if tags do not match any packages", 196 filesToCreate: []gofiles.GoFileSpec{ 197 { 198 RelPath: "foo_test.go", 199 Src: `package foo 200 import "testing" 201 func TestFoo(t *testing.T) { 202 t.Errorf("fooFail") 203 }`, 204 }, 205 }, 206 config: unindent(`tags: 207 integration: 208 names: 209 - "integration" 210 `), 211 args: []string{ 212 "--tags", "integration", 213 }, 214 wantMatch: func(currCaseTmpDir string) string { 215 return "^no packages to test\n$" 216 }, 217 wantError: "^no packages to test\n$", 218 }, 219 { 220 name: "union of tags is run when multiple tags are specified", 221 filesToCreate: []gofiles.GoFileSpec{ 222 { 223 RelPath: "foo_test.go", 224 Src: `package foo 225 import "testing" 226 func TestFoo(t *testing.T) { 227 t.Errorf("fooFail") 228 }`, 229 }, 230 { 231 RelPath: "bar/bar_test.go", 232 Src: `package bar 233 import "testing" 234 func TestBar(t *testing.T) { 235 t.Errorf("barFail") 236 }`, 237 }, 238 { 239 RelPath: "baz/baz_test.go", 240 Src: `package baz 241 import "testing" 242 func TestBaz(t *testing.T) { 243 t.Errorf("bazFail") 244 }`, 245 }, 246 }, 247 config: unindent(`tags: 248 bar: 249 paths: 250 - "bar" 251 baz: 252 paths: 253 - "baz" 254 exclude: 255 paths: 256 - "vendor" 257 `), 258 args: []string{ 259 "--tags", "bar,baz", 260 }, 261 wantMatch: func(currCaseTmpDir string) string { 262 return `(?s)--- FAIL: TestBar (.+)\n.+bar_test.go:[0-9]+: barFail.+FAIL\t` + pkgName(t, currCaseTmpDir) + `/bar\t[0-9.]+s.+` + 263 `--- FAIL: TestBaz (.+)\n.+baz_test.go:[0-9]+: bazFail.+FAIL\t` + pkgName(t, currCaseTmpDir) + `/baz\t[0-9.]+s.+` 264 }, 265 wantError: "(?s).+2 packages had failing tests:.+", 266 }, 267 { 268 name: "only non-tagged tests are run if multiple tags are specified and tests are run without arguments", 269 filesToCreate: []gofiles.GoFileSpec{ 270 { 271 RelPath: "foo_test.go", 272 Src: `package foo 273 import "testing" 274 func TestFoo(t *testing.T) { 275 t.Errorf("fooFail") 276 }`, 277 }, 278 { 279 RelPath: "bar/bar_test.go", 280 Src: `package bar 281 import "testing" 282 func TestBar(t *testing.T) { 283 t.Errorf("barFail") 284 }`, 285 }, 286 { 287 RelPath: "baz/baz_test.go", 288 Src: `package baz 289 import "testing" 290 func TestBaz(t *testing.T) { 291 t.Errorf("bazFail") 292 }`, 293 }, 294 }, 295 config: unindent(`tags: 296 bar: 297 paths: 298 - "bar" 299 baz: 300 paths: 301 - "baz" 302 exclude: 303 paths: 304 - "vendor" 305 `), 306 wantMatch: func(currCaseTmpDir string) string { 307 return `(?s)--- FAIL: TestFoo (.+)\n.+foo_test.go:[0-9]+: fooFail.+FAIL\t` + pkgName(t, currCaseTmpDir) + `\t[0-9.]+s.+` 308 }, 309 wantError: "(?s).+1 package had failing tests:.+", 310 }, 311 { 312 name: "fails if invalid tag is supplied", 313 filesToCreate: []gofiles.GoFileSpec{ 314 { 315 RelPath: "foo_test.go", 316 Src: `package foo 317 import "testing" 318 func TestFoo(t *testing.T) { 319 t.Errorf("fooFail") 320 }`, 321 }, 322 }, 323 config: unindent(`exclude: 324 paths: 325 - "vendor" 326 `), 327 args: []string{ 328 "--tags", "invalid,n!otvalid", 329 }, 330 wantMatch: func(currCaseTmpDir string) string { 331 return `invalid tags: "invalid", "n!otvalid"` 332 }, 333 wantError: `invalid tags: "invalid", "n!otvalid"`, 334 }, 335 } { 336 currCaseTmpDir, err := ioutil.TempDir(tmpDir, "") 337 require.NoError(t, err, "Case %d: %s", i, currCase.name) 338 339 _, err = gofiles.Write(currCaseTmpDir, currCase.filesToCreate) 340 require.NoError(t, err, "Case %d: %s", i, currCase.name) 341 342 configFile := path.Join(currCaseTmpDir, "config.yml") 343 err = ioutil.WriteFile(configFile, []byte(currCase.config), 0644) 344 require.NoError(t, err, "Case %d: %s", i, currCase.name) 345 346 err = os.Chdir(currCaseTmpDir) 347 require.NoError(t, err) 348 349 args := []string{"--config", configFile} 350 args = append(args, currCase.args...) 351 args = append(args, "test") 352 353 cmd := exec.Command(cli, args...) 354 outputBytes, err := cmd.CombinedOutput() 355 output := string(outputBytes) 356 357 if err != nil { 358 if currCase.wantError == "" { 359 t.Fatalf("Case %d: %s\nunexpected error:\n%v\nOutput: %v", i, currCase.name, err, output) 360 } else if !regexp.MustCompile(currCase.wantError).MatchString(output) { 361 t.Fatalf("Case %d: %s\nexpected error output to contain %v, but was %v", i, currCase.name, currCase.wantError, output) 362 } 363 } else if currCase.wantError != "" { 364 t.Fatalf("Case %d: %s\nexpected error %v, but was none.\nOutput: %v", i, currCase.name, currCase.wantError, output) 365 } 366 367 expectedExpr := currCase.wantMatch(currCaseTmpDir) 368 if !regexp.MustCompile(expectedExpr).MatchString(output) { 369 t.Errorf("Case %d: %s\nOutput did not match expected expression.\nExpected:\n%v\nActual:\n%v", i, currCase.name, expectedExpr, output) 370 } 371 } 372 } 373 374 func TestClean(t *testing.T) { 375 cli, err := products.Bin("gunit") 376 require.NoError(t, err) 377 378 wd, err := os.Getwd() 379 require.NoError(t, err) 380 381 tmpDir, cleanup, err := dirs.TempDir(wd, "") 382 defer cleanup() 383 require.NoError(t, err) 384 385 files, err := gofiles.Write(tmpDir, []gofiles.GoFileSpec{ 386 { 387 RelPath: "tmp_placeholder_test.go", 388 Src: "package main", 389 }, 390 }) 391 require.NoError(t, err) 392 393 originalWd, err := os.Getwd() 394 require.NoError(t, err) 395 defer func() { 396 if err := os.Chdir(originalWd); err != nil { 397 require.NoError(t, err) 398 } 399 }() 400 401 err = os.Chdir(tmpDir) 402 require.NoError(t, err) 403 404 cmd := exec.Command(cli, "clean") 405 output, err := cmd.CombinedOutput() 406 require.NoError(t, err, "Command %v failed with output:\n%s", cmd.Args, string(output)) 407 408 _, err = os.Stat(files["tmp_placeholder_test.go"].Path) 409 assert.True(t, os.IsNotExist(err)) 410 } 411 412 func unindent(input string) string { 413 return strings.Replace(input, "\n\t\t\t\t\t", "\n", -1) 414 } 415 416 func pkgName(t *testing.T, path string) string { 417 pkgPath, err := pkgpath.NewAbsPkgPath(path).GoPathSrcRel() 418 require.NoError(t, err) 419 return pkgPath 420 }