github.com/fr-nvriep/migrate/v4@v4.3.2/database/testing/testing.go (about)

     1  // Package testing has the database tests.
     2  // All database drivers must pass the Test function.
     3  // This lives in it's own package so it stays a test dependency.
     4  package testing
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/fr-nvriep/migrate/v4/database"
    15  )
    16  
    17  // Test runs tests against database implementations.
    18  func Test(t *testing.T, d database.Driver, migration []byte) {
    19  	if migration == nil {
    20  		t.Fatal("test must provide migration reader")
    21  	}
    22  
    23  	TestNilVersion(t, d) // test first
    24  	TestLockAndUnlock(t, d)
    25  	TestRun(t, d, bytes.NewReader(migration))
    26  	TestSetVersion(t, d) // also tests Version()
    27  	// Drop breaks the driver, so test it last.
    28  	TestDrop(t, d)
    29  }
    30  
    31  func TestNilVersion(t *testing.T, d database.Driver) {
    32  	v, _, err := d.Version()
    33  	if err != nil {
    34  		t.Fatal(err)
    35  	}
    36  	if v != database.NilVersion {
    37  		t.Fatalf("Version: expected version to be NilVersion (-1), got %v", v)
    38  	}
    39  }
    40  
    41  func TestLockAndUnlock(t *testing.T, d database.Driver) {
    42  	// add a timeout, in case there is a deadlock
    43  	done := make(chan struct{})
    44  	errs := make(chan error)
    45  
    46  	go func() {
    47  		timeout := time.After(15 * time.Second)
    48  		for {
    49  			select {
    50  			case <-done:
    51  				return
    52  			case <-timeout:
    53  				errs <- fmt.Errorf("Timeout after 15 seconds. Looks like a deadlock in Lock/UnLock.\n%#v", d)
    54  				return
    55  			}
    56  		}
    57  	}()
    58  
    59  	// run the locking test ...
    60  	go func() {
    61  		if err := d.Lock(); err != nil {
    62  			errs <- err
    63  			return
    64  		}
    65  
    66  		// try to acquire lock again
    67  		if err := d.Lock(); err == nil {
    68  			errs <- errors.New("lock: expected err not to be nil")
    69  			return
    70  		}
    71  
    72  		// unlock
    73  		if err := d.Unlock(); err != nil {
    74  			errs <- err
    75  			return
    76  		}
    77  
    78  		// try to lock
    79  		if err := d.Lock(); err != nil {
    80  			errs <- err
    81  			return
    82  		}
    83  		if err := d.Unlock(); err != nil {
    84  			errs <- err
    85  			return
    86  		}
    87  		// notify everyone
    88  		close(done)
    89  	}()
    90  
    91  	// wait for done or any error
    92  	for {
    93  		select {
    94  		case <-done:
    95  			return
    96  		case err := <-errs:
    97  			t.Fatal(err)
    98  		}
    99  	}
   100  }
   101  
   102  func TestRun(t *testing.T, d database.Driver, migration io.Reader) {
   103  	if migration == nil {
   104  		t.Fatal("migration can't be nil")
   105  	}
   106  
   107  	if err := d.Run(migration); err != nil {
   108  		t.Fatal(err)
   109  	}
   110  }
   111  
   112  func TestDrop(t *testing.T, d database.Driver) {
   113  	if err := d.Drop(); err != nil {
   114  		t.Fatal(err)
   115  	}
   116  }
   117  
   118  func TestSetVersion(t *testing.T, d database.Driver) {
   119  	if err := d.SetVersion(1, true); err != nil {
   120  		t.Fatal(err)
   121  	}
   122  
   123  	// call again
   124  	if err := d.SetVersion(1, true); err != nil {
   125  		t.Fatal(err)
   126  	}
   127  
   128  	v, dirty, err := d.Version()
   129  	if err != nil {
   130  		t.Fatal(err)
   131  	}
   132  	if !dirty {
   133  		t.Fatal("expected dirty")
   134  	}
   135  	if v != 1 {
   136  		t.Fatal("expected version to be 1")
   137  	}
   138  
   139  	if err := d.SetVersion(2, false); err != nil {
   140  		t.Fatal(err)
   141  	}
   142  
   143  	// call again
   144  	if err := d.SetVersion(2, false); err != nil {
   145  		t.Fatal(err)
   146  	}
   147  
   148  	v, dirty, err = d.Version()
   149  	if err != nil {
   150  		t.Fatal(err)
   151  	}
   152  	if dirty {
   153  		t.Fatal("expected not dirty")
   154  	}
   155  	if v != 2 {
   156  		t.Fatal("expected version to be 2")
   157  	}
   158  }