github.com/seashell-org/golang-migrate/v4@v4.15.3-0.20220722221203-6ab6c6c062d1/database/firebird/firebird_test.go (about) 1 package firebird 2 3 import ( 4 "context" 5 "database/sql" 6 sqldriver "database/sql/driver" 7 "fmt" 8 "log" 9 10 "io" 11 "strings" 12 "testing" 13 14 migrate "github.com/seashell-org/golang-migrate/v4" 15 16 "github.com/dhui/dktest" 17 18 dt "github.com/seashell-org/golang-migrate/v4/database/testing" 19 "github.com/seashell-org/golang-migrate/v4/dktesting" 20 _ "github.com/seashell-org/golang-migrate/v4/source/file" 21 22 _ "github.com/nakagami/firebirdsql" 23 ) 24 25 const ( 26 user = "test_user" 27 password = "123456" 28 dbName = "test.fdb" 29 ) 30 31 var ( 32 opts = dktest.Options{ 33 PortRequired: true, 34 ReadyFunc: isReady, 35 Env: map[string]string{ 36 "FIREBIRD_DATABASE": dbName, 37 "FIREBIRD_USER": user, 38 "FIREBIRD_PASSWORD": password, 39 }, 40 } 41 specs = []dktesting.ContainerSpec{ 42 {ImageName: "jacobalberty/firebird:2.5-ss", Options: opts}, 43 {ImageName: "jacobalberty/firebird:3.0", Options: opts}, 44 } 45 ) 46 47 func fbConnectionString(host, port string) string { 48 //firebird://user:password@servername[:port_number]/database_name_or_file[?params1=value1[¶m2=value2]...] 49 return fmt.Sprintf("firebird://%s:%s@%s:%s//firebird/data/%s", user, password, host, port, dbName) 50 } 51 52 func isReady(ctx context.Context, c dktest.ContainerInfo) bool { 53 ip, port, err := c.FirstPort() 54 if err != nil { 55 return false 56 } 57 58 db, err := sql.Open("firebirdsql", fbConnectionString(ip, port)) 59 if err != nil { 60 log.Println("open error:", err) 61 return false 62 } 63 defer func() { 64 if err := db.Close(); err != nil { 65 log.Println("close error:", err) 66 } 67 }() 68 if err = db.PingContext(ctx); err != nil { 69 switch err { 70 case sqldriver.ErrBadConn, io.EOF: 71 return false 72 default: 73 log.Println(err) 74 } 75 return false 76 } 77 78 return true 79 } 80 81 func Test(t *testing.T) { 82 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 83 ip, port, err := c.FirstPort() 84 if err != nil { 85 t.Fatal(err) 86 } 87 88 addr := fbConnectionString(ip, port) 89 p := &Firebird{} 90 d, err := p.Open(addr) 91 if err != nil { 92 t.Fatal(err) 93 } 94 defer func() { 95 if err := d.Close(); err != nil { 96 t.Error(err) 97 } 98 }() 99 dt.Test(t, d, []byte("SELECT Count(*) FROM rdb$relations")) 100 }) 101 } 102 103 func TestMigrate(t *testing.T) { 104 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 105 ip, port, err := c.FirstPort() 106 if err != nil { 107 t.Fatal(err) 108 } 109 110 addr := fbConnectionString(ip, port) 111 p := &Firebird{} 112 d, err := p.Open(addr) 113 if err != nil { 114 t.Fatal(err) 115 } 116 defer func() { 117 if err := d.Close(); err != nil { 118 t.Error(err) 119 } 120 }() 121 m, err := migrate.NewWithDatabaseInstance("file://./examples/migrations", "firebirdsql", d) 122 if err != nil { 123 t.Fatal(err) 124 } 125 dt.TestMigrate(t, m) 126 }) 127 } 128 129 func TestErrorParsing(t *testing.T) { 130 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 131 ip, port, err := c.FirstPort() 132 if err != nil { 133 t.Fatal(err) 134 } 135 136 addr := fbConnectionString(ip, port) 137 p := &Firebird{} 138 d, err := p.Open(addr) 139 if err != nil { 140 t.Fatal(err) 141 } 142 defer func() { 143 if err := d.Close(); err != nil { 144 t.Error(err) 145 } 146 }() 147 148 wantErr := `migration failed in line 0: CREATE TABLEE foo (foo varchar(40)); (details: Dynamic SQL Error 149 SQL error code = -104 150 Token unknown - line 1, column 8 151 TABLEE 152 )` 153 154 if err := d.Run(strings.NewReader("CREATE TABLEE foo (foo varchar(40));")); err == nil { 155 t.Fatal("expected err but got nil") 156 } else if err.Error() != wantErr { 157 msg := err.Error() 158 t.Fatalf("expected '%s' but got '%s'", wantErr, msg) 159 } 160 }) 161 } 162 163 func TestFilterCustomQuery(t *testing.T) { 164 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 165 ip, port, err := c.FirstPort() 166 if err != nil { 167 t.Fatal(err) 168 } 169 170 addr := fbConnectionString(ip, port) + "?sslmode=disable&x-custom=foobar" 171 p := &Firebird{} 172 d, err := p.Open(addr) 173 if err != nil { 174 t.Fatal(err) 175 } 176 defer func() { 177 if err := d.Close(); err != nil { 178 t.Error(err) 179 } 180 }() 181 }) 182 } 183 184 func Test_Lock(t *testing.T) { 185 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 186 ip, port, err := c.FirstPort() 187 if err != nil { 188 t.Fatal(err) 189 } 190 191 addr := fbConnectionString(ip, port) 192 p := &Firebird{} 193 d, err := p.Open(addr) 194 if err != nil { 195 t.Fatal(err) 196 } 197 defer func() { 198 if err := d.Close(); err != nil { 199 t.Error(err) 200 } 201 }() 202 203 dt.Test(t, d, []byte("SELECT Count(*) FROM rdb$relations")) 204 205 ps := d.(*Firebird) 206 207 err = ps.Lock() 208 if err != nil { 209 t.Fatal(err) 210 } 211 212 err = ps.Unlock() 213 if err != nil { 214 t.Fatal(err) 215 } 216 217 err = ps.Lock() 218 if err != nil { 219 t.Fatal(err) 220 } 221 222 err = ps.Unlock() 223 if err != nil { 224 t.Fatal(err) 225 } 226 }) 227 }