github.com/mrqzzz/migrate@v5.1.7+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 Cmd []string 21 } 22 23 func ParallelTest(t *testing.T, versions []Version, readyFn IsReadyFunc, testFn TestFunc) { 24 timeout, err := strconv.Atoi(os.Getenv("MIGRATE_TEST_CONTAINER_BOOT_TIMEOUT")) 25 if err != nil { 26 timeout = 60 // Cassandra docker image can take ~30s to start 27 } 28 29 for i, version := range versions { 30 version := version // capture range variable, see https://goo.gl/60w3p2 31 32 // Only test against one version in short mode 33 // TODO: order is random, maybe always pick first version instead? 34 if i > 0 && testing.Short() { 35 t.Logf("Skipping %v in short mode", version) 36 37 } else { 38 t.Run(version.Image, func(t *testing.T) { 39 t.Parallel() 40 41 // create new container 42 container, err := NewDockerContainer(t, version.Image, version.ENV, version.Cmd) 43 if err != nil { 44 t.Fatalf("%v\n%s", err, containerLogs(t, container)) 45 } 46 47 // make sure to remove container once done 48 defer container.Remove() 49 50 // wait until database is ready 51 tick := time.NewTicker(1000 * time.Millisecond) 52 defer tick.Stop() 53 timeout := time.NewTimer(time.Duration(timeout) * time.Second) 54 defer timeout.Stop() 55 outer: 56 for { 57 select { 58 case <-tick.C: 59 if readyFn(container) { 60 break outer 61 } 62 63 case <-timeout.C: 64 t.Fatalf("Docker: Container not ready, timeout for %v.\n%s", version, containerLogs(t, container)) 65 } 66 } 67 68 // we can now run the tests 69 testFn(t, container) 70 }) 71 } 72 } 73 } 74 75 func containerLogs(t *testing.T, c *DockerContainer) []byte { 76 r, err := c.Logs() 77 if err != nil { 78 t.Error(err) 79 return nil 80 } 81 defer r.Close() 82 b, err := ioutil.ReadAll(r) 83 if err != nil { 84 t.Error(err) 85 return nil 86 } 87 return b 88 } 89 90 type Instance interface { 91 Host() string 92 Port() uint 93 PortFor(int) uint 94 NetworkSettings() dockertypes.NetworkSettings 95 KeepForDebugging() 96 }