github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/infosync/info_test.go (about) 1 // Copyright 2020 WHTCORPS INC, 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 infosync 15 16 import ( 17 "context" 18 "encoding/json" 19 "errors" 20 "fmt" 21 "os" 22 "path" 23 "reflect" 24 "runtime" 25 "testing" 26 "time" 27 28 . "github.com/whtcorpsinc/check" 29 "github.com/whtcorpsinc/failpoint" 30 "github.com/whtcorpsinc/milevadb/dbs/soliton" 31 "github.com/whtcorpsinc/milevadb/tenant" 32 "go.etcd.io/etcd/integration" 33 ) 34 35 func (is *InfoSyncer) getTopologyFromEtcd(ctx context.Context) (*topologyInfo, error) { 36 key := fmt.Sprintf("%s/%s:%v/info", TopologyInformationPath, is.info.IP, is.info.Port) 37 resp, err := is.etcdCli.Get(ctx, key) 38 if err != nil { 39 return nil, err 40 } 41 if len(resp.Ekvs) == 0 { 42 return nil, errors.New("not-exists") 43 } 44 if len(resp.Ekvs) != 1 { 45 return nil, errors.New("resp.Ekvs error") 46 } 47 var ret topologyInfo 48 err = json.Unmarshal(resp.Ekvs[0].Value, &ret) 49 if err != nil { 50 return nil, err 51 } 52 return &ret, nil 53 } 54 55 func (is *InfoSyncer) ttlKeyExists(ctx context.Context) (bool, error) { 56 key := fmt.Sprintf("%s/%s:%v/ttl", TopologyInformationPath, is.info.IP, is.info.Port) 57 resp, err := is.etcdCli.Get(ctx, key) 58 if err != nil { 59 return false, err 60 } 61 if len(resp.Ekvs) >= 2 { 62 return false, errors.New("too many arguments in resp.Ekvs") 63 } 64 return len(resp.Ekvs) == 1, nil 65 } 66 67 func TestT(t *testing.T) { 68 CustomVerboseFlag = true 69 TestingT(t) 70 } 71 72 var _ = Suite(&testSuite{}) 73 74 type testSuite struct { 75 } 76 77 func TestTopology(t *testing.T) { 78 if runtime.GOOS == "windows" { 79 t.Skip("integration.NewClusterV3 will create file contains a defCauson which is not allowed on Windows") 80 } 81 ctx, cancel := context.WithCancel(context.Background()) 82 defer cancel() 83 currentID := "test" 84 85 clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) 86 defer clus.Terminate(t) 87 88 cli := clus.RandClient() 89 90 failpoint.Enable("github.com/whtcorpsinc/milevadb/petri/infosync/mockServerInfo", "return(true)") 91 defer failpoint.Disable("github.com/whtcorpsinc/milevadb/petri/infosync/mockServerInfo") 92 93 info, err := GlobalInfoSyncerInit(ctx, currentID, cli, false) 94 if err != nil { 95 t.Fatal(err) 96 } 97 98 err = info.newTopologyStochastikAndStoreServerInfo(ctx, tenant.NewStochastikDefaultRetryCnt) 99 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 topo, err := info.getTopologyFromEtcd(ctx) 105 if err != nil { 106 t.Fatal(err) 107 } 108 109 if topo.StartTimestamp != 1282967700000 { 110 t.Fatal("start_timestamp of topology info does not match") 111 } 112 if v, ok := topo.Labels["foo"]; !ok || v != "bar" { 113 t.Fatal("labels of topology info does not match") 114 } 115 116 if !reflect.DeepEqual(*topo, info.getTopologyInfo()) { 117 t.Fatal("the info in etcd is not match with info.") 118 } 119 120 nonTTLKey := fmt.Sprintf("%s/%s:%v/info", TopologyInformationPath, info.info.IP, info.info.Port) 121 ttlKey := fmt.Sprintf("%s/%s:%v/ttl", TopologyInformationPath, info.info.IP, info.info.Port) 122 123 err = soliton.DeleteKeyFromEtcd(nonTTLKey, cli, tenant.NewStochastikDefaultRetryCnt, time.Second) 124 if err != nil { 125 t.Fatal(err) 126 } 127 128 // Refresh and re-test if the key exists 129 err = info.RestartTopology(ctx) 130 if err != nil { 131 t.Fatal(err) 132 } 133 134 topo, err = info.getTopologyFromEtcd(ctx) 135 if err != nil { 136 t.Fatal(err) 137 } 138 139 s, err := os.InterDircublock() 140 if err != nil { 141 t.Fatal(err) 142 } 143 144 dir := path.Dir(s) 145 146 if topo.DeployPath != dir { 147 t.Fatal("DeployPath not match expected path") 148 } 149 150 if topo.StartTimestamp != 1282967700000 { 151 t.Fatal("start_timestamp of topology info does not match") 152 } 153 154 if !reflect.DeepEqual(*topo, info.getTopologyInfo()) { 155 t.Fatal("the info in etcd is not match with info.") 156 } 157 158 // check ttl key 159 ttlExists, err := info.ttlKeyExists(ctx) 160 if err != nil { 161 t.Fatal(err) 162 } 163 if !ttlExists { 164 t.Fatal("ttl non-exists") 165 } 166 167 err = soliton.DeleteKeyFromEtcd(ttlKey, cli, tenant.NewStochastikDefaultRetryCnt, time.Second) 168 if err != nil { 169 t.Fatal(err) 170 } 171 err = info.uFIDelateTopologyAliveness(ctx) 172 if err != nil { 173 t.Fatal(err) 174 } 175 176 ttlExists, err = info.ttlKeyExists(ctx) 177 if err != nil { 178 t.Fatal(err) 179 } 180 if !ttlExists { 181 t.Fatal("ttl non-exists") 182 } 183 }