Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reparo/syncer: add unit test #540

Merged
merged 37 commits into from
Apr 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e91c939
add test for formatvalue
WangXiangUSTC Apr 16, 2019
f2e8739
add test for New syncer
WangXiangUSTC Apr 16, 2019
cd8b5ac
refine some function to let it easy to add unit test
WangXiangUSTC Apr 16, 2019
5231186
add unit test for decode
WangXiangUSTC Apr 16, 2019
cf74baf
refine test
WangXiangUSTC Apr 16, 2019
b262cfc
add test for memory syncer
WangXiangUSTC Apr 16, 2019
7dd35db
minor update
WangXiangUSTC Apr 16, 2019
a54c49a
minor update
WangXiangUSTC Apr 16, 2019
04ab7bc
update reparo integration test
WangXiangUSTC Apr 16, 2019
e78bc8c
add mysql syncer test
WangXiangUSTC Apr 16, 2019
96452eb
minor update
WangXiangUSTC Apr 16, 2019
fb064ad
minor update
WangXiangUSTC Apr 17, 2019
768f8f1
minor fix
WangXiangUSTC Apr 17, 2019
8f875b5
update val name
WangXiangUSTC Apr 18, 2019
31a9ace
address comment
WangXiangUSTC Apr 18, 2019
d2eb5ad
use strings.Builder
WangXiangUSTC Apr 19, 2019
f185d46
add test
WangXiangUSTC Apr 22, 2019
7b1af3f
revert
WangXiangUSTC Apr 22, 2019
4cc5317
add test for callback
WangXiangUSTC Apr 24, 2019
f2d8613
address comment
WangXiangUSTC Apr 24, 2019
b7071ed
revert change in print, and capture stdout for test
WangXiangUSTC Apr 24, 2019
6655dc3
format code
WangXiangUSTC Apr 24, 2019
28eda63
fix test
WangXiangUSTC Apr 24, 2019
dbc2642
add test
WangXiangUSTC Apr 25, 2019
d54b885
minor update
WangXiangUSTC Apr 25, 2019
96f71ab
Merge branch 'master' into xiang/reparo_syncer_test
Apr 25, 2019
7b98a9c
Merge branch 'master' into xiang/reparo_syncer_test
WangXiangUSTC Apr 28, 2019
b4927d2
Merge branch 'master' into xiang/reparo_syncer_test
WangXiangUSTC Apr 28, 2019
8b3bfd2
fix check
WangXiangUSTC Apr 28, 2019
86edf10
Merge branch 'master' into xiang/reparo_syncer_test
WangXiangUSTC Apr 28, 2019
dd02aed
format code
WangXiangUSTC Apr 28, 2019
0bd0c15
address comemnt
WangXiangUSTC Apr 29, 2019
c274caa
address comment
WangXiangUSTC Apr 29, 2019
984c7c0
format code
WangXiangUSTC Apr 29, 2019
201a7cb
add syncTest function
WangXiangUSTC Apr 29, 2019
f60c245
Merge branch 'master' into xiang/reparo_syncer_test
WangXiangUSTC Apr 29, 2019
65bf64a
handle out put of printsyncer for test
WangXiangUSTC Apr 29, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require (
github.com/gorilla/websocket v1.4.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180820150422-93bf4626fba7 // indirect
github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d
github.com/kr/pretty v0.1.0 // indirect
github.com/montanaflynn/stats v0.0.0-20180911141734-db72e6cae808 // indirect
github.com/pierrec/lz4 v2.0.5+incompatible // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d h1:cVtBfNW5XTHiKQe7jDaDBSh/EVM4XLPutLAGboIXuM0=
github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand Down
22 changes: 22 additions & 0 deletions reparo/syncer/memory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package syncer

import (
"github.com/pingcap/check"
)

type testMemorySuite struct{}

var _ = check.Suite(&testMemorySuite{})

func (s *testMemorySuite) TestMemorySyncer(c *check.C) {
syncer, err := newMemSyncer()
c.Assert(err, check.IsNil)

syncTest(c, Syncer(syncer))

binlog := syncer.GetBinlogs()
c.Assert(binlog, check.HasLen, 2)

err = syncer.Close()
c.Assert(err, check.IsNil)
}
12 changes: 10 additions & 2 deletions reparo/syncer/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,23 @@ type mysqlSyncer struct {
loaderErr error
}

var _ Syncer = &mysqlSyncer{}
var (
_ Syncer = &mysqlSyncer{}
defaultWorkerCount = 16
defaultBatchSize = 20
)

func newMysqlSyncer(cfg *DBConfig) (*mysqlSyncer, error) {
db, err := loader.CreateDB(cfg.User, cfg.Password, cfg.Host, cfg.Port)
if err != nil {
return nil, errors.Trace(err)
}

loader, err := loader.NewLoader(db, loader.WorkerCount(16), loader.BatchSize(20))
return newMysqlSyncerFromSQLDB(db)
}

func newMysqlSyncerFromSQLDB(db *sql.DB) (*mysqlSyncer, error) {
loader, err := loader.NewLoader(db, loader.WorkerCount(defaultWorkerCount), loader.BatchSize(defaultBatchSize))
if err != nil {
return nil, errors.Annotate(err, "new loader failed")
}
Expand Down
78 changes: 78 additions & 0 deletions reparo/syncer/mysql_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package syncer
WangXiangUSTC marked this conversation as resolved.
Show resolved Hide resolved

import (
"time"

sqlmock "github.com/DATA-DOG/go-sqlmock"
"github.com/pingcap/check"
pb "github.com/pingcap/tidb-binlog/proto/binlog"
)

type testMysqlSuite struct{}

var _ = check.Suite(&testMysqlSuite{})

func (s *testMysqlSuite) TestMysqlSyncer(c *check.C) {
originWorkerCount := defaultWorkerCount
defaultWorkerCount = 1
defer func() {
defaultWorkerCount = originWorkerCount
}()

db, mock, err := sqlmock.New()
c.Assert(err, check.IsNil)

syncer, err := newMysqlSyncerFromSQLDB(db)
c.Assert(err, check.IsNil)

mock.ExpectBegin()
mock.ExpectExec("create database test").WillReturnResult(sqlmock.NewResult(0, 0))
mock.ExpectCommit()

mock.ExpectQuery("SELECT column_name, extra FROM information_schema.columns").WithArgs("test", "t1").WillReturnRows(sqlmock.NewRows([]string{"column_name", "extra"}).AddRow("a", "").AddRow("b", ""))

rows := sqlmock.NewRows([]string{"non_unique", "index_name", "seq_in_index", "column_name"})
mock.ExpectQuery("SELECT non_unique, index_name, seq_in_index, column_name FROM information_schema.statistics").
WithArgs("test", "t1").
WillReturnRows(rows)

mock.ExpectBegin()
mock.ExpectExec("INSERT INTO").WithArgs(1, "test").WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectExec("DELETE FROM").WithArgs(1, "test").WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectExec("UPDATE").WithArgs("abc").WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectCommit()

syncTest(c, Syncer(syncer))

err = syncer.Close()
c.Assert(err, check.IsNil)
}

func syncTest(c *check.C, syncer Syncer) {
ddlBinlog := &pb.Binlog{
Tp: pb.BinlogType_DDL,
DdlQuery: []byte("create database test;"),
}
dmlBinlog := &pb.Binlog{
Tp: pb.BinlogType_DML,
DmlData: &pb.DMLData{
Events: generateDMLEvents(c),
},
}

binlogs := make([]*pb.Binlog, 0, 2)
err := syncer.Sync(ddlBinlog, func(binlog *pb.Binlog) {
c.Log(binlog)
binlogs = append(binlogs, binlog)
})
c.Assert(err, check.IsNil)

err = syncer.Sync(dmlBinlog, func(binlog *pb.Binlog) {
c.Log(binlog)
binlogs = append(binlogs, binlog)
})
c.Assert(err, check.IsNil)

time.Sleep(100 * time.Millisecond)
c.Assert(binlogs, check.HasLen, 2)
}
2 changes: 1 addition & 1 deletion reparo/syncer/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func printInsertOrDeleteEvent(row [][]byte) error {
}

tp := col.Tp[0]
fmt.Printf("%s(%s): %s \n", col.Name, col.MysqlType, formatValueToString(val, tp))
fmt.Printf("%s(%s): %s\n", col.Name, col.MysqlType, formatValueToString(val, tp))
}
return nil
}
110 changes: 110 additions & 0 deletions reparo/syncer/print_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package syncer

