Skip to content

Commit e28917c

Browse files
Updated tests
1 parent 35147cd commit e28917c

File tree

5 files changed

+1003
-68
lines changed

5 files changed

+1003
-68
lines changed

cmd/main_test.go

+19-50
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,19 @@ package main
22

33
import (
44
"fmt"
5-
"os"
65
"reflect"
7-
"strings"
86
"testing"
97

10-
"github.com/Percona-Lab/random_data_load/internal/testutils"
8+
tu "github.com/Percona-Lab/random_data_load/internal/testutils"
119
"github.com/Percona-Lab/random_data_load/tableparser"
12-
"github.com/kr/pretty"
1310
)
1411

1512
func TestParse(t *testing.T) {
16-
os.Setenv("TEST_DSN", "root:root@tcp(127.1:3306)/")
17-
18-
db := testutils.GetMySQLConnection()
13+
db := tu.GetMySQLConnection(t)
1914

2015
table, err := tableparser.NewTable(db, "sakila", "rental")
21-
if err != nil {
22-
t.Error(err)
23-
}
16+
tu.Ok(t, err)
2417
values := makeValueFuncs(db, table.Fields)
25-
pretty.Println(table)
2618

2719
wantRows := 1
2820
rowsChan := makeRowsChan(wantRows, values)
@@ -33,45 +25,29 @@ func TestParse(t *testing.T) {
3325
for _, v := range c {
3426
f = append(f, fmt.Sprintf("%v %T", v, v))
3527
}
36-
fmt.Println(strings.Join(f, ", "))
37-
}
38-
if count != wantRows {
39-
t.Errorf("count is not correct: want: %d, have %d", wantRows, count)
4028
}
29+
tu.Assert(t, count == wantRows, "count is not correct: want: %d, have %d", wantRows, count)
4130
}
4231

4332
func TestGetSamples(t *testing.T) {
44-
os.Setenv("TEST_DSN", "root:root@tcp(127.1:3306)/")
45-
46-
conn := testutils.GetMySQLConnection()
33+
conn := tu.GetMySQLConnection(t)
4734
var wantRows int64 = 100
4835
samples, err := getSamples(conn, "sakila", "inventory", "inventory_id", wantRows, "int")
49-
if err != nil {
50-
t.Errorf("error getting samples: %s", err)
51-
}
36+
tu.Ok(t, err, "error getting samples")
5237
_, ok := samples[0].(int64)
53-
if !ok {
54-
t.Errorf("Wrong data type.")
55-
}
56-
if int64(len(samples)) > wantRows {
57-
t.Errorf("Wrong number of samples. Have %d, want 100.", len(samples))
58-
}
38+
tu.Assert(t, ok, "Wrong data type.")
39+
tu.Assert(t, int64(len(samples)) == wantRows,
40+
"Wrong number of samples. Have %d, want 100.", len(samples))
5941
}
6042

