github.com/kruftik/go-migrate@v3.5.4+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.Tick(1000 * time.Millisecond) 52 timeout := time.After(time.Duration(timeout) * time.Second) 53 outer: 54 for { 55 select { 56 case <-tick: 57 if readyFn(container) { 58 break outer 59 } 60 61 case <-timeout: 62 t.Fatalf("Docker: Container not ready, timeout for %v.\n%s", version, containerLogs(t, container)) 63 } 64 } 65 66 // we can now run the tests 67 testFn(t, container) 68 }) 69 } 70 } 71 } 72 73 func containerLogs(t *testing.T, c *DockerContainer) []byte { 74 r, err := c.Logs() 75 if err != nil { 76 t.Error(err) 77 return nil 78 } 79 defer r.Close() 80 b, err := ioutil.ReadAll(r) 81 if err != nil { 82 t.Error(err) 83 return nil 84 } 85 return b 86 } 87 88 type Instance interface { 89 Host() string 90 Port() uint 91 PortFor(int) uint 92 NetworkSettings() dockertypes.NetworkSettings 93 KeepForDebugging() 94 }