github.com/wmetaw/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  }