github.com/postmates/migrate@v3.0.2-0.20200730201548-1a6ead3e680d+incompatible/testing/testing.go (about) 1 package testing 2 3 import ( 4 "io/ioutil" 5 "os" 6 "strconv" 7 "testing" 8 "time" 9 10 dockertypes "github.com/docker/docker/api/types" 11 ) 12 13 type IsReadyFunc func(Instance) bool 14 15 type TestFunc func(*testing.T, Instance) 16 17 type Version struct { 18 Image string 19 ENV []string 20 } 21 22 func ParallelTest(t *testing.T, versions []Version, readyFn IsReadyFunc, testFn TestFunc) { 23 delay, err := strconv.Atoi(os.Getenv("MIGRATE_TEST_CONTAINER_BOOT_DELAY")) 24 if err != nil { 25 delay = 0 26 } 27 28 for i, version := range versions { 29 version := version // capture range variable, see https://goo.gl/60w3p2 30 31 // Only test against one version in short mode 32 // TODO: order is random, maybe always pick first version instead? 33 if i > 0 && testing.Short() { 34 t.Logf("Skipping %v in short mode", version) 35 36 } else { 37 t.Run(version.Image, func(t *testing.T) { 38 t.Parallel() 39 40 // create new container 41 container, err := NewDockerContainer(t, version.Image, version.ENV) 42 if err != nil { 43 t.Fatalf("%v\n%s", err, containerLogs(t, container)) 44 } 45 46 // make sure to remove container once done 47 defer container.Remove() 48 49 // wait until database is ready 50 tick := time.Tick(1000 * time.Millisecond) 51 timeout := time.After(time.Duration(delay + 60) * time.Second) 52 outer: 53 for { 54 select { 55 case <-tick: 56 if readyFn(container) { 57 break outer 58 } 59 60 case <-timeout: 61 t.Fatalf("Docker: Container not ready, timeout for %v.\n%s", version, containerLogs(t, container)) 62 } 63 } 64 65 time.Sleep(time.Duration(int64(delay)) * time.Second) 66 67 // we can now run the tests 68 testFn(t, container) 69 }) 70 } 71 } 72 } 73 74 func containerLogs(t *testing.T, c *DockerContainer) []byte { 75 r, err := c.Logs() 76 if err != nil { 77 t.Error("%v", err) 78 return nil 79 } 80 defer r.Close() 81 b, err := ioutil.ReadAll(r) 82 if err != nil { 83 t.Error("%v", err) 84 return nil 85 } 86 return b 87 } 88 89 type Instance interface { 90 Host() string 91 Port() uint 92 NetworkSettings() dockertypes.NetworkSettings 93 KeepForDebugging() 94 }