Skip to content

Commit 3c80053

Browse files
Prometheus2677FPiety0521
authored andcommitted
added tests for clickhouse database (#532)
* added tests for clickhouse * added atomic lock flag to clickhouse & remove extra test * added clickhouse test package
1 parent d2b1700 commit 3c80053

File tree

2 files changed

+196
-5
lines changed

2 files changed

+196
-5
lines changed

database/clickhouse/clickhouse.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package clickhouse
33
import (
44
"database/sql"
55
"fmt"
6+
"go.uber.org/atomic"
67
"io"
78
"io/ioutil"
89
"net/url"
@@ -58,8 +59,9 @@ func WithInstance(conn *sql.DB, config *Config) (database.Driver, error) {
5859
}
5960

6061
type ClickHouse struct {
61-
conn *sql.DB
62-
config *Config
62+
conn *sql.DB
63+
config *Config
64+
isLocked atomic.Bool
6365
}
6466

6567
func (ch *ClickHouse) Open(dsn string) (database.Driver, error) {
@@ -260,6 +262,18 @@ func (ch *ClickHouse) Drop() (err error) {
260262
return nil
261263
}
262264

263-
func (ch *ClickHouse) Lock() error { return nil }
264-
func (ch *ClickHouse) Unlock() error { return nil }
265-
func (ch *ClickHouse) Close() error { return ch.conn.Close() }
265+
func (ch *ClickHouse) Lock() error {
266+
if !ch.isLocked.CAS(false, true) {
267+
return database.ErrLocked
268+
}
269+
270+
return nil
271+
}
272+
func (ch *ClickHouse) Unlock() error {
273+
if !ch.isLocked.CAS(true, false) {
274+
return database.ErrLocked
275+
}
276+
277+
return nil
278+
}
279+
func (ch *ClickHouse) Close() error { return ch.conn.Close() }
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package clickhouse_test
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
sqldriver "database/sql/driver"
7+
"fmt"
8+
_ "github.com/ClickHouse/clickhouse-go"
9+
"github.com/dhui/dktest"
10+
"github.com/golang-migrate/migrate/v4"
11+
"github.com/golang-migrate/migrate/v4/database/clickhouse"
12+
dt "github.com/golang-migrate/migrate/v4/database/testing"
13+
"github.com/golang-migrate/migrate/v4/dktesting"
14+
_ "github.com/golang-migrate/migrate/v4/source/file"
15+
"log"
16+
"testing"
17+
)
18+
19+
const defaultPort = 9000
20+
21+
var (
22+
opts = dktest.Options{
23+
Env: map[string]string{"CLICKHOUSE_USER": "user", "CLICKHOUSE_PASSWORD": "password", "CLICKHOUSE_DB": "db"},
24+
PortRequired: true, ReadyFunc: isReady,
25+
}
26+
specs = []dktesting.ContainerSpec{
27+
{ImageName: "yandex/clickhouse-server:21.3", Options: opts},
28+
}
29+
)
30+
31+
func clickhouseConnectionString(host, port string) string {
32+
return fmt.Sprintf("clickhouse://%v:%v?username=user&password=password&database=db&x-multi-statement=true&debug=false", host, port)
33+
}
34+
35+
func isReady(ctx context.Context, c dktest.ContainerInfo) bool {
36+
ip, port, err := c.Port(defaultPort)
37+
if err != nil {
38+
return false
39+
}
40+
41+
db, err := sql.Open("clickhouse", clickhouseConnectionString(ip, port))
42+
43+
if err != nil {
44+
log.Println("open error", err)
45+
return false
46+
}
47+
defer func() {
48+
if err := db.Close(); err != nil {
49+
log.Println("close error:", err)
50+
}
51+
}()
52+
53+
if err = db.PingContext(ctx); err != nil {
54+
switch err {
55+
case sqldriver.ErrBadConn:
56+
return false
57+
default:
58+
fmt.Println(err)
59+
}
60+
return false
61+
}
62+
63+
return true
64+
}
65+
66+
func Test(t *testing.T) {
67+
dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) {
68+
ip, port, err := c.Port(defaultPort)
69+
if err != nil {
70+
t.Fatal(err)
71+
}
72+
73+
addr := clickhouseConnectionString(ip, port)
74+
p := &clickhouse.ClickHouse{}
75+
d, err := p.Open(addr)
76+
if err != nil {
77+
t.Fatal(err)
78+
}
79+
defer func() {
80+
if err := d.Close(); err != nil {
81+
t.Error(err)
82+
}
83+
}()
84+
85+
dt.Test(t, d, []byte("SELECT 1"))
86+
})
87+
}
88+
89+
func TestMigrate(t *testing.T) {
90+
dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) {
91+
ip, port, err := c.Port(defaultPort)
92+
if err != nil {
93+
t.Fatal(err)
94+
}
95+
96+
addr := clickhouseConnectionString(ip, port)
97+
p := &clickhouse.ClickHouse{}
98+
d, err := p.Open(addr)
99+
if err != nil {
100+
t.Fatal(err)
101+
}
102+
defer func() {
103+
if err := d.Close(); err != nil {
104+
t.Error(err)
105+
}
106+
}()
107+
m, err := migrate.NewWithDatabaseInstance("file://./examples/migrations", "db", d)
108+
109+
if err != nil {
110+
t.Fatal(err)
111+
}
112+
dt.TestMigrate(t, m)
113+
})
114+
}
115+
116+
func TestVersion(t *testing.T) {
117+
dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) {
118+
expectedVersion := 1
119+
120+
ip, port, err := c.Port(defaultPort)
121+
if err != nil {
122+
t.Fatal(err)
123+
}
124+
125+
addr := clickhouseConnectionString(ip, port)
126+
p := &clickhouse.ClickHouse{}
127+
d, err := p.Open(addr)
128+
if err != nil {
129+
t.Fatal(err)
130+
}
131+
defer func() {
132+
if err := d.Close(); err != nil {
133+
t.Error(err)
134+
}
135+
}()
136+
137+
err = d.SetVersion(expectedVersion, false)
138+
if err != nil {
139+
t.Fatal(err)
140+
}
141+
142+
version, _, err := d.Version()
143+
if err != nil {
144+
t.Fatal(err)
145+
}
146+
147+
if version != expectedVersion {
148+
t.Fatal("Version mismatch")
149+
}
150+
})
151+
}
152+
153+
func TestDrop(t *testing.T) {
154+
dktesting.ParallelTest(t, specs, func(t *testing.T, c dktest.ContainerInfo) {
155+
ip, port, err := c.Port(defaultPort)
156+
if err != nil {
157+
t.Fatal(err)
158+
}
159+
160+
addr := clickhouseConnectionString(ip, port)
161+
p := &clickhouse.ClickHouse{}
162+
d, err := p.Open(addr)
163+
if err != nil {
164+
t.Fatal(err)
165+
}
166+
defer func() {
167+
if err := d.Close(); err != nil {
168+
t.Error(err)
169+
}
170+
}()
171+
172+
err = d.Drop()
173+
if err != nil {
174+
t.Fatal(err)
175+
}
176+
})
177+
}

0 commit comments

Comments
 (0)