github.com/Elate-DevOps/migrate/v4@v4.0.12/database/clickhouse/clickhouse_test.go (about) 1 package clickhouse_test 2 3 import ( 4 "context" 5 "database/sql" 6 sqldriver "database/sql/driver" 7 "fmt" 8 "log" 9 "testing" 10 11 _ "github.com/ClickHouse/clickhouse-go" 12 "github.com/Elate-DevOps/migrate/v4" 13 "github.com/Elate-DevOps/migrate/v4/database/clickhouse" 14 dt "github.com/Elate-DevOps/migrate/v4/database/testing" 15 "github.com/Elate-DevOps/migrate/v4/dktesting" 16 _ "github.com/Elate-DevOps/migrate/v4/source/file" 17 "github.com/dhui/dktest" 18 ) 19 20 const defaultPort = 9000 21 22 var ( 23 tableEngines = []string{"TinyLog", "MergeTree"} 24 opts = dktest.Options{ 25 Env: map[string]string{"CLICKHOUSE_USER": "user", "CLICKHOUSE_PASSWORD": "password", "CLICKHOUSE_DB": "db"}, 26 PortRequired: true, ReadyFunc: isReady, 27 } 28 specs = []dktesting.ContainerSpec{ 29 {ImageName: "yandex/clickhouse-server:21.3", Options: opts}, 30 } 31 ) 32 33 func clickhouseConnectionString(host, port, engine string) string { 34 if engine != "" { 35 return fmt.Sprintf( 36 "clickhouse://%v:%v?username=user&password=password&database=db&x-multi-statement=true&x-migrations-table-engine=%v&debug=false", 37 host, port, engine) 38 } 39 40 return fmt.Sprintf( 41 "clickhouse://%v:%v?username=user&password=password&database=db&x-multi-statement=true&debug=false", 42 host, port) 43 } 44 45 func isReady(ctx context.Context, c dktest.ContainerInfo) bool { 46 ip, port, err := c.Port(defaultPort) 47 if err != nil { 48 return false 49 } 50 51 db, err := sql.Open("clickhouse", clickhouseConnectionString(ip, port, "")) 52 if err != nil { 53 log.Println("open error", err) 54 return false 55 } 56 defer func() { 57 if err := db.Close(); err != nil { 58 log.Println("close error:", err) 59 } 60 }() 61 62 if err = db.PingContext(ctx); err != nil { 63 switch err { 64 case sqldriver.ErrBadConn: 65 return false 66 default: 67 fmt.Println(err) 68 } 69 return false 70 } 71 72 return true 73 } 74 75 func TestCases(t *testing.T) { 76 for _, engine := range tableEngines { 77 t.Run("Test_"+engine, func(t *testing.T) { testSimple(t, engine) }) 78 t.Run("Migrate_"+engine, func(t *testing.T) { testMigrate(t, engine) }) 79 t.Run("Version_"+engine, func(t *testing.T) { testVersion(t, engine) }) 80 t.Run("Drop_"+engine, func(t *testing.T) { testDrop(t, engine) }) 81 } 82 t.Run("WithInstanceDefaultConfigValues", func(t *testing.T) { testSimpleWithInstanceDefaultConfigValues(t) }) 83 } 84 85 func testSimple(t *testing.T, engine string) { 86 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 87 ip, port, err := c.Port(defaultPort) 88 if err != nil { 89 t.Fatal(err) 90 } 91 92 addr := clickhouseConnectionString(ip, port, engine) 93 p := &clickhouse.ClickHouse{} 94 d, err := p.Open(addr) 95 if err != nil { 96 t.Fatal(err) 97 } 98 defer func() { 99 if err := d.Close(); err != nil { 100 t.Error(err) 101 } 102 }() 103 104 dt.Test(t, d, []byte("SELECT 1")) 105 }) 106 } 107 108 func testSimpleWithInstanceDefaultConfigValues(t *testing.T) { 109 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 110 ip, port, err := c.Port(defaultPort) 111 if err != nil { 112 t.Fatal(err) 113 } 114 115 addr := clickhouseConnectionString(ip, port, "") 116 conn, err := sql.Open("clickhouse", addr) 117 if err != nil { 118 t.Fatal(err) 119 } 120 d, err := clickhouse.WithInstance(conn, &clickhouse.Config{}) 121 if err != nil { 122 _ = conn.Close() 123 t.Fatal(err) 124 } 125 defer func() { 126 if err := d.Close(); err != nil { 127 t.Error(err) 128 } 129 }() 130 131 dt.Test(t, d, []byte("SELECT 1")) 132 }) 133 } 134 135 func testMigrate(t *testing.T, engine string) { 136 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 137 ip, port, err := c.Port(defaultPort) 138 if err != nil { 139 t.Fatal(err) 140 } 141 142 addr := clickhouseConnectionString(ip, port, engine) 143 p := &clickhouse.ClickHouse{} 144 d, err := p.Open(addr) 145 if err != nil { 146 t.Fatal(err) 147 } 148 defer func() { 149 if err := d.Close(); err != nil { 150 t.Error(err) 151 } 152 }() 153 m, err := migrate.NewWithDatabaseInstance("file://./examples/migrations", "db", d) 154 if err != nil { 155 t.Fatal(err) 156 } 157 dt.TestMigrate(t, m) 158 }) 159 } 160 161 func testVersion(t *testing.T, engine string) { 162 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 163 expectedVersion := 1 164 165 ip, port, err := c.Port(defaultPort) 166 if err != nil { 167 t.Fatal(err) 168 } 169 170 addr := clickhouseConnectionString(ip, port, engine) 171 p := &clickhouse.ClickHouse{} 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 err = d.SetVersion(expectedVersion, false) 183 if err != nil { 184 t.Fatal(err) 185 } 186 187 version, _, err := d.Version() 188 if err != nil { 189 t.Fatal(err) 190 } 191 192 if version != expectedVersion { 193 t.Fatal("Version mismatch") 194 } 195 }) 196 } 197 198 func testDrop(t *testing.T, engine string) { 199 dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) { 200 ip, port, err := c.Port(defaultPort) 201 if err != nil { 202 t.Fatal(err) 203 } 204 205 addr := clickhouseConnectionString(ip, port, engine) 206 p := &clickhouse.ClickHouse{} 207 d, err := p.Open(addr) 208 if err != nil { 209 t.Fatal(err) 210 } 211 defer func() { 212 if err := d.Close(); err != nil { 213 t.Error(err) 214 } 215 }() 216 217 err = d.Drop() 218 if err != nil { 219 t.Fatal(err) 220 } 221 }) 222 }