github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/upgrade/upgrade_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 upgrade 15 16 import ( 17 "context" 18 "fmt" 19 "testing" 20 21 . "github.com/pingcap/check" 22 "github.com/pingcap/tiflow/dm/common" 23 clientv3 "go.etcd.io/etcd/client/v3" 24 "go.etcd.io/etcd/tests/v3/integration" 25 ) 26 27 var ( 28 mockCluster *integration.ClusterV3 29 bigTxnCluster *integration.ClusterV3 30 etcdTestCli *clientv3.Client 31 bigTxnTestCli *clientv3.Client 32 ) 33 34 func TestUpgrade(t *testing.T) { 35 integration.BeforeTestExternal(t) 36 37 suite.(*testForEtcd).testT = t 38 suiteForBigTxn.(*testForBigTxn).testT = t 39 40 TestingT(t) 41 } 42 43 func clearTestData(c *C) { 44 clearVersion := clientv3.OpDelete(common.ClusterVersionKey) 45 _, err := etcdTestCli.Txn(context.Background()).Then(clearVersion).Commit() 46 c.Assert(err, IsNil) 47 } 48 49 type testForEtcd struct { 50 testT *testing.T 51 } 52 53 type testForBigTxn struct { 54 testT *testing.T 55 } 56 57 var ( 58 suite = SerialSuites(&testForEtcd{}) 59 suiteForBigTxn = SerialSuites(&testForBigTxn{}) 60 ) 61 62 func (t *testForEtcd) SetUpSuite(c *C) { 63 mockCluster = integration.NewClusterV3(t.testT, &integration.ClusterConfig{Size: 1}) 64 etcdTestCli = mockCluster.RandClient() 65 } 66 67 func (t *testForEtcd) TearDownSuite(c *C) { 68 mockCluster.Terminate(t.testT) 69 } 70 71 func (t *testForBigTxn) SetUpSuite(c *C) { 72 bigTxnCluster = integration.NewClusterV3(t.testT, &integration.ClusterConfig{Size: 1, MaxTxnOps: 2048}) 73 bigTxnTestCli = bigTxnCluster.RandClient() 74 } 75 76 func (t *testForBigTxn) TearDownSuite(c *C) { 77 bigTxnCluster.Terminate(t.testT) 78 } 79 80 func (t *testForEtcd) TestTryUpgrade(c *C) { 81 defer clearTestData(c) 82 83 // mock upgrade functions. 84 oldUpgrades := upgrades 85 defer func() { 86 upgrades = oldUpgrades 87 }() 88 mockVerNo := uint64(0) 89 upgrades = []func(cli *clientv3.Client, uctx Context) error{ 90 func(cli *clientv3.Client, uctx Context) error { 91 mockVerNo = currentInternalNo + 1 92 return nil 93 }, 94 } 95 96 // no previous version exist, new cluster. 97 ver, rev1, err := GetVersion(etcdTestCli) 98 c.Assert(err, IsNil) 99 c.Assert(rev1, Greater, int64(0)) 100 c.Assert(ver.NotSet(), IsTrue) 101 102 // try to upgrade, run actual upgrade functions 103 c.Assert(TryUpgrade(etcdTestCli, newUpgradeContext()), IsNil) 104 ver, rev2, err := GetVersion(etcdTestCli) 105 c.Assert(err, IsNil) 106 c.Assert(rev2, Greater, rev1) 107 c.Assert(ver, DeepEquals, CurrentVersion) 108 c.Assert(mockVerNo, Equals, uint64(5)) 109 110 // try to upgrade again, do nothing because the version is the same. 111 mockVerNo = 0 112 c.Assert(TryUpgrade(etcdTestCli, newUpgradeContext()), IsNil) 113 ver, rev3, err := GetVersion(etcdTestCli) 114 c.Assert(err, IsNil) 115 c.Assert(rev3, Equals, rev2) 116 c.Assert(ver, DeepEquals, CurrentVersion) 117 c.Assert(mockVerNo, Equals, uint64(0)) 118 119 // mock a newer current version. 120 oldCurrentVer := CurrentVersion 121 defer func() { 122 CurrentVersion = oldCurrentVer 123 }() 124 newerVer := NewVersion(currentInternalNo+1, "mock-current-ver") 125 CurrentVersion = newerVer 126 127 // try to upgrade, to a newer version, upgrade operations applied. 128 c.Assert(TryUpgrade(etcdTestCli, newUpgradeContext()), IsNil) 129 ver, rev4, err := GetVersion(etcdTestCli) 130 c.Assert(err, IsNil) 131 c.Assert(rev4, Greater, rev3) 132 c.Assert(ver, DeepEquals, newerVer) 133 c.Assert(mockVerNo, Equals, currentInternalNo+1) 134 135 // try to upgrade, to an older version, do nothing. 136 mockVerNo = 0 137 CurrentVersion = oldCurrentVer 138 c.Assert(TryUpgrade(etcdTestCli, newUpgradeContext()), IsNil) 139 ver, rev5, err := GetVersion(etcdTestCli) 140 c.Assert(err, IsNil) 141 c.Assert(rev5, Equals, rev4) 142 c.Assert(ver, DeepEquals, newerVer) // not changed. 143 c.Assert(mockVerNo, Equals, uint64(0)) 144 } 145 146 func (t *testForEtcd) TestUpgradeToVer3(c *C) { 147 ctx := context.Background() 148 source := "source-1" 149 oldKey := common.UpstreamConfigKeyAdapterV1.Encode(source) 150 oldVal := "test" 151 152 _, err := etcdTestCli.Put(ctx, oldKey, oldVal) 153 c.Assert(err, IsNil) 154 c.Assert(upgradeToVer3(ctx, etcdTestCli), IsNil) 155 156 newKey := common.UpstreamConfigKeyAdapter.Encode(source) 157 resp, err := etcdTestCli.Get(ctx, newKey) 158 c.Assert(err, IsNil) 159 c.Assert(resp.Kvs, HasLen, 1) 160 c.Assert(string(resp.Kvs[0].Value), Equals, oldVal) 161 162 // test won't overwrite new value 163 newVal := "test2" 164 _, err = etcdTestCli.Put(ctx, newKey, newVal) 165 c.Assert(err, IsNil) 166 c.Assert(upgradeToVer3(ctx, etcdTestCli), IsNil) 167 resp, err = etcdTestCli.Get(ctx, newKey) 168 c.Assert(err, IsNil) 169 c.Assert(resp.Kvs, HasLen, 1) 170 c.Assert(string(resp.Kvs[0].Value), Equals, newVal) 171 172 for i := 0; i < 500; i++ { 173 key := common.UpstreamConfigKeyAdapterV1.Encode(fmt.Sprintf("%s-%d", source, i)) 174 val := fmt.Sprintf("%s-%d", oldVal, i) 175 _, err := etcdTestCli.Put(ctx, key, val) 176 c.Assert(err, IsNil) 177 } 178 c.Assert(upgradeToVer3(ctx, etcdTestCli), ErrorMatches, ".*too many operations in txn request.*") 179 } 180 181 func (t *testForBigTxn) TestUpgradeToVer3(c *C) { 182 source := "source-1" 183 oldVal := "test" 184 ctx := context.Background() 185 186 for i := 0; i < 1000; i++ { 187 key := common.UpstreamConfigKeyAdapterV1.Encode(fmt.Sprintf("%s-%d", source, i)) 188 val := fmt.Sprintf("%s-%d", oldVal, i) 189 _, err := bigTxnTestCli.Put(ctx, key, val) 190 c.Assert(err, IsNil) 191 } 192 c.Assert(upgradeToVer3(ctx, bigTxnTestCli), IsNil) 193 }