github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/binlog/reader/mock_test.go (about) 1 // Copyright 2019 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package reader 15 16 import ( 17 "context" 18 "errors" 19 "testing" 20 "time" 21 22 "github.com/go-mysql-org/go-mysql/mysql" 23 "github.com/go-mysql-org/go-mysql/replication" 24 "github.com/stretchr/testify/require" 25 ) 26 27 type testMockCase struct { 28 ev *replication.BinlogEvent 29 err error 30 } 31 32 func TestRead(t *testing.T) { 33 t.Parallel() 34 r := NewMockReader() 35 36 // some interface methods do nothing 37 require.Nil(t, r.StartSyncByPos(mysql.Position{})) 38 require.Nil(t, r.StartSyncByGTID(nil)) 39 require.Nil(t, r.Status()) 40 require.Nil(t, r.Close()) 41 42 // replace with special error 43 mockR := r.(*MockReader) 44 errStartByPos := errors.New("special error for start by pos") 45 errStartByGTID := errors.New("special error for start by GTID") 46 errClose := errors.New("special error for close") 47 mockR.ErrStartByPos = errStartByPos 48 mockR.ErrStartByGTID = errStartByGTID 49 mockR.ErrClose = errClose 50 require.Equal(t, errStartByPos, r.StartSyncByPos(mysql.Position{})) 51 require.Equal(t, errStartByGTID, r.StartSyncByGTID(nil)) 52 require.Equal(t, errClose, r.Close()) 53 54 cases := []testMockCase{ 55 { 56 ev: &replication.BinlogEvent{ 57 RawData: []byte{1}, 58 }, 59 err: nil, 60 }, 61 { 62 ev: &replication.BinlogEvent{ 63 RawData: []byte{2}, 64 }, 65 err: nil, 66 }, 67 { 68 ev: nil, 69 err: errors.New("1"), 70 }, 71 { 72 ev: &replication.BinlogEvent{ 73 RawData: []byte{3}, 74 }, 75 err: nil, 76 }, 77 { 78 ev: nil, 79 err: errors.New("2"), 80 }, 81 } 82 83 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 84 defer cancel() 85 86 go func() { 87 for _, cs := range cases { 88 if cs.err != nil { 89 require.Nil(t, mockR.PushError(ctx, cs.err)) 90 } else { 91 require.Nil(t, mockR.PushEvent(ctx, cs.ev)) 92 } 93 } 94 }() 95 96 obtained := make([]testMockCase, 0, len(cases)) 97 for { 98 ev, err := r.GetEvent(ctx) 99 if err != nil { 100 obtained = append(obtained, testMockCase{ev: nil, err: err}) 101 } else { 102 obtained = append(obtained, testMockCase{ev: ev, err: nil}) 103 } 104 require.Nil(t, ctx.Err()) 105 if len(obtained) == len(cases) { 106 break 107 } 108 } 109 110 require.Equal(t, cases, obtained) 111 112 cancel() // cancel manually 113 require.Equal(t, ctx.Err(), mockR.PushError(ctx, cases[0].err)) 114 require.Equal(t, ctx.Err(), mockR.PushEvent(ctx, cases[0].ev)) 115 ev, err := r.GetEvent(ctx) 116 require.Nil(t, ev) 117 require.Equal(t, ctx.Err(), err) 118 }