github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/simulator/mcp/uk_test.go (about) 1 // Copyright 2022 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 mcp 15 16 import ( 17 "sync" 18 "testing" 19 20 "github.com/pingcap/tiflow/dm/pkg/log" 21 "github.com/stretchr/testify/suite" 22 ) 23 24 type testUniqueKeySuite struct { 25 suite.Suite 26 } 27 28 func (s *testUniqueKeySuite) SetupSuite() { 29 s.Require().Nil(log.InitLogger(&log.Config{})) 30 } 31 32 func (s *testUniqueKeySuite) TestUKClone() { 33 origUKCol1Value := 111 34 origUKCol2Value := "COL1" 35 originalUK := &UniqueKey{ 36 rowID: -1, 37 value: map[string]interface{}{ 38 "col1": origUKCol1Value, 39 "col2": origUKCol2Value, 40 }, 41 } 42 newUKCol1Value := 222 43 newUKCol2Value := "COL2" 44 clonedUK := originalUK.Clone() 45 clonedUK.value["col1"] = newUKCol1Value 46 clonedUK.value["col2"] = newUKCol2Value 47 48 s.T().Logf("original UK: %v; cloned UK: %v\n", originalUK, clonedUK) 49 50 s.Equalf(origUKCol1Value, originalUK.value["col1"], "original.%s value incorrect", "col1") 51 s.Equalf(origUKCol2Value, originalUK.value["col2"], "original.%s value incorrect", "col2") 52 s.Equalf(newUKCol1Value, clonedUK.value["col1"], "cloned.%s value incorrect", "col1") 53 s.Equalf(newUKCol2Value, clonedUK.value["col2"], "cloned.%s value incorrect", "col2") 54 } 55 56 func (s *testUniqueKeySuite) TestUKChangeBasic() { 57 col1Value := 111 58 col2Value := "aaa" 59 theValueMap := map[string]interface{}{ 60 "col1": col1Value, 61 "col2": col2Value, 62 } 63 theUK := NewUniqueKey(-1, theValueMap) 64 s.Equalf(col1Value, theUK.value["col1"], "%s value incorrect", "col1") 65 s.Equalf(col2Value, theUK.value["col2"], "%s value incorrect", "col2") 66 67 theValueMap["col1"] = 222 68 theValueMap["col2"] = "bbb" 69 s.Equalf(col1Value, theUK.value["col1"], "%s value incorrect", "col1") 70 s.Equalf(col2Value, theUK.value["col2"], "%s value incorrect", "col2") 71 72 assignedValueMap := theUK.GetValue() 73 s.Equalf(col1Value, assignedValueMap["col1"], "%s value incorrect", "col1") 74 s.Equalf(col2Value, assignedValueMap["col2"], "%s value incorrect", "col2") 75 76 newRowID := 999 77 theUK.SetRowID(newRowID) 78 s.Equal(newRowID, theUK.GetRowID(), "row ID value incorrect") 79 80 newCol1Value := 333 81 newCol2Value := "ccc" 82 newValueMap := map[string]interface{}{ 83 "col1": newCol1Value, 84 "col2": newCol2Value, 85 } 86 theUK.SetValue(newValueMap) 87 s.Equalf(newCol1Value, theUK.value["col1"], "%s value incorrect", "col1") 88 s.Equalf(newCol2Value, theUK.value["col2"], "%s value incorrect", "col2") 89 s.Equalf(col1Value, assignedValueMap["col1"], "assigned map's %s value incorrect", "col1") 90 s.Equalf(col2Value, assignedValueMap["col2"], "assigned map's %s value incorrect", "col2") 91 92 newValueMap["col1"] = 444 93 newValueMap["col2"] = "ddd" 94 s.Equalf(newCol1Value, theUK.value["col1"], "%s value incorrect", "col1") 95 s.Equalf(newCol2Value, theUK.value["col2"], "%s value incorrect", "col2") 96 } 97 98 func (s *testUniqueKeySuite) TestUKParallelChange() { 99 theUK := NewUniqueKey(-1, nil) 100 pendingCh := make(chan struct{}) 101 var wg sync.WaitGroup 102 targetID := 100 103 workerCnt := 10 104 wg.Add(workerCnt) 105 for i := 0; i < workerCnt; i++ { 106 go func() { 107 defer wg.Done() 108 <-pendingCh 109 for i := 1; i <= targetID; i++ { 110 theUK.SetRowID(i) 111 theUK.SetValue(map[string]interface{}{ 112 "id": i, 113 }) 114 } 115 }() 116 } 117 close(pendingCh) 118 wg.Wait() 119 s.Equal(targetID, theUK.GetRowID(), "row ID value incorrect") 120 theValue := theUK.GetValue() 121 s.Equal(targetID, theValue["id"], "ID column value incorrect") 122 s.Equal(targetID, theUK.value["id"], "ID column value in UK incorrect") 123 } 124 125 func (s *testUniqueKeySuite) TestUKValueEqual() { 126 col1Value := 111 127 col2Value := "aaa" 128 uk1 := &UniqueKey{ 129 rowID: -1, 130 value: map[string]interface{}{ 131 "col1": col1Value, 132 "col2": col2Value, 133 }, 134 } 135 uk2 := &UniqueKey{ 136 rowID: 100, 137 value: map[string]interface{}{ 138 "col1": col1Value, 139 "col2": col2Value, 140 }, 141 } 142 s.Equal(true, uk1.IsValueEqual(uk2), "uk1 should equal uk2 on value") 143 s.Equal(true, uk2.IsValueEqual(uk1), "uk2 should equal uk1 on value") 144 uk3 := &UniqueKey{ 145 rowID: 100, 146 value: map[string]interface{}{ 147 "col1": col1Value, 148 "col2": "bbb", 149 }, 150 } 151 s.Equal(false, uk1.IsValueEqual(uk3), "uk1 should not equal uk3 on value") 152 s.Equal(false, uk3.IsValueEqual(uk1), "uk3 should not equal uk1 on value") 153 uk4 := &UniqueKey{ 154 rowID: 100, 155 value: map[string]interface{}{ 156 "col3": 321, 157 }, 158 } 159 s.Equal(false, uk1.IsValueEqual(uk4), "uk1 should not equal uk4 on value") 160 s.Equal(false, uk4.IsValueEqual(uk1), "uk4 should not equal uk1 on value") 161 uk5 := &UniqueKey{ 162 rowID: 100, 163 value: map[string]interface{}{ 164 "col3": 321, 165 "col1": col1Value, 166 "col2": col2Value, 167 }, 168 } 169 s.Equal(false, uk1.IsValueEqual(uk5), "uk1 should not equal uk5 on value") 170 s.Equal(false, uk5.IsValueEqual(uk1), "uk5 should not equal uk1 on value") 171 } 172 173 func TestUniqueKeySuite(t *testing.T) { 174 suite.Run(t, &testUniqueKeySuite{}) 175 }