import (
"strings"

capturer "github.com/kami-zh/go-capturer"
"github.com/pingcap/check"
pb "github.com/pingcap/tidb-binlog/proto/binlog"
)

type testPrintSuite struct{}

var _ = check.Suite(&testPrintSuite{})

func (s *testPrintSuite) TestPrintSyncer(c *check.C) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that these test cases are almost identical, can we create a test function that can validate all of these syncers?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only validation functions are different

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this case is lack of output validation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

define a new function to do these things 201a7cb

syncer, err := newPrintSyncer()
c.Assert(err, check.IsNil)

out := capturer.CaptureStdout(func() {
syncTest(c, Syncer(syncer))
})

c.Assert(out, check.Equals,
"DDL query: create database test;\n"+
"schema: test; table: t1; type: Insert\n"+
"a(int): 1\n"+
"b(varchar): test\n"+
"schema: test; table: t1; type: Delete\n"+
"a(int): 1\n"+
"b(varchar): test\n"+
"schema: test; table: t1; type: Update\n"+
"c(varchar): test => abc\n")

err = syncer.Close()
c.Assert(err, check.IsNil)
}

func (s *testPrintSuite) TestPrintEventHeader(c *check.C) {
schema := "test"
table := "t1"
event := &pb.Event{
Tp: pb.EventType_Insert,
SchemaName: &schema,
TableName: &table,
}

out := capturer.CaptureStdout(func() {
printEventHeader(event)
})
lines := strings.Split(strings.TrimSpace(out), "\n")
c.Assert(lines, check.HasLen, 1)
c.Assert(lines[0], check.Matches, ".*schema: test; table: t1; type: Insert.*")
}

