github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/shardddl/pessimism/lock_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 pessimism
    15  
    16  import (
    17  	. "github.com/pingcap/check"
    18  	"github.com/pingcap/tiflow/dm/pkg/terror"
    19  )
    20  
    21  type testLock struct{}
    22  
    23  var _ = Suite(&testLock{})
    24  
    25  func (t *testLock) TestLock(c *C) {
    26  	var (
    27  		ID      = "test-`foo`.`bar`"
    28  		task    = "test"
    29  		source1 = "mysql-replica-1"
    30  		source2 = "mysql-replica-2"
    31  		source3 = "mysql-replica-3"
    32  		DDLs    = []string{
    33  			"ALTER TABLE bar ADD COLUMN c1 INT",
    34  			"ALTER TABLE bar ADD COLUMN c2 INT",
    35  		}
    36  	)
    37  
    38  	// create the lock with only 1 source.
    39  	l1 := NewLock(ID, task, source1, DDLs, []string{source1})
    40  
    41  	// DDLs mismatch.
    42  	synced, remain, err := l1.TrySync(source1, DDLs[1:], []string{source1})
    43  	c.Assert(terror.ErrMasterShardingDDLDiff.Equal(err), IsTrue)
    44  	c.Assert(synced, IsFalse)
    45  	c.Assert(remain, Equals, 1)
    46  	c.Assert(l1.Ready(), DeepEquals, map[string]bool{source1: false})
    47  	synced, _ = l1.IsSynced()
    48  	c.Assert(synced, IsFalse)
    49  	c.Assert(l1.IsDone(source1), IsFalse)
    50  	c.Assert(l1.IsResolved(), IsFalse)
    51  
    52  	// synced.
    53  	synced, remain, err = l1.TrySync(source1, DDLs, []string{source1})
    54  	c.Assert(err, IsNil)
    55  	c.Assert(synced, IsTrue)
    56  	c.Assert(remain, Equals, 0)
    57  	c.Assert(l1.Ready(), DeepEquals, map[string]bool{source1: true})
    58  	synced, _ = l1.IsSynced()
    59  	c.Assert(synced, IsTrue)
    60  	c.Assert(l1.IsDone(source1), IsFalse)
    61  	c.Assert(l1.IsResolved(), IsFalse)
    62  
    63  	// mark done.
    64  	l1.MarkDone(source1)
    65  	c.Assert(l1.IsDone(source1), IsTrue)
    66  	c.Assert(l1.IsResolved(), IsTrue)
    67  
    68  	// create the lock with 2 sources.
    69  	l2 := NewLock(ID, task, source1, DDLs, []string{source1, source2})
    70  
    71  	// join a new source.
    72  	synced, remain, err = l2.TrySync(source1, DDLs, []string{source2, source3})
    73  	c.Assert(err, IsNil)
    74  	c.Assert(synced, IsFalse)
    75  	c.Assert(remain, Equals, 2)
    76  	c.Assert(l2.Ready(), DeepEquals, map[string]bool{
    77  		source1: true,
    78  		source2: false,
    79  		source3: false,
    80  	})
    81  
    82  	// sync other sources.
    83  	synced, remain, err = l2.TrySync(source2, DDLs, []string{})
    84  	c.Assert(err, IsNil)
    85  	c.Assert(synced, IsFalse)
    86  	c.Assert(remain, Equals, 1)
    87  	c.Assert(l2.Ready(), DeepEquals, map[string]bool{
    88  		source1: true,
    89  		source2: true,
    90  		source3: false,
    91  	})
    92  	synced, remain, err = l2.TrySync(source3, DDLs, nil)
    93  	c.Assert(err, IsNil)
    94  	c.Assert(synced, IsTrue)
    95  	c.Assert(remain, Equals, 0)
    96  	c.Assert(l2.Ready(), DeepEquals, map[string]bool{
    97  		source1: true,
    98  		source2: true,
    99  		source3: true,
   100  	})
   101  
   102  	// done none.
   103  	c.Assert(l2.IsDone(source1), IsFalse)
   104  	c.Assert(l2.IsDone(source2), IsFalse)
   105  	c.Assert(l2.IsDone(source3), IsFalse)
   106  	c.Assert(l2.IsResolved(), IsFalse)
   107  
   108  	// done some.
   109  	l2.MarkDone(source1)
   110  	l2.MarkDone(source2)
   111  	c.Assert(l2.IsDone(source1), IsTrue)
   112  	c.Assert(l2.IsDone(source2), IsTrue)
   113  	c.Assert(l2.IsDone(source3), IsFalse)
   114  	c.Assert(l2.IsResolved(), IsFalse)
   115  
   116  	// done all.
   117  	l2.MarkDone(source3)
   118  	c.Assert(l2.IsDone(source3), IsTrue)
   119  	c.Assert(l2.IsResolved(), IsTrue)
   120  
   121  	// mark on not existing source has no effect.
   122  	l2.MarkDone("not-exist-source")
   123  	c.Assert(l2.IsResolved(), IsTrue)
   124  
   125  	// create the lock with 2 sources.
   126  	l3 := NewLock(ID, task, source1, DDLs, []string{source1, source2})
   127  	l3.ForceSynced()
   128  	synced, remain = l3.IsSynced()
   129  	c.Assert(synced, IsTrue)
   130  	c.Assert(remain, Equals, 0)
   131  
   132  	// revert the synced stage.
   133  	l3.RevertSynced([]string{source2})
   134  	synced, remain = l3.IsSynced()
   135  	c.Assert(synced, IsFalse)
   136  	c.Assert(remain, Equals, 1)
   137  	ready := l3.Ready()
   138  	c.Assert(ready[source1], IsTrue)
   139  	c.Assert(ready[source2], IsFalse)
   140  }