github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/ha/source_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 ha 15 16 import ( 17 "bytes" 18 "context" 19 "fmt" 20 "os" 21 "path" 22 "testing" 23 24 . "github.com/pingcap/check" 25 "github.com/pingcap/tiflow/dm/config" 26 clientv3 "go.etcd.io/etcd/client/v3" 27 "go.etcd.io/etcd/tests/v3/integration" 28 ) 29 30 const ( 31 sourceSampleFile = "source.yaml" 32 sourceFileContent = `--- 33 server-id: 101 34 source-id: mysql-replica-01 35 relay-dir: ./relay_log 36 enable-gtid: true 37 relay-binlog-gtid: "e68f6068-53ec-11eb-9c5f-0242ac110003:1-50" 38 from: 39 host: 127.0.0.1 40 user: root 41 password: Up8156jArvIPymkVC+5LxkAT6rek 42 port: 3306 43 max-allowed-packet: 0 44 security: 45 ssl-ca: "%s" 46 ssl-cert: "%s" 47 ssl-key: "%s" 48 ` 49 caFile = "ca.pem" 50 caFileContent = ` 51 -----BEGIN CERTIFICATE----- 52 test no content 53 -----END CERTIFICATE----- 54 ` 55 certFile = "cert.pem" 56 certFileContent = ` 57 -----BEGIN CERTIFICATE----- 58 test no content 59 -----END CERTIFICATE----- 60 ` 61 keyFile = "key.pem" 62 keyFileContent = ` 63 -----BEGIN RSA PRIVATE KEY----- 64 test no content 65 -----END RSA PRIVATE KEY----- 66 ` 67 ) 68 69 var ( 70 sourceSampleFilePath string 71 caFilePath string 72 certFilePath string 73 keyFilePath string 74 75 etcdTestCli *clientv3.Client 76 ) 77 78 func TestHA(t *testing.T) { 79 integration.BeforeTestExternal(t) 80 mockCluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) 81 defer mockCluster.Terminate(t) 82 83 etcdTestCli = mockCluster.RandClient() 84 85 TestingT(t) 86 } 87 88 // clear keys in etcd test cluster. 89 func clearTestInfoOperation(c *C) { 90 c.Assert(ClearTestInfoOperation(etcdTestCli), IsNil) 91 } 92 93 type testForEtcd struct{} 94 95 var _ = Suite(&testForEtcd{}) 96 97 func (t *testForEtcd) SetUpTest(c *C) { 98 createTestFixture(c) 99 } 100 101 func createTestFixture(c *C) { 102 dir := c.MkDir() 103 104 caFilePath = path.Join(dir, caFile) 105 err := os.WriteFile(caFilePath, []byte(caFileContent), 0o644) 106 c.Assert(err, IsNil) 107 108 certFilePath = path.Join(dir, certFile) 109 err = os.WriteFile(certFilePath, []byte(certFileContent), 0o644) 110 c.Assert(err, IsNil) 111 112 keyFilePath = path.Join(dir, keyFile) 113 err = os.WriteFile(keyFilePath, []byte(keyFileContent), 0o644) 114 c.Assert(err, IsNil) 115 116 sourceSampleFilePath = path.Join(dir, sourceSampleFile) 117 sourceFileContent := fmt.Sprintf(sourceFileContent, caFilePath, certFilePath, keyFilePath) 118 err = os.WriteFile(sourceSampleFilePath, []byte(sourceFileContent), 0o644) 119 c.Assert(err, IsNil) 120 } 121 122 func (t *testForEtcd) TestSourceEtcd(c *C) { 123 defer clearTestInfoOperation(c) 124 125 cfg, err := config.LoadFromFile(sourceSampleFilePath) 126 c.Assert(err, IsNil) 127 source := cfg.SourceID 128 cfgExtra := *cfg 129 cfgExtra.SourceID = "mysql-replica-2" 130 131 // no source config exist. 132 scm1, rev1, err := GetSourceCfg(etcdTestCli, source, 0) 133 c.Assert(err, IsNil) 134 c.Assert(rev1, Greater, int64(0)) 135 c.Assert(scm1, HasLen, 0) 136 cfgM, _, err := GetSourceCfg(etcdTestCli, "", 0) 137 c.Assert(err, IsNil) 138 c.Assert(cfgM, HasLen, 0) 139 140 // put a source config. 141 c.Assert(cfg.From.Security.LoadTLSContent(), IsNil) 142 rev2, err := PutSourceCfg(etcdTestCli, cfg) 143 c.Assert(err, IsNil) 144 c.Assert(rev2, Greater, rev1) 145 146 // get the config back. 147 scm2, rev3, err := GetSourceCfg(etcdTestCli, source, 0) 148 c.Assert(err, IsNil) 149 c.Assert(rev3, Equals, rev2) 150 cfg2 := scm2[source] 151 c.Assert(cfg2, DeepEquals, cfg) 152 noContentBytes := []byte("test no content") 153 c.Assert(bytes.Contains(cfg2.From.Security.SSLCABytes, noContentBytes), Equals, true) 154 c.Assert(bytes.Contains(cfg2.From.Security.SSLKeyBytes, noContentBytes), Equals, true) 155 c.Assert(bytes.Contains(cfg2.From.Security.SSLCertBytes, noContentBytes), Equals, true) 156 // put another source config. 157 rev2, err = PutSourceCfg(etcdTestCli, &cfgExtra) 158 c.Assert(err, IsNil) 159 160 // get all two config. 161 cfgM, rev3, err = GetSourceCfg(etcdTestCli, "", 0) 162 c.Assert(err, IsNil) 163 c.Assert(rev3, Equals, rev2) 164 c.Assert(cfgM, HasLen, 2) 165 c.Assert(cfgM[source], DeepEquals, cfg) 166 c.Assert(cfgM[cfgExtra.SourceID], DeepEquals, &cfgExtra) 167 168 // delete the config. 169 deleteOp := deleteSourceCfgOp(source) 170 deleteResp, err := etcdTestCli.Txn(context.Background()).Then(deleteOp).Commit() 171 c.Assert(err, IsNil) 172 173 // get again, not exists now. 174 scm3, rev4, err := GetSourceCfg(etcdTestCli, source, 0) 175 c.Assert(err, IsNil) 176 c.Assert(rev4, Equals, deleteResp.Header.Revision) 177 c.Assert(scm3, HasLen, 0) 178 }