github.com/matrixorigin/matrixone@v0.7.0/pkg/pb/logservice/logservice_test.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package logservice 16 17 import ( 18 "testing" 19 20 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 21 "github.com/stretchr/testify/assert" 22 ) 23 24 func TestLogRecord(t *testing.T) { 25 r := LogRecord{ 26 Data: make([]byte, 32), 27 } 28 assert.Equal(t, 32-HeaderSize-8, len(r.Payload())) 29 r.ResizePayload(2) 30 assert.Equal(t, HeaderSize+8+2, len(r.Data)) 31 assert.Equal(t, 2, len(r.Payload())) 32 } 33 34 func TestCNStateUpdate(t *testing.T) { 35 state := CNState{Stores: map[string]CNStoreInfo{}} 36 37 hb1 := CNStoreHeartbeat{UUID: "cn-a", ServiceAddress: "addr-a", Role: metadata.CNRole_AP} 38 tick1 := uint64(100) 39 40 state.Update(hb1, tick1) 41 assert.Equal(t, state.Stores[hb1.UUID], CNStoreInfo{ 42 Tick: tick1, 43 ServiceAddress: hb1.ServiceAddress, 44 Role: metadata.CNRole_AP, 45 }) 46 47 hb2 := CNStoreHeartbeat{UUID: "cn-b", ServiceAddress: "addr-b", Role: metadata.CNRole_TP} 48 tick2 := uint64(200) 49 50 state.Update(hb2, tick2) 51 assert.Equal(t, state.Stores[hb2.UUID], CNStoreInfo{ 52 Tick: tick2, 53 ServiceAddress: hb2.ServiceAddress, 54 Role: metadata.CNRole_TP, 55 }) 56 57 hb3 := CNStoreHeartbeat{UUID: "cn-a", ServiceAddress: "addr-a", Role: metadata.CNRole_TP} 58 tick3 := uint64(300) 59 60 state.Update(hb3, tick3) 61 assert.Equal(t, state.Stores[hb3.UUID], CNStoreInfo{ 62 Tick: tick3, 63 ServiceAddress: hb3.ServiceAddress, 64 Role: metadata.CNRole_TP, 65 }) 66 } 67 68 func TestDNStateUpdate(t *testing.T) { 69 state := DNState{Stores: map[string]DNStoreInfo{}} 70 71 hb1 := DNStoreHeartbeat{ 72 UUID: "dn-a", 73 ServiceAddress: "addr-a", 74 Shards: []DNShardInfo{{ 75 ShardID: 1, 76 ReplicaID: 1, 77 }}, 78 LogtailServerAddress: "addr-0", 79 } 80 tick1 := uint64(100) 81 82 state.Update(hb1, tick1) 83 assert.Equal(t, state.Stores["dn-a"], DNStoreInfo{ 84 Tick: tick1, 85 ServiceAddress: hb1.ServiceAddress, 86 Shards: hb1.Shards, 87 LogtailServerAddress: hb1.LogtailServerAddress, 88 }) 89 90 hb2 := DNStoreHeartbeat{ 91 UUID: "dn-a", 92 ServiceAddress: "addr-a", 93 Shards: []DNShardInfo{ 94 {ShardID: 1, ReplicaID: 1}, 95 {ShardID: 2, ReplicaID: 1}}, 96 LogtailServerAddress: "addr-0", 97 } 98 tick2 := uint64(200) 99 100 state.Update(hb2, tick2) 101 assert.Equal(t, state.Stores[hb2.UUID], DNStoreInfo{ 102 Tick: tick2, 103 ServiceAddress: hb2.ServiceAddress, 104 Shards: hb2.Shards, 105 LogtailServerAddress: "addr-0", 106 }) 107 } 108 109 func TestLogStateUpdateStores(t *testing.T) { 110 defer func() { 111 if r := recover(); r == nil { 112 t.Errorf("The code did not panic") 113 } 114 }() 115 116 state := LogState{ 117 Shards: map[uint64]LogShardInfo{}, 118 Stores: map[string]LogStoreInfo{}, 119 } 120 121 hb1 := LogStoreHeartbeat{ 122 UUID: "log-a", 123 RaftAddress: "raft-a", 124 ServiceAddress: "addr-a", 125 GossipAddress: "gossip-a", 126 Replicas: []LogReplicaInfo{{ 127 LogShardInfo: LogShardInfo{ 128 ShardID: 1, 129 Replicas: map[uint64]string{1: "log-a"}, 130 Epoch: 1, 131 LeaderID: 1, 132 Term: 1, 133 }, 134 ReplicaID: 1, 135 }}, 136 } 137 tick1 := uint64(100) 138 state.Update(hb1, tick1) 139 assert.Equal(t, state.Stores[hb1.UUID], LogStoreInfo{ 140 Tick: tick1, 141 RaftAddress: hb1.RaftAddress, 142 ServiceAddress: hb1.ServiceAddress, 143 GossipAddress: hb1.GossipAddress, 144 Replicas: hb1.Replicas, 145 }) 146 147 hb2 := LogStoreHeartbeat{ 148 UUID: "log-a", 149 RaftAddress: "raft-a", 150 ServiceAddress: "addr-a", 151 GossipAddress: "gossip-a", 152 Replicas: []LogReplicaInfo{{ 153 LogShardInfo: LogShardInfo{ 154 ShardID: 1, 155 Replicas: map[uint64]string{1: "log-a", 2: "log-b"}, 156 Epoch: 2, 157 LeaderID: 1, 158 Term: 2, 159 }, 160 ReplicaID: 1, 161 }}, 162 } 163 tick2 := uint64(200) 164 state.Update(hb2, tick2) 165 assert.Equal(t, state.Stores[hb2.UUID], LogStoreInfo{ 166 Tick: tick2, 167 RaftAddress: hb2.RaftAddress, 168 ServiceAddress: hb2.ServiceAddress, 169 GossipAddress: hb2.GossipAddress, 170 Replicas: hb2.Replicas, 171 }) 172 173 hb3 := LogStoreHeartbeat{ 174 UUID: "log-a", 175 RaftAddress: "raft-a", 176 ServiceAddress: "addr-a", 177 GossipAddress: "gossip-a", 178 Replicas: []LogReplicaInfo{{ 179 LogShardInfo: LogShardInfo{ 180 ShardID: 1, 181 Replicas: map[uint64]string{1: "log-a"}, 182 Epoch: 2, 183 LeaderID: 1, 184 Term: 2, 185 }, 186 ReplicaID: 1, 187 }}, 188 } 189 tick3 := uint64(200) 190 191 // should panic() 192 state.Update(hb3, tick3) 193 } 194 195 func TestLogString(t *testing.T) { 196 cases := []struct { 197 desc string 198 199 command ScheduleCommand 200 expected string 201 }{ 202 { 203 desc: "add log replica", 204 command: ScheduleCommand{ 205 UUID: "storeA", 206 Bootstrapping: false, 207 ConfigChange: &ConfigChange{ 208 Replica: Replica{ 209 UUID: "storeB", 210 ShardID: 1, 211 ReplicaID: 4, 212 Epoch: 1, 213 LogShardID: 0, 214 }, 215 ChangeType: AddReplica, 216 InitialMembers: nil, 217 }, 218 ServiceType: LogService, 219 ShutdownStore: nil, 220 }, 221 expected: "L/Add storeA storeB:1:4:1", 222 }, 223 { 224 desc: "remove log replica", 225 command: ScheduleCommand{ 226 UUID: "storeA", 227 Bootstrapping: false, 228 ConfigChange: &ConfigChange{ 229 Replica: Replica{ 230 UUID: "storeB", 231 ShardID: 1, 232 ReplicaID: 4, 233 Epoch: 1, 234 LogShardID: 0, 235 }, 236 ChangeType: RemoveReplica, 237 InitialMembers: nil, 238 }, 239 ServiceType: LogService, 240 ShutdownStore: nil, 241 }, 242 expected: "L/Remove storeA storeB:1:4:1", 243 }, 244 { 245 desc: "remove log replica", 246 command: ScheduleCommand{ 247 UUID: "storeA", 248 Bootstrapping: false, 249 ConfigChange: &ConfigChange{ 250 Replica: Replica{ 251 UUID: "storeA", 252 ShardID: 1, 253 ReplicaID: 4, 254 Epoch: 1, 255 LogShardID: 0, 256 }, 257 ChangeType: StartReplica, 258 InitialMembers: nil, 259 }, 260 ServiceType: LogService, 261 ShutdownStore: nil, 262 }, 263 expected: "L/Start storeA storeA:1:4:1", 264 }, 265 { 266 desc: "remove log replica", 267 command: ScheduleCommand{ 268 UUID: "storeA", 269 Bootstrapping: false, 270 ConfigChange: &ConfigChange{ 271 Replica: Replica{ 272 UUID: "storeA", 273 ShardID: 1, 274 ReplicaID: 4, 275 Epoch: 1, 276 LogShardID: 0, 277 }, 278 ChangeType: StartReplica, 279 InitialMembers: nil, 280 }, 281 ServiceType: DNService, 282 ShutdownStore: nil, 283 }, 284 expected: "D/Start storeA storeA:1:4:1", 285 }, 286 { 287 desc: "remove log replica", 288 command: ScheduleCommand{ 289 UUID: "storeA", 290 Bootstrapping: false, 291 ServiceType: LogService, 292 ShutdownStore: &ShutdownStore{ 293 StoreID: "storeA", 294 }, 295 }, 296 expected: "L/shutdown storeA", 297 }, 298 { 299 desc: "kill zombie", 300 command: ScheduleCommand{ 301 UUID: "storeA", 302 Bootstrapping: false, 303 ConfigChange: &ConfigChange{ 304 Replica: Replica{ 305 UUID: "storeA", 306 ShardID: 1, 307 }, 308 ChangeType: KillZombie, 309 }, 310 ServiceType: LogService, 311 }, 312 expected: "L/Kill storeA storeA:1:0:0", 313 }, 314 { 315 desc: "bootstrapping", 316 command: ScheduleCommand{ 317 UUID: "storeA", 318 Bootstrapping: true, 319 ConfigChange: &ConfigChange{ 320 Replica: Replica{ 321 UUID: "storeA", 322 ShardID: 1, 323 ReplicaID: 1, 324 }, 325 ChangeType: StartReplica, 326 InitialMembers: map[uint64]string{1: "storeA123", 2: "storeB", 3: "storeC"}, 327 }, 328 ServiceType: LogService, 329 }, 330 expected: "L/Start storeA storeA:1:1:0 [1:storeA 2:storeB 3:storeC]", 331 }, 332 } 333 334 for _, c := range cases { 335 output := c.command.LogString() 336 assert.Equal(t, c.expected, output) 337 } 338 }