github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/cdc/puller/mock_puller_test.go (about) 1 // Copyright 2020 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 puller 15 16 /* 17 import ( 18 "context" 19 "sync" 20 "sync/atomic" 21 "time" 22 23 "github.com/pingcap/check" 24 "github.com/pingcap/errors" 25 "github.com/pingcap/ticdc/cdc/entry" 26 "github.com/pingcap/ticdc/cdc/model" 27 "github.com/pingcap/ticdc/pkg/util" 28 "github.com/pingcap/tidb/store/tikv/oracle" 29 ) 30 31 type mockPullerSuite struct{} 32 33 var _ = check.Suite(&mockPullerSuite{}) 34 35 func (s *mockPullerSuite) TestTxnSort(c *check.C) { 36 defer testleak.AfterTest(c)() 37 pm := NewMockPullerManager(c, true) 38 plr := pm.CreatePuller(0, []regionspan.Span{regionspan.Span{}.Hack()}) 39 ctx, cancel := context.WithCancel(context.Background()) 40 defer cancel() 41 ts := uint64(0) 42 go func() { 43 err := plr.CollectRawTxns(ctx, func(ctx context.Context, txn model.RawTxn) error { 44 c.Assert(ts, check.Less, txn.Ts) 45 atomic.StoreUint64(&ts, txn.Ts) 46 return nil 47 }) 48 c.Assert(err, check.IsNil) 49 }() 50 pm.Run(context.Background()) 51 pm.MustExec("create table test.test(id varchar(255) primary key, a int)") 52 pm.MustExec("insert into test.test(id, a) values(?, ?)", 1, 1) 53 pm.MustExec("update test.test set id = ? where a = ?", 6, 1) 54 pm.MustExec("insert into test.test(id, a) values(?, ?)", 2, 2) 55 pm.MustExec("insert into test.test(id, a) values(?, ?)", 3, 3) 56 pm.MustExec("delete from test.test") 57 waitForGrowingTs(&ts, oracle.EncodeTSO(time.Now().Unix()*1000)) 58 } 59 60 func (s *mockPullerSuite) TestDDLPuller(c *check.C) { 61 defer testleak.AfterTest(c)() 62 pm := NewMockPullerManager(c, true) 63 plr := pm.CreatePuller(0, []regionspan.Span{regionspan.GetDDLSpan()}) 64 ctx, cancel := context.WithCancel(context.Background()) 65 defer cancel() 66 ts := uint64(0) 67 txnMounter := entry.NewTxnMounter(nil) 68 go func() { 69 err := plr.CollectRawTxns(ctx, func(ctx context.Context, rawTxn model.RawTxn) error { 70 c.Assert(ts, check.Less, rawTxn.Ts) 71 atomic.StoreUint64(&ts, rawTxn.Ts) 72 if len(rawTxn.Entries) == 0 { 73 return nil 74 } 75 for _, e := range rawTxn.Entries { 76 c.Assert(util.KeyInSpan(e.Key, regionspan.GetDDLSpan()), check.IsTrue) 77 } 78 t, err := txnMounter.Mount(rawTxn) 79 c.Assert(err, check.IsNil) 80 if !t.IsDDL() { 81 return nil 82 } 83 c.Assert(t.DDL.Table, check.Equals, "test") 84 c.Assert(t.DDL.Database, check.Equals, "test") 85 return nil 86 }) 87 c.Assert(err, check.IsNil) 88 }() 89 pm.Run(context.Background()) 90 pm.MustExec("create table test.test(id varchar(255) primary key, a int)") 91 pm.MustExec("insert into test.test(id, a) values(?, ?)", 1, 1) 92 pm.MustExec("update test.test set id = ? where a = ?", 6, 1) 93 pm.MustExec("insert into test.test(id, a) values(?, ?)", 2, 2) 94 pm.MustExec("insert into test.test(id, a) values(?, ?)", 3, 3) 95 pm.MustExec("delete from test.test") 96 waitForGrowingTs(&ts, oracle.EncodeTSO(time.Now().Unix()*1000)) 97 } 98 99 func (s *mockPullerSuite) TestStartTs(c *check.C) { 100 defer testleak.AfterTest(c)() 101 pm := NewMockPullerManager(c, true) 102 plrA := pm.CreatePuller(0, []regionspan.Span{regionspan.Span{}.Hack()}) 103 ctx, cancel := context.WithCancel(context.Background()) 104 ts := uint64(0) 105 var rawTxns []model.RawTxn 106 var mu sync.Mutex 107 go func() { 108 err := plrA.CollectRawTxns(ctx, func(ctx context.Context, txn model.RawTxn) error { 109 mu.Lock() 110 defer mu.Unlock() 111 c.Assert(ts, check.Less, txn.Ts) 112 atomic.StoreUint64(&ts, txn.Ts) 113 rawTxns = append(rawTxns, txn) 114 return nil 115 }) 116 c.Assert(errors.Cause(err), check.Equals, context.Canceled) 117 }() 118 pm.Run(context.Background()) 119 pm.MustExec("create table test.test(id varchar(255) primary key, a int)") 120 pm.MustExec("insert into test.test(id, a) values(?, ?)", 1, 1) 121 pm.MustExec("update test.test set id = ? where a = ?", 6, 1) 122 pm.MustExec("insert into test.test(id, a) values(?, ?)", 2, 2) 123 pm.MustExec("insert into test.test(id, a) values(?, ?)", 3, 3) 124 pm.MustExec("delete from test.test") 125 waitForGrowingTs(&ts, oracle.EncodeTSO(time.Now().Unix()*1000)) 126 cancel() 127 mu.Lock() 128 index := len(rawTxns) / 2 129 plrB := pm.CreatePuller(rawTxns[index].Ts, []regionspan.Span{regionspan.Span{}.Hack()}) 130 mu.Unlock() 131 ctx, cancel = context.WithCancel(context.Background()) 132 err := plrB.CollectRawTxns(ctx, func(ctx context.Context, txn model.RawTxn) error { 133 mu.Lock() 134 defer mu.Unlock() 135 if index >= len(rawTxns) { 136 cancel() 137 return nil 138 } 139 c.Assert(rawTxns[index], check.DeepEquals, txn) 140 index++ 141 return nil 142 }) 143 c.Assert(errors.Cause(err), check.Equals, context.Canceled) 144 } 145 146 func waitForGrowingTs(growingTs *uint64, targetTs uint64) { 147 for { 148 growingTsLocal := atomic.LoadUint64(growingTs) 149 if growingTsLocal >= targetTs { 150 return 151 } 152 time.Sleep(100 * time.Millisecond) 153 } 154 } 155 */