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  }