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  }