github.com/matrixorigin/matrixone@v1.2.0/pkg/tests/service/utility_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 service 16 17 import ( 18 "testing" 19 20 "github.com/stretchr/testify/require" 21 22 "github.com/matrixorigin/matrixone/pkg/hakeeper" 23 pb "github.com/matrixorigin/matrixone/pkg/pb/logservice" 24 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 25 ) 26 27 const ( 28 // default replica number for log shard 29 defaultLogShardSize = 3 30 ) 31 32 func TestParseExpectedTNShardCount(t *testing.T) { 33 cluster := pb.ClusterInfo{ 34 TNShards: mockTNShardRecords(10, 11, 12, 12), 35 } 36 // expected tn shards: 10, 11, 12 37 require.Equal(t, 3, ParseExpectedTNShardCount(cluster)) 38 } 39 40 func TestParseExpectedLogShardCount(t *testing.T) { 41 cluster := pb.ClusterInfo{ 42 LogShards: mockLogShardRecords(10, 11, 11), 43 } 44 // expected log shards: 10, 11 45 require.Equal(t, 2, ParseExpectedLogShardCount(cluster)) 46 } 47 48 func TestParseReportedTNShardCount(t *testing.T) { 49 hkcfg := hakeeper.Config{} 50 hkcfg.Fill() 51 52 expiredTick := uint64(10) 53 currTick := hkcfg.ExpiredTick(expiredTick, hkcfg.TNStoreTimeout) + 1 54 55 tnState := pb.TNState{ 56 Stores: map[string]pb.TNStoreInfo{ 57 "expired1": { 58 Tick: expiredTick, 59 Shards: []pb.TNShardInfo{ 60 mockTnShardInfo(10, 100), 61 }, 62 }, 63 "working1": { 64 Tick: currTick, 65 Shards: []pb.TNShardInfo{ 66 mockTnShardInfo(11, 101), 67 mockTnShardInfo(11, 102), 68 mockTnShardInfo(12, 103), 69 }, 70 }, 71 }, 72 } 73 74 // working tn shards: 11, 12 75 require.Equal(t, 2, ParseReportedTNShardCount(tnState, hkcfg, currTick)) 76 } 77 78 func TestParseReportedLogShardCount(t *testing.T) { 79 hkcfg := hakeeper.Config{} 80 hkcfg.Fill() 81 82 expiredTick := uint64(10) 83 currTick := hkcfg.ExpiredTick(expiredTick, hkcfg.LogStoreTimeout) + 1 84 85 logState := pb.LogState{ 86 Stores: map[string]pb.LogStoreInfo{ 87 "expired1": { 88 Tick: expiredTick, 89 Replicas: []pb.LogReplicaInfo{ 90 mockLogReplicaInfo(11, 100), 91 }, 92 }, 93 "workding1": { 94 Tick: currTick, 95 Replicas: []pb.LogReplicaInfo{ 96 mockLogReplicaInfo(11, 101), 97 }, 98 }, 99 "workding2": { 100 Tick: currTick, 101 Replicas: []pb.LogReplicaInfo{ 102 mockLogReplicaInfo(12, 102), 103 }, 104 }, 105 "workding3": { 106 Tick: currTick, 107 Replicas: []pb.LogReplicaInfo{ 108 mockLogReplicaInfo(12, 103), 109 }, 110 }, 111 }, 112 } 113 114 // reported working log shard: 11, 12 115 require.Equal(t, 2, ParseReportedLogShardCount(logState, hkcfg, currTick)) 116 } 117 118 func TestParseLogShardExpectedSize(t *testing.T) { 119 cluster := pb.ClusterInfo{ 120 LogShards: mockLogShardRecords(10, 11), 121 } 122 123 // log shard 10 recorded in ClusterInfo 124 require.Equal(t, defaultLogShardSize, ParseLogShardExpectedSize(10, cluster)) 125 126 // log shard 100 not recorded in ClusterInfo 127 require.Equal(t, 0, ParseLogShardExpectedSize(100, cluster)) 128 } 129 130 func TestParseLogShardReportedSize(t *testing.T) { 131 hkcfg := hakeeper.Config{} 132 hkcfg.Fill() 133 134 expiredTick := uint64(10) 135 currTick := hkcfg.ExpiredTick(expiredTick, hkcfg.LogStoreTimeout) + 1 136 137 logState := pb.LogState{ 138 Stores: map[string]pb.LogStoreInfo{ 139 "expired1": { 140 Tick: expiredTick, 141 Replicas: []pb.LogReplicaInfo{ 142 mockLogReplicaInfo(11, 100), 143 }, 144 }, 145 "workding1": { 146 Tick: currTick, 147 Replicas: []pb.LogReplicaInfo{ 148 mockLogReplicaInfo(11, 101), 149 }, 150 }, 151 "workding2": { 152 Tick: currTick, 153 Replicas: []pb.LogReplicaInfo{ 154 mockLogReplicaInfo(11, 102), 155 }, 156 }, 157 "workding3": { 158 Tick: currTick, 159 Replicas: []pb.LogReplicaInfo{ 160 mockLogReplicaInfo(11, 103), 161 }, 162 }, 163 }, 164 } 165 166 // 3 working replicas reported for log shard 11 167 require.Equal(t, 3, ParseLogShardReportedSize(11, logState, hkcfg, currTick)) 168 } 169 170 func TestParseTNShardReportedSize(t *testing.T) { 171 hkcfg := hakeeper.Config{} 172 hkcfg.Fill() 173 174 expiredTick := uint64(10) 175 currTick := hkcfg.ExpiredTick(expiredTick, hkcfg.TNStoreTimeout) + 1 176 177 tnState := pb.TNState{ 178 Stores: map[string]pb.TNStoreInfo{ 179 "expired1": { 180 Tick: expiredTick, 181 Shards: []pb.TNShardInfo{ 182 mockTnShardInfo(10, 100), 183 }, 184 }, 185 "working1": { 186 Tick: currTick, 187 Shards: []pb.TNShardInfo{ 188 mockTnShardInfo(11, 101), 189 mockTnShardInfo(11, 102), 190 mockTnShardInfo(12, 103), 191 }, 192 }, 193 }, 194 } 195 196 require.Equal(t, 2, ParseTNShardReportedSize(11, tnState, hkcfg, currTick)) 197 } 198 199 func mockTNShardRecords(ids ...uint64) []metadata.TNShardRecord { 200 records := make([]metadata.TNShardRecord, 0, len(ids)) 201 for _, id := range ids { 202 records = append(records, metadata.TNShardRecord{ 203 ShardID: id, 204 LogShardID: id, 205 }) 206 } 207 return records 208 } 209 210 func mockLogShardRecords(ids ...uint64) []metadata.LogShardRecord { 211 records := make([]metadata.LogShardRecord, 0, len(ids)) 212 for _, id := range ids { 213 records = append(records, metadata.LogShardRecord{ 214 ShardID: id, 215 NumberOfReplicas: uint64(defaultLogShardSize), 216 }) 217 } 218 return records 219 } 220 221 func mockTnShardInfo(shardID, replicaID uint64) pb.TNShardInfo { 222 return pb.TNShardInfo{ 223 ShardID: shardID, 224 ReplicaID: replicaID, 225 } 226 } 227 228 func mockLogReplicaInfo(shardID, replicaID uint64) pb.LogReplicaInfo { 229 return pb.LogReplicaInfo{ 230 ReplicaID: replicaID, 231 LogShardInfo: pb.LogShardInfo{ 232 ShardID: shardID, 233 }, 234 } 235 }