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