github.hscsec.cn/amacneil/dbmate@v1.4.1/pkg/dbmate/db_test.go (about)

     1  package dbmate
     2  
     3  import (
     4  	"io/ioutil"
     5  	"net/url"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  var testdataDir string
    15  
    16  func newTestDB(t *testing.T, u *url.URL) *DB {
    17  	var err error
    18  
    19  	// only chdir once, because testdata is relative to current directory
    20  	if testdataDir == "" {
    21  		testdataDir, err = filepath.Abs("../../testdata")
    22  		require.NoError(t, err)
    23  
    24  		err = os.Chdir(testdataDir)
    25  		require.NoError(t, err)
    26  	}
    27  
    28  	db := New(u)
    29  	db.AutoDumpSchema = false
    30  
    31  	return db
    32  }
    33  
    34  func TestNew(t *testing.T) {
    35  	u := postgresTestURL(t)
    36  	db := New(u)
    37  	require.True(t, db.AutoDumpSchema)
    38  	require.Equal(t, u.String(), db.DatabaseURL.String())
    39  	require.Equal(t, "./db/migrations", db.MigrationsDir)
    40  	require.Equal(t, "./db/schema.sql", db.SchemaFile)
    41  	require.Equal(t, time.Second, db.WaitInterval)
    42  	require.Equal(t, 60*time.Second, db.WaitTimeout)
    43  }
    44  
    45  func TestWait(t *testing.T) {
    46  	u := postgresTestURL(t)
    47  	db := newTestDB(t, u)
    48  
    49  	// speed up our retry loop for testing
    50  	db.WaitInterval = time.Millisecond
    51  	db.WaitTimeout = 5 * time.Millisecond
    52  
    53  	// drop database
    54  	err := db.Drop()
    55  	require.NoError(t, err)
    56  
    57  	// test wait
    58  	err = db.Wait()
    59  	require.NoError(t, err)
    60  
    61  	// test invalid connection
    62  	u.Host = "postgres:404"
    63  	err = db.Wait()
    64  	require.Error(t, err)
    65  	require.Contains(t, err.Error(), "unable to connect to database: dial tcp")
    66  	require.Contains(t, err.Error(), "connect: connection refused")
    67  }
    68  
    69  func TestDumpSchema(t *testing.T) {
    70  	u := postgresTestURL(t)
    71  	db := newTestDB(t, u)
    72  
    73  	// create custom schema file directory
    74  	dir, err := ioutil.TempDir("", "dbmate")
    75  	require.NoError(t, err)
    76  	defer func() {
    77  		err := os.RemoveAll(dir)
    78  		require.NoError(t, err)
    79  	}()
    80  
    81  	// create schema.sql in subdirectory to test creating directory
    82  	db.SchemaFile = filepath.Join(dir, "/schema/schema.sql")
    83  
    84  	// drop database
    85  	err = db.Drop()
    86  	require.NoError(t, err)
    87  
    88  	// create and migrate
    89  	err = db.CreateAndMigrate()
    90  	require.NoError(t, err)
    91  
    92  	// schema.sql should not exist
    93  	_, err = os.Stat(db.SchemaFile)
    94  	require.True(t, os.IsNotExist(err))
    95  
    96  	// dump schema
    97  	err = db.DumpSchema()
    98  	require.NoError(t, err)
    99  
   100  	// verify schema
   101  	schema, err := ioutil.ReadFile(db.SchemaFile)
   102  	require.NoError(t, err)
   103  	require.Contains(t, string(schema), "-- PostgreSQL database dump")
   104  }
   105  
   106  func TestAutoDumpSchema(t *testing.T) {
   107  	u := postgresTestURL(t)
   108  	db := newTestDB(t, u)
   109  	db.AutoDumpSchema = true
   110  
   111  	// create custom schema file directory
   112  	dir, err := ioutil.TempDir("", "dbmate")
   113  	require.NoError(t, err)
   114  	defer func() {
   115  		err := os.RemoveAll(dir)
   116  		require.NoError(t, err)
   117  	}()
   118  
   119  	// create schema.sql in subdirectory to test creating directory
   120  	db.SchemaFile = filepath.Join(dir, "/schema/schema.sql")
   121  
   122  	// drop database
   123  	err = db.Drop()
   124  	require.NoError(t, err)
   125  
   126  	// schema.sql should not exist
   127  	_, err = os.Stat(db.SchemaFile)
   128  	require.True(t, os.IsNotExist(err))
   129  
   130  	// create and migrate
   131  	err = db.CreateAndMigrate()
   132  	require.NoError(t, err)
   133  
   134  	// verify schema
   135  	schema, err := ioutil.ReadFile(db.SchemaFile)
   136  	require.NoError(t, err)
   137  	require.Contains(t, string(schema), "-- PostgreSQL database dump")
   138  
   139  	// remove schema
   140  	err = os.Remove(db.SchemaFile)
   141  	require.NoError(t, err)
   142  
   143  	// rollback
   144  	err = db.Rollback()
   145  	require.NoError(t, err)
   146  
   147  	// schema should be recreated
   148  	schema, err = ioutil.ReadFile(db.SchemaFile)
   149  	require.NoError(t, err)
   150  	require.Contains(t, string(schema), "-- PostgreSQL database dump")
   151  }
   152  
   153  func testURLs(t *testing.T) []*url.URL {
   154  	return []*url.URL{
   155  		postgresTestURL(t),
   156  		mySQLTestURL(t),
   157  		sqliteTestURL(t),
   158  	}
   159  }
   160  
   161  func testMigrateURL(t *testing.T, u *url.URL) {
   162  	db := newTestDB(t, u)
   163  
   164  	// drop and recreate database
   165  	err := db.Drop()
   166  	require.NoError(t, err)
   167  	err = db.Create()
   168  	require.NoError(t, err)
   169  
   170  	// migrate
   171  	err = db.Migrate()
   172  	require.NoError(t, err)
   173  
   174  	// verify results
   175  	sqlDB, err := GetDriverOpen(u)
   176  	require.NoError(t, err)
   177  	defer mustClose(sqlDB)
   178  
   179  	count := 0
   180  	err = sqlDB.QueryRow(`select count(*) from schema_migrations
   181  		where version = '20151129054053'`).Scan(&count)
   182  	require.NoError(t, err)
   183  	require.Equal(t, 1, count)
   184  
   185  	err = sqlDB.QueryRow("select count(*) from users").Scan(&count)
   186  	require.NoError(t, err)
   187  	require.Equal(t, 1, count)
   188  }
   189  
   190  func TestMigrate(t *testing.T) {
   191  	for _, u := range testURLs(t) {
   192  		testMigrateURL(t, u)
   193  	}
   194  }
   195  
   196  func testUpURL(t *testing.T, u *url.URL) {
   197  	db := newTestDB(t, u)
   198  
   199  	// drop database
   200  	err := db.Drop()
   201  	require.NoError(t, err)
   202  
   203  	// create and migrate
   204  	err = db.CreateAndMigrate()
   205  	require.NoError(t, err)
   206  
   207  	// verify results
   208  	sqlDB, err := GetDriverOpen(u)
   209  	require.NoError(t, err)
   210  	defer mustClose(sqlDB)
   211  
   212  	count := 0
   213  	err = sqlDB.QueryRow(`select count(*) from schema_migrations
   214  		where version = '20151129054053'`).Scan(&count)
   215  	require.NoError(t, err)
   216  	require.Equal(t, 1, count)
   217  
   218  	err = sqlDB.QueryRow("select count(*) from users").Scan(&count)
   219  	require.NoError(t, err)
   220  	require.Equal(t, 1, count)
   221  }
   222  
   223  func TestUp(t *testing.T) {
   224  	for _, u := range testURLs(t) {
   225  		testUpURL(t, u)
   226  	}
   227  }
   228  
   229  func testRollbackURL(t *testing.T, u *url.URL) {
   230  	db := newTestDB(t, u)
   231  
   232  	// drop, recreate, and migrate database
   233  	err := db.Drop()
   234  	require.NoError(t, err)
   235  	err = db.Create()
   236  	require.NoError(t, err)
   237  	err = db.Migrate()
   238  	require.NoError(t, err)
   239  
   240  	// verify migration
   241  	sqlDB, err := GetDriverOpen(u)
   242  	require.NoError(t, err)
   243  	defer mustClose(sqlDB)
   244  
   245  	count := 0
   246  	err = sqlDB.QueryRow(`select count(*) from schema_migrations
   247  		where version = '20151129054053'`).Scan(&count)
   248  	require.NoError(t, err)
   249  	require.Equal(t, 1, count)
   250  
   251  	// rollback
   252  	err = db.Rollback()
   253  	require.NoError(t, err)
   254  
   255  	// verify rollback
   256  	err = sqlDB.QueryRow("select count(*) from schema_migrations").Scan(&count)
   257  	require.NoError(t, err)
   258  	require.Equal(t, 0, count)
   259  
   260  	err = sqlDB.QueryRow("select count(*) from users").Scan(&count)
   261  	require.NotNil(t, err)
   262  	require.Regexp(t, "(does not exist|doesn't exist|no such table)", err.Error())
   263  }
   264  
   265  func TestRollback(t *testing.T) {
   266  	for _, u := range testURLs(t) {
   267  		testRollbackURL(t, u)
   268  	}
   269  }