github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/cdc/sink/common/common_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 common 15 16 import ( 17 "sort" 18 "testing" 19 20 "github.com/google/go-cmp/cmp" 21 "github.com/pingcap/check" 22 "github.com/pingcap/ticdc/cdc/model" 23 "github.com/pingcap/ticdc/pkg/util/testleak" 24 ) 25 26 type SinkCommonSuite struct{} 27 28 func Test(t *testing.T) { check.TestingT(t) } 29 30 var _ = check.Suite(&SinkCommonSuite{}) 31 32 func (s SinkCommonSuite) TestSplitResolvedTxn(c *check.C) { 33 defer testleak.AfterTest(c)() 34 testCases := [][]struct { 35 input []*model.RowChangedEvent 36 resolvedTs model.Ts 37 expected map[model.TableID][]*model.SingleTableTxn 38 }{{{ // Testing basic transaction collocation, no txns with the same committs 39 input: []*model.RowChangedEvent{ 40 {StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}}, 41 {StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}}, 42 {StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}}, 43 {StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 3}}, 44 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 45 {StartTs: 1, CommitTs: 11, Table: &model.TableName{TableID: 1}}, 46 {StartTs: 1, CommitTs: 12, Table: &model.TableName{TableID: 2}}, 47 }, 48 resolvedTs: 6, 49 expected: map[model.TableID][]*model.SingleTableTxn{ 50 1: {{Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 5, Rows: []*model.RowChangedEvent{ 51 {StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}}, 52 {StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}}, 53 }}}, 54 2: {{Table: &model.TableName{TableID: 2}, StartTs: 1, CommitTs: 6, Rows: []*model.RowChangedEvent{ 55 {StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}}, 56 }}}, 57 }, 58 }, { 59 input: []*model.RowChangedEvent{ 60 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 3}}, 61 }, 62 resolvedTs: 13, 63 expected: map[model.TableID][]*model.SingleTableTxn{ 64 1: {{Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 8, Rows: []*model.RowChangedEvent{ 65 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 66 }}, {Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 11, Rows: []*model.RowChangedEvent{ 67 {StartTs: 1, CommitTs: 11, Table: &model.TableName{TableID: 1}}, 68 }}}, 69 2: {{Table: &model.TableName{TableID: 2}, StartTs: 1, CommitTs: 12, Rows: []*model.RowChangedEvent{ 70 {StartTs: 1, CommitTs: 12, Table: &model.TableName{TableID: 2}}, 71 }}}, 72 3: {{Table: &model.TableName{TableID: 3}, StartTs: 1, CommitTs: 7, Rows: []*model.RowChangedEvent{ 73 {StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 3}}, 74 }}, {Table: &model.TableName{TableID: 3}, StartTs: 1, CommitTs: 8, Rows: []*model.RowChangedEvent{ 75 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 3}}, 76 }}}, 77 }, 78 }}, {{ // Testing the short circuit path 79 input: []*model.RowChangedEvent{}, 80 resolvedTs: 6, 81 expected: nil, 82 }, { 83 input: []*model.RowChangedEvent{ 84 {StartTs: 1, CommitTs: 11, Table: &model.TableName{TableID: 1}}, 85 {StartTs: 1, CommitTs: 12, Table: &model.TableName{TableID: 1}}, 86 {StartTs: 1, CommitTs: 13, Table: &model.TableName{TableID: 2}}, 87 }, 88 resolvedTs: 6, 89 expected: map[model.TableID][]*model.SingleTableTxn{}, 90 }}, {{ // Testing the txns with the same commitTs 91 input: []*model.RowChangedEvent{ 92 {StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}}, 93 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 94 {StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}}, 95 {StartTs: 2, CommitTs: 6, Table: &model.TableName{TableID: 2}}, 96 {StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 97 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 98 {StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 99 {StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}}, 100 {StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 2}}, 101 }, 102 resolvedTs: 6, 103 expected: map[model.TableID][]*model.SingleTableTxn{ 104 1: {{Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 5, Rows: []*model.RowChangedEvent{ 105 {StartTs: 1, CommitTs: 5, Table: &model.TableName{TableID: 1}}, 106 }}}, 107 2: {{Table: &model.TableName{TableID: 2}, StartTs: 1, CommitTs: 6, Rows: []*model.RowChangedEvent{ 108 {StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}}, 109 {StartTs: 1, CommitTs: 6, Table: &model.TableName{TableID: 2}}, 110 }}, {Table: &model.TableName{TableID: 2}, StartTs: 2, CommitTs: 6, Rows: []*model.RowChangedEvent{ 111 {StartTs: 2, CommitTs: 6, Table: &model.TableName{TableID: 2}}, 112 }}}, 113 }, 114 }, { 115 input: []*model.RowChangedEvent{ 116 {StartTs: 2, CommitTs: 7, Table: &model.TableName{TableID: 2}}, 117 {StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 2}}, 118 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 119 {StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 120 {StartTs: 1, CommitTs: 9, Table: &model.TableName{TableID: 1}}, 121 }, 122 resolvedTs: 13, 123 expected: map[model.TableID][]*model.SingleTableTxn{ 124 1: {{Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 8, Rows: []*model.RowChangedEvent{ 125 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 126 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 127 {StartTs: 1, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 128 }}, {Table: &model.TableName{TableID: 1}, StartTs: 2, CommitTs: 8, Rows: []*model.RowChangedEvent{ 129 {StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 130 {StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 131 {StartTs: 2, CommitTs: 8, Table: &model.TableName{TableID: 1}}, 132 }}, {Table: &model.TableName{TableID: 1}, StartTs: 1, CommitTs: 9, Rows: []*model.RowChangedEvent{ 133 {StartTs: 1, CommitTs: 9, Table: &model.TableName{TableID: 1}}, 134 }}}, 135 2: {{Table: &model.TableName{TableID: 2}, StartTs: 1, CommitTs: 7, Rows: []*model.RowChangedEvent{ 136 {StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 2}}, 137 {StartTs: 1, CommitTs: 7, Table: &model.TableName{TableID: 2}}, 138 }}, {Table: &model.TableName{TableID: 2}, StartTs: 2, CommitTs: 7, Rows: []*model.RowChangedEvent{ 139 {StartTs: 2, CommitTs: 7, Table: &model.TableName{TableID: 2}}, 140 }}}, 141 }, 142 }}} 143 for _, tc := range testCases { 144 cache := NewUnresolvedTxnCache() 145 for _, t := range tc { 146 cache.Append(nil, t.input...) 147 resolved := cache.Resolved(t.resolvedTs) 148 for tableID, txns := range resolved { 149 sort.Slice(txns, func(i, j int) bool { 150 if txns[i].CommitTs != txns[j].CommitTs { 151 return txns[i].CommitTs < txns[j].CommitTs 152 } 153 return txns[i].StartTs < txns[j].StartTs 154 }) 155 resolved[tableID] = txns 156 } 157 c.Assert(resolved, check.DeepEquals, t.expected, 158 check.Commentf("%s", cmp.Diff(resolved, t.expected))) 159 } 160 } 161 }