func (s *testPrintSuite) TestPrintDDL(c *check.C) {
ddlBinlog := &pb.Binlog{
Tp: pb.BinlogType_DDL,
DdlQuery: []byte("create database test;"),
}

out := capturer.CaptureStdout(func() {
printDDL(ddlBinlog)
})
lines := strings.Split(strings.TrimSpace(out), "\n")
c.Assert(lines, check.HasLen, 1)
c.Assert(lines[0], check.Matches, ".*DDL query: create database test;.*")
}

func (s *testPrintSuite) TestPrintRow(c *check.C) {
cols := generateColumns(c)

insertEvent := &pb.Event{
Tp: pb.EventType_Insert,
Row: [][]byte{cols[0], cols[1]},
}

out := capturer.CaptureStdout(func() {
printEvent(insertEvent)
})
lines := strings.Split(strings.TrimSpace(out), "\n")
c.Assert(lines, check.HasLen, 3)
c.Assert(lines[0], check.Equals, "schema: ; table: ; type: Insert")
c.Assert(lines[1], check.Equals, "a(int): 1")
c.Assert(lines[2], check.Equals, "b(varchar): test")

deleteEvent := &pb.Event{
Tp: pb.EventType_Delete,
Row: [][]byte{cols[0], cols[1]},
}
out = capturer.CaptureStdout(func() {
printEvent(deleteEvent)
})
lines = strings.Split(strings.TrimSpace(out), "\n")
c.Assert(lines, check.HasLen, 3)
c.Assert(lines[0], check.Equals, "schema: ; table: ; type: Delete")
c.Assert(lines[1], check.Equals, "a(int): 1")
c.Assert(lines[2], check.Equals, "b(varchar): test")

updateEvent := &pb.Event{
Tp: pb.EventType_Update,
Row: [][]byte{cols[2]},
}
out = capturer.CaptureStdout(func() {
printEvent(updateEvent)
})
lines = strings.Split(strings.TrimSpace(out), "\n")
c.Assert(lines, check.HasLen, 2)
c.Assert(lines[0], check.Equals, "schema: ; table: ; type: Update")
c.Assert(lines[1], check.Equals, "c(varchar): test => abc")
}
41 changes: 41 additions & 0 deletions reparo/syncer/syncer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package syncer

import (
"reflect"

"github.com/pingcap/check"
)

type testSyncerSuite struct{}

var _ = check.Suite(&testSyncerSuite{})

func (s *testSyncerSuite) TestNewSyncer(c *check.C) {
cfg := new(DBConfig)

testCases := []struct {
typeStr string
tp reflect.Type
checker check.Checker
}{
{
"print",
reflect.TypeOf(new(printSyncer)),
check.Equals,
}, {
"memory",
reflect.TypeOf(new(MemSyncer)),
check.Equals,
}, {
"print",
reflect.TypeOf(new(MemSyncer)),
check.Not(check.Equals),
},
}

for _, testCase := range testCases {
syncer, err := New(testCase.typeStr, cfg)
c.Assert(err, check.IsNil)
c.Assert(reflect.TypeOf(syncer), testCase.checker, testCase.tp)
}
}
4 changes: 2 additions & 2 deletions reparo/syncer/translate.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ func pbBinlogToTxn(binlog *pb.Binlog) (txn *loader.Txn, err error) {
return nil, errors.Trace(err)
}

_, newDatum, err := codec.DecodeOne(col.Value)
_, oldDatum, err := codec.DecodeOne(col.Value)
if err != nil {
return nil, errors.Trace(err)
}
_, oldDatum, err := codec.DecodeOne(col.ChangedValue)
_, newDatum, err := codec.DecodeOne(col.ChangedValue)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the bug? ***

if err != nil {
return nil, errors.Trace(err)
}
Expand Down
Loading