github.com/matrixorigin/matrixone@v0.7.0/pkg/hakeeper/checkers/logservice/check_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  	"fmt"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/common/runtime"
    23  	"github.com/matrixorigin/matrixone/pkg/hakeeper"
    24  	"github.com/matrixorigin/matrixone/pkg/hakeeper/checkers/util"
    25  	"github.com/matrixorigin/matrixone/pkg/hakeeper/operator"
    26  	"github.com/matrixorigin/matrixone/pkg/logutil"
    27  	pb "github.com/matrixorigin/matrixone/pkg/pb/logservice"
    28  	"github.com/matrixorigin/matrixone/pkg/pb/metadata"
    29  	"github.com/stretchr/testify/assert"
    30  )
    31  
    32  func TestMain(m *testing.M) {
    33  	logutil.SetupMOLogger(&logutil.LogConfig{
    34  		Level:  "debug",
    35  		Format: "console",
    36  	})
    37  
    38  	runtime.SetupProcessLevelRuntime(runtime.NewRuntime(metadata.ServiceType_LOG, "test", logutil.GetGlobalLogger()))
    39  	m.Run()
    40  }
    41  
    42  var expiredTick = uint64(hakeeper.DefaultLogStoreTimeout / time.Second * hakeeper.DefaultTickPerSecond)
    43  
    44  func TestCheck(t *testing.T) {
    45  	cases := []struct {
    46  		desc        string
    47  		cluster     pb.ClusterInfo
    48  		infos       pb.LogState
    49  		removing    map[uint64][]uint64
    50  		adding      map[uint64][]uint64
    51  		currentTick uint64
    52  		expected    []*operator.Operator
    53  	}{
    54  		{
    55  			desc: "normal case",
    56  			cluster: pb.ClusterInfo{
    57  				LogShards: []metadata.LogShardRecord{{
    58  					ShardID:          1,
    59  					NumberOfReplicas: 3,
    60  				}},
    61  			},
    62  			infos: pb.LogState{
    63  				Shards: map[uint64]pb.LogShardInfo{1: {
    64  					ShardID:  1,
    65  					Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
    66  					Epoch:    1,
    67  					LeaderID: 1,
    68  					Term:     1,
    69  				}},
    70  				Stores: map[string]pb.LogStoreInfo{"a": {
    71  					Tick: 0,
    72  					Replicas: []pb.LogReplicaInfo{{
    73  						LogShardInfo: pb.LogShardInfo{
    74  							ShardID:  1,
    75  							Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
    76  							Epoch:    1,
    77  							LeaderID: 1,
    78  							Term:     1,
    79  						}, ReplicaID: 1}}},
    80  					"b": {
    81  						Tick: 0,
    82  						Replicas: []pb.LogReplicaInfo{{
    83  							LogShardInfo: pb.LogShardInfo{
    84  								ShardID:  1,
    85  								Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
    86  								Epoch:    1,
    87  								LeaderID: 1,
    88  								Term:     1,
    89  							}, ReplicaID: 2}}},
    90  					"c": {
    91  						Tick: 0,
    92  						Replicas: []pb.LogReplicaInfo{{
    93  							LogShardInfo: pb.LogShardInfo{
    94  								ShardID:  1,
    95  								Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
    96  								Epoch:    1,
    97  								LeaderID: 1,
    98  								Term:     1,
    99  							}, ReplicaID: 3}}},
   100  				},
   101  			},
   102  			removing:    nil,
   103  			adding:      nil,
   104  			currentTick: 0,
   105  			expected:    nil,
   106  		},
   107  		{
   108  			desc: "store \"a\" expired",
   109  			cluster: pb.ClusterInfo{
   110  				LogShards: []metadata.LogShardRecord{{
   111  					ShardID:          1,
   112  					NumberOfReplicas: 3,
   113  				}},
   114  			},
   115  			infos: pb.LogState{
   116  				Shards: map[uint64]pb.LogShardInfo{1: {
   117  					ShardID:  1,
   118  					Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   119  					Epoch:    1,
   120  					LeaderID: 1,
   121  					Term:     1,
   122  				}},
   123  				Stores: map[string]pb.LogStoreInfo{
   124  					"a": {
   125  						Tick: 0,
   126  						Replicas: []pb.LogReplicaInfo{{
   127  							LogShardInfo: pb.LogShardInfo{
   128  								ShardID:  1,
   129  								Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   130  								Epoch:    1,
   131  								LeaderID: 1,
   132  								Term:     1,
   133  							}, ReplicaID: 1}}},
   134  					"b": {
   135  						Tick: expiredTick + 1,
   136  						Replicas: []pb.LogReplicaInfo{{
   137  							LogShardInfo: pb.LogShardInfo{
   138  								ShardID:  1,
   139  								Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   140  								Epoch:    1,
   141  								LeaderID: 1,
   142  								Term:     1,
   143  							}, ReplicaID: 2}}},
   144  					"c": {
   145  						Tick: expiredTick + 1,
   146  						Replicas: []pb.LogReplicaInfo{{
   147  							LogShardInfo: pb.LogShardInfo{
   148  								ShardID:  1,
   149  								Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   150  								Epoch:    1,
   151  								LeaderID: 1,
   152  								Term:     1,
   153  							}, ReplicaID: 3}}},
   154  					"d": {
   155  						Tick: expiredTick + 1,
   156  					},
   157  				},
   158  			},
   159  			removing:    nil,
   160  			adding:      nil,
   161  			currentTick: expiredTick + 1,
   162  			expected: []*operator.Operator{
   163  				operator.NewOperator("", 1, 1,
   164  					operator.RemoveLogService{
   165  						Target: "b",
   166  						Replica: operator.Replica{
   167  							UUID:      "a",
   168  							ShardID:   1,
   169  							ReplicaID: 1,
   170  							Epoch:     1},
   171  					}),
   172  			},
   173  		},
   174  		{
   175  			desc: "shard 1 has only 2 replicas, which expected as 3",
   176  			cluster: pb.ClusterInfo{
   177  				LogShards: []metadata.LogShardRecord{{
   178  					ShardID:          1,
   179  					NumberOfReplicas: 3,
   180  				}},
   181  			},
   182  			infos: pb.LogState{
   183  				Shards: map[uint64]pb.LogShardInfo{1: {
   184  					ShardID:  1,
   185  					Replicas: map[uint64]string{1: "a", 2: "b"},
   186  					Epoch:    1,
   187  					LeaderID: 1,
   188  					Term:     1,
   189  				}},
   190  				Stores: map[string]pb.LogStoreInfo{"a": {
   191  					Tick: 0,
   192  					Replicas: []pb.LogReplicaInfo{{
   193  						LogShardInfo: pb.LogShardInfo{
   194  							ShardID:  1,
   195  							Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   196  							Epoch:    1,
   197  							LeaderID: 1,
   198  							Term:     1,
   199  						}, ReplicaID: 1}}},
   200  					"b": {
   201  						Tick: 0,
   202  						Replicas: []pb.LogReplicaInfo{{
   203  							LogShardInfo: pb.LogShardInfo{
   204  								ShardID:  1,
   205  								Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   206  								Epoch:    1,
   207  								LeaderID: 1,
   208  								Term:     1,
   209  							}, ReplicaID: 2}}},
   210  					"c": {Tick: 0, Replicas: []pb.LogReplicaInfo{}},
   211  				},
   212  			},
   213  			removing:    nil,
   214  			adding:      nil,
   215  			currentTick: 0,
   216  			expected: []*operator.Operator{operator.NewOperator("adding 1:4(at epoch 1) to c", 1,
   217  				1, operator.AddLogService{
   218  					Target: "a",
   219  					Replica: operator.Replica{
   220  						UUID:      "c",
   221  						ShardID:   1,
   222  						ReplicaID: 4,
   223  						Epoch:     1,
   224  					},
   225  				})},
   226  		},
   227  		{
   228  			desc: "replica 3 on store c is not started",
   229  			cluster: pb.ClusterInfo{
   230  				LogShards: []metadata.LogShardRecord{{
   231  					ShardID:          1,
   232  					NumberOfReplicas: 3,
   233  				}},
   234  			},
   235  			infos: pb.LogState{
   236  				Shards: map[uint64]pb.LogShardInfo{1: {
   237  					ShardID:  1,
   238  					Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   239  					Epoch:    1,
   240  					LeaderID: 1,
   241  					Term:     1,
   242  				}},
   243  				Stores: map[string]pb.LogStoreInfo{"a": {
   244  					Tick: 0,
   245  					Replicas: []pb.LogReplicaInfo{{
   246  						LogShardInfo: pb.LogShardInfo{
   247  							ShardID:  1,
   248  							Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   249  							Epoch:    1,
   250  							LeaderID: 1,
   251  							Term:     1,
   252  						}, ReplicaID: 1}}},
   253  					"b": {
   254  						Tick: 0,
   255  						Replicas: []pb.LogReplicaInfo{{
   256  							LogShardInfo: pb.LogShardInfo{
   257  								ShardID:  1,
   258  								Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   259  								Epoch:    1,
   260  								LeaderID: 1,
   261  								Term:     1,
   262  							}, ReplicaID: 2}}},
   263  					"c": {
   264  						Tick:     0,
   265  						Replicas: []pb.LogReplicaInfo{}},
   266  				},
   267  			},
   268  			removing:    nil,
   269  			adding:      nil,
   270  			currentTick: 0,
   271  			expected: []*operator.Operator{operator.NewOperator("", 1,
   272  				1, operator.StartLogService{
   273  					Replica: operator.Replica{
   274  						UUID:      "c",
   275  						ShardID:   1,
   276  						ReplicaID: 3},
   277  				})},
   278  		},
   279  		{
   280  			desc: "store \"a\" expired and is processing",
   281  			cluster: pb.ClusterInfo{
   282  				LogShards: []metadata.LogShardRecord{{
   283  					ShardID:          1,
   284  					NumberOfReplicas: 3,
   285  				}},
   286  			},
   287  			infos: pb.LogState{
   288  				Shards: map[uint64]pb.LogShardInfo{1: {
   289  					ShardID:  1,
   290  					Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   291  					Epoch:    1,
   292  					LeaderID: 1,
   293  					Term:     1,
   294  				}},
   295  				Stores: map[string]pb.LogStoreInfo{"a": {
   296  					Tick: 0,
   297  					Replicas: []pb.LogReplicaInfo{{
   298  						LogShardInfo: pb.LogShardInfo{
   299  							ShardID:  1,
   300  							Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   301  							Epoch:    1,
   302  							LeaderID: 1,
   303  							Term:     1,
   304  						}, ReplicaID: 1}}},
   305  					"b": {
   306  						Tick: expiredTick + 1,
   307  						Replicas: []pb.LogReplicaInfo{{
   308  							LogShardInfo: pb.LogShardInfo{
   309  								ShardID:  1,
   310  								Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   311  								Epoch:    1,
   312  								LeaderID: 1,
   313  								Term:     1,
   314  							}, ReplicaID: 2}}},
   315  					"c": {
   316  						Tick: expiredTick + 1,
   317  						Replicas: []pb.LogReplicaInfo{{
   318  							LogShardInfo: pb.LogShardInfo{
   319  								ShardID:  1,
   320  								Replicas: map[uint64]string{1: "a", 2: "b", 3: "c"},
   321  								Epoch:    1,
   322  								LeaderID: 1,
   323  								Term:     1,
   324  							}, ReplicaID: 3}}},
   325  				},
   326  			},
   327  			removing:    map[uint64][]uint64{1: {1}},
   328  			adding:      nil,
   329  			currentTick: expiredTick + 1,
   330  			expected:    []*operator.Operator{},
   331  		},
   332  	}
   333  
   334  	for i, c := range cases {
   335  		fmt.Printf("case %v: %s\n", i, c.desc)
   336  		alloc := util.NewTestIDAllocator(3)
   337  		cfg := hakeeper.Config{}
   338  		cfg.Fill()
   339  		executing := operator.ExecutingReplicas{
   340  			Adding:   c.adding,
   341  			Removing: c.removing,
   342  		}
   343  		operators := Check(alloc, cfg, c.cluster, c.infos, executing, pb.TaskTableUser{}, c.currentTick)
   344  
   345  		assert.Equal(t, len(c.expected), len(operators))
   346  		for j, op := range operators {
   347  			assert.Equal(t, len(c.expected[j].OpSteps()), len(op.OpSteps()))
   348  			for k, step := range op.OpSteps() {
   349  				assert.Equal(t, c.expected[j].OpSteps()[k], step)
   350  			}
   351  		}
   352  	}
   353  }