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  }