6143
func TestValueFuncs(t *testing.T) {
62-
os.Setenv("TEST_DSN", "root:root@tcp(127.1:3306)/")
63-
64-
conn := testutils.GetMySQLConnection()
44+
conn := tu.GetMySQLConnection(t)
6545

6646
table, err := tableparser.NewTable(conn, "sakila", "rental")
67-
if err != nil {
68-
t.Error(err)
69-
}
47+
tu.Ok(t, err)
7048

7149
values := makeValueFuncs(conn, table.Fields)
72-
if len(values) != 6 {
73-
t.Errorf("Wrong number of value functions. Have %d, want 6", len(values))
74-
}
50+
tu.Assert(t, len(values) == 6, "Wrong number of value functions. Have %d, want 6", len(values))
7551

7652
wantTypes := []string{
7753
"*getters.RandomDateInRange",
@@ -84,21 +60,17 @@ func TestValueFuncs(t *testing.T) {
8460

8561
for i, vf := range values {
8662
gotType := reflect.ValueOf(vf).Type().String()
87-
if gotType != wantTypes[i] {
88-
fmt.Printf("Wrong value function type for field %d, %s. Have %s, want %s\n", i,
89-
table.Fields[i].ColumnName, gotType, wantTypes[i])
90-
}
63+
tu.Assert(t, gotType == wantTypes[i],
64+
"Wrong value function type for field %d, %s. Have %s, want %s\n", i,
65+
table.Fields[i].ColumnName, gotType, wantTypes[i])
9166
}
9267
}
93-
func TestMakeRowsChan(t *testing.T) {
94-
os.Setenv("TEST_DSN", "root:root@tcp(127.1:3306)/")
9568

96-
conn := testutils.GetMySQLConnection()
69+
func TestMakeRowsChan(t *testing.T) {
70+
conn := tu.GetMySQLConnection(t)
9771

9872
table, err := tableparser.NewTable(conn, "sakila", "rental")
99-
if err != nil {
100-
t.Error(err)
101-
}
73+
tu.Ok(t, err)
10274

10375
wantRows := 10000
10476

@@ -112,9 +84,6 @@ func TestMakeRowsChan(t *testing.T) {
11284
for _, v := range r {
11385
s = append(s, fmt.Sprintf("%v", v))
11486
}
115-
fmt.Println(strings.Join(s, ", "))
116-
}
117-
if count != wantRows {
118-
t.Errorf("Invalid number of generated rows. Have %d, want %d", count, wantRows)
11987
}
88+
tu.Assert(t, count == wantRows, "Invalid number of generated rows. Have %d, want %d", count, wantRows)
12089
}

internal/testutils/testutils.go

+107-10
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,18 @@ import (
88
"os"
99
"os/exec"
1010
"path/filepath"
11+
"reflect"
12+
"runtime"
1113
"strings"
14+
"testing"
15+
16+
"github.com/go-sql-driver/mysql"
1217
)
1318

14-
var basedir string
15-
var db *sql.DB
19+
var (
20+
basedir string
21+
db *sql.DB
22+
)
1623

1724
func BaseDir() string {
1825
if basedir != "" {
@@ -27,29 +34,119 @@ func BaseDir() string {
2734
return basedir
2835
}
2936

30-
func GetMySQLConnection() *sql.DB {
37+
func GetMySQLConnection(tb testing.TB) *sql.DB {
3138
if db != nil {
3239
return db
3340
}
41+
3442
dsn := os.Getenv("TEST_DSN")
35-
db, err := sql.Open("mysql", dsn)
43+
if dsn == "" {
44+
fmt.Printf("%s TEST_DSN environment variable is empty", caller())
45+
tb.FailNow()
46+
}
47+
48+
// Parse the DSN in the env var and ensure it has parseTime & multiStatements enabled
49+
// MultiStatements is required for LoadQueriesFromFile
50+
cfg, err := mysql.ParseDSN(dsn)
51+
if err != nil {
52+
fmt.Printf("%s cannot parse DSN %q: %s", caller(), dsn, err)
53+
tb.FailNow()
54+
}
55+
if cfg.Params == nil {
56+
cfg.Params = make(map[string]string)
57+
}
58+
cfg.ParseTime = true
59+
cfg.MultiStatements = true
60+
61+
db, err := sql.Open("mysql", cfg.FormatDSN())
3662
if err != nil {
37-
panic(fmt.Sprintf("cannot connect to the db: DSN: %s\n%s", dsn, err))
63+
fmt.Printf("%s cannot connect to the db: DSN: %s\n%s", caller(), dsn, err)
64+
tb.FailNow()
3865
}
3966
return db
4067
}
4168

42-
func LoadJson(filename string, dest interface{}) error {
43-
file := filepath.Join(BaseDir(), "/", filename)
69+
func LoadQueriesFromFile(tb testing.TB, filename string) {
70+
conn := GetMySQLConnection(tb)
71+
file := filepath.Join("testdata", filename)
4472
data, err := ioutil.ReadFile(file)
4573
if err != nil {
46-
return err
74+
fmt.Printf("%s cannot load json file %q: %s\n\n", caller(), file, err)
75+
tb.FailNow()
76+
}
77+
_, err = conn.Exec(string(data))
78+
if err != nil {
79+
fmt.Printf("%s cannot load queries from %q: %s\n\n", caller(), file, err)
80+
tb.FailNow()
81+
}
82+
}
83+
84+
func LoadJson(tb testing.TB, filename string, dest interface{}) {
85+
file := filepath.Join("testdata", filename)
86+
data, err := ioutil.ReadFile(file)
87+
if err != nil {
88+
fmt.Printf("%s cannot load json file %q: %s\n\n", caller(), file, err)
89+
tb.FailNow()
4790
}
4891

4992
err = json.Unmarshal(data, dest)
5093
if err != nil {
51-
return err
94+
fmt.Printf("%s cannot unmarshal the contents of %q into %T: %s\n\n", caller(), file, dest, err)
95+
tb.FailNow()
96+
}
97+
}
98+
99+
func WriteJson(tb testing.TB, filename string, data interface{}) {
100+
file := filepath.Join("testdata", filename)
101+
buf, err := json.MarshalIndent(data, "", " ")
102+
if err != nil {
103+
fmt.Printf("%s cannot marshal %T into %q: %s\n\n", caller(), data, file, err)
104+
tb.FailNow()
105+
}
106+
err = ioutil.WriteFile(file, buf, os.ModePerm)
107+
if err != nil {
108+
fmt.Printf("%s cannot write file %q: %s\n\n", caller(), file, err)
109+
tb.FailNow()
110+
}
111+
}
112+
113+
// assert fails the test if the condition is false.
114+
func Assert(tb testing.TB, condition bool, msg string, v ...interface{}) {
115+
if !condition {
116+
fmt.Printf("%s "+msg+"\n\n", append([]interface{}{caller()}, v...)...)
117+
tb.FailNow()
118+
}
119+
}
120+
121+
// ok fails the test if an err is not nil.
122+
func Ok(tb testing.TB, err error, args ...interface{}) {
123+
if err != nil {
124+
msg := fmt.Sprintf("%s: unexpected error: %s\n\n", caller(), err.Error())
125+
if len(args) > 0 {
126+
msg = fmt.Sprintf("%s: %s "+args[0].(string), append([]interface{}{caller(), err}, args[1:]...)) + "\n\n"
127+
}
128+
fmt.Println(msg)
129+
tb.FailNow()
130+
}
131+
}
132+
133+
func NotOk(tb testing.TB, err error) {
134+
if err == nil {
135+
fmt.Printf("%s: expected error is nil\n\n", caller())
136+
tb.FailNow()
52137
}
138+
}
139+
140+
// equals fails the test if exp is not equal to act.
141+
func Equals(tb testing.TB, exp, act interface{}) {
142+
if !reflect.DeepEqual(exp, act) {
143+
fmt.Printf("%s\n\n\texp: %#v\n\n\tgot: %#v\n\n", caller(), exp, act)
144+
tb.FailNow()
145+
}
146+
}
53147

54-
return nil
148+
// Get the caller's function name and line to show a better error message
149+
func caller() string {
150+
_, file, line, _ := runtime.Caller(2)
151+
return fmt.Sprintf("%s:%d", filepath.Base(file), line)
55152
}

tableparser/tableparser_test.go

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,34 @@
11
package tableparser
22

33
import (
4-
"os"
54
"reflect"
65
"testing"
76

8-
"github.com/Percona-Lab/random_data_load/internal/testutils"
7+
tu "github.com/Percona-Lab/random_data_load/internal/testutils"
98
_ "github.com/go-sql-driver/mysql"
109
)
1110

1211
func TestParse(t *testing.T) {
13-
os.Setenv("TEST_DSN", "root:root@tcp(127.1:3306)/")
14-
15-
db := testutils.GetMySQLConnection()
12+
db := tu.GetMySQLConnection(t)
1613

1714
table, err := NewTable(db, "sakila", "film")
1815
if err != nil {
1916
t.Error(err)
2017
}
2118
var want *Table
22-
testutils.LoadJson("/tests/table001.json", &want)
19+
tu.LoadJson(t, "table001.json", &want)
2320

2421
if !reflect.DeepEqual(table, want) {
2522
t.Error("Table film was not correctly parsed")
2623
}
2724
}
2825

29-
func TestGetTriggers(t *testing.T) {
30-
os.Setenv("TEST_DSN", "root:root@tcp(127.1:3306)/")
26+
func TestGetIndexes(t *testing.T) {
27+
db := tu.GetMySQLConnection(t)
28+
want := []Index{}
29+
tu.LoadJson(t, "indexes.json", &want)
3130

31+
idx, err := getIndexes(db, "sakila", "film_actor")
32+
tu.Ok(t, err)
33+
tu.Equals(t, idx, want)
3234
}

tableparser/testdata/indexes.json

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
[
2+
{
3+
"NonUnique": false,
4+
"KeyName": "PRIMARY",
5+
"SeqInIndex": 1,
6+
"ColumnName": "actor_id",
7+
"Collation": "A",
8+
"Cardinality": 200,
9+
"SubPart": {
10+
"Int64": 0,
11+
"Valid": false
12+
},
13+
"Packed": {
14+
"String": "",
15+
"Valid": false
16+
},
17+
"Null": "",
18+
"IndexType": "BTREE",
19+
"Comment": "",
20+
"IndexComment": ""
21+
},
22+
{
23+
"NonUnique": false,
24+
"KeyName": "PRIMARY",
25+
"SeqInIndex": 2,
26+
"ColumnName": "film_id",
27+
"Collation": "A",
28+
"Cardinality": 5462,
29+
"SubPart": {
30+
"Int64": 0,
31+
"Valid": false
32+
},
33+
"Packed": {
34+
"String": "",
35+
"Valid": false
36+
},
37+
"Null": "",
38+
"IndexType": "BTREE",
39+
"Comment": "",
40+
"IndexComment": ""
41+
},
42+
{
43+
"NonUnique": true,
44+
"KeyName": "idx_fk_film_id",
45+
"SeqInIndex": 1,
46+
"ColumnName": "film_id",
47+
"Collation": "A",
48+
"Cardinality": 997,
49+
"SubPart": {
50+
"Int64": 0,
51+
"Valid": false
52+
},
53+
"Packed": {
54+
"String": "",
55+
"Valid": false
56+
},
57+
"Null": "",
58+
"IndexType": "BTREE",
59+
"Comment": "",
60+
"IndexComment": ""
61+
}
62+
]

0 commit comments

Comments
 (0)