github.com/newrelic-forks/migrate@v3.0.0+incompatible/testing/testing.go (about)

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