github.com/matrixorigin/matrixone@v1.2.0/pkg/hakeeper/task/cn_selector_test.go (about)

     1  // Copyright 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 task
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/hakeeper"
    22  	pb "github.com/matrixorigin/matrixone/pkg/pb/logservice"
    23  	"github.com/matrixorigin/matrixone/pkg/pb/metadata"
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  var expiredTick = uint64(hakeeper.DefaultCNStoreTimeout / time.Second * hakeeper.DefaultTickPerSecond)
    28  
    29  func getUUIDs(cnState *cnPool) map[string]struct{} {
    30  	uuids := make(map[string]struct{}, len(cnState.freq))
    31  	for uuid := range cnState.freq {
    32  		uuids[uuid] = struct{}{}
    33  	}
    34  	return uuids
    35  }
    36  
    37  func TestSelectWorkingCNs(t *testing.T) {
    38  	cases := []struct {
    39  		infos       pb.CNState
    40  		currentTick uint64
    41  		expectedCN  map[string]struct{}
    42  	}{
    43  		{
    44  			infos:       pb.CNState{},
    45  			currentTick: 0,
    46  			expectedCN:  map[string]struct{}{},
    47  		},
    48  		{
    49  			infos:       pb.CNState{Stores: map[string]pb.CNStoreInfo{"a": {Tick: 0}}},
    50  			currentTick: 0,
    51  			expectedCN:  map[string]struct{}{"a": {}},
    52  		},
    53  		{
    54  			infos: pb.CNState{Stores: map[string]pb.CNStoreInfo{
    55  				"a": {Tick: 0},
    56  				"b": {Tick: expiredTick}}},
    57  			currentTick: expiredTick + 1,
    58  			expectedCN:  map[string]struct{}{"b": {}},
    59  		},
    60  	}
    61  
    62  	for _, c := range cases {
    63  		cfg := hakeeper.Config{}
    64  		cfg.Fill()
    65  		pool := newCNPoolWithCNState(c.infos)
    66  		working := pool.selectCNs(notExpired(cfg, c.currentTick))
    67  		assert.Equal(t, c.expectedCN, getUUIDs(working))
    68  	}
    69  }
    70  
    71  func TestContainsLabel(t *testing.T) {
    72  	cases := []struct {
    73  		infos      pb.CNState
    74  		key, value string
    75  		expectedCN map[string]struct{}
    76  	}{
    77  		{
    78  			infos: pb.CNState{Stores: map[string]pb.CNStoreInfo{"a": {}}},
    79  			key:   "k1", value: "v1",
    80  			expectedCN: map[string]struct{}{},
    81  		},
    82  		{
    83  			infos: pb.CNState{Stores: map[string]pb.CNStoreInfo{
    84  				"a": {Labels: map[string]metadata.LabelList{"k1": {Labels: []string{"v1"}}}},
    85  			}},
    86  			key: "k1", value: "v1",
    87  			expectedCN: map[string]struct{}{"a": {}},
    88  		},
    89  		{
    90  			infos: pb.CNState{
    91  				Stores: map[string]pb.CNStoreInfo{
    92  					"a": {
    93  						Labels: map[string]metadata.LabelList{"k1": {Labels: []string{"v1", "v2"}}},
    94  					},
    95  					"b": {
    96  						Labels: map[string]metadata.LabelList{"k1": {Labels: []string{"v1"}}},
    97  					},
    98  				},
    99  			},
   100  			key: "k1", value: "v1",
   101  			expectedCN: map[string]struct{}{"a": {}, "b": {}},
   102  		},
   103  		{
   104  			infos: pb.CNState{
   105  				Stores: map[string]pb.CNStoreInfo{
   106  					"a": {
   107  						Labels: map[string]metadata.LabelList{"k1": {Labels: []string{"v1", "v2"}}},
   108  					},
   109  					"b": {
   110  						Labels: map[string]metadata.LabelList{"k1": {Labels: []string{"v1"}}},
   111  					},
   112  				},
   113  			},
   114  			key: "k1", value: "v2",
   115  			expectedCN: map[string]struct{}{"a": {}},
   116  		},
   117  		{
   118  			infos: pb.CNState{
   119  				Stores: map[string]pb.CNStoreInfo{
   120  					"a": {
   121  						Labels: map[string]metadata.LabelList{
   122  							"k1": {Labels: []string{"v1"}},
   123  						},
   124  					},
   125  				},
   126  			},
   127  			key: "k2", value: "v1",
   128  			expectedCN: map[string]struct{}{},
   129  		},
   130  	}
   131  
   132  	for _, c := range cases {
   133  		cfg := hakeeper.Config{}
   134  		cfg.Fill()
   135  		pool := newCNPoolWithCNState(c.infos)
   136  		working := pool.selectCNs(containsLabel(c.key, c.value))
   137  		assert.Equal(t, c.expectedCN, getUUIDs(working))
   138  	}
   139  }
   140  
   141  func TestWithResource(t *testing.T) {
   142  	cases := []struct {
   143  		infos      pb.CNState
   144  		cpu, mem   uint64
   145  		expectedCN map[string]struct{}
   146  	}{
   147  		{
   148  			infos:      pb.CNState{Stores: map[string]pb.CNStoreInfo{"a": {}}},
   149  			cpu:        1,
   150  			expectedCN: map[string]struct{}{},
   151  		},
   152  		{
   153  			infos: pb.CNState{Stores: map[string]pb.CNStoreInfo{
   154  				"a": {Resource: pb.Resource{
   155  					CPUTotal: 1,
   156  					MemTotal: 100,
   157  				}},
   158  			}},
   159  			cpu: 1, mem: 100,
   160  			expectedCN: map[string]struct{}{"a": {}},
   161  		},
   162  		{
   163  			infos: pb.CNState{
   164  				Stores: map[string]pb.CNStoreInfo{
   165  					"a": {Resource: pb.Resource{
   166  						CPUTotal: 1,
   167  						MemTotal: 100,
   168  					}},
   169  					"b": {
   170  						Resource: pb.Resource{
   171  							CPUTotal: 2,
   172  							MemTotal: 200,
   173  						},
   174  					},
   175  				},
   176  			},
   177  			cpu: 2, mem: 150,
   178  			expectedCN: map[string]struct{}{"b": {}},
   179  		},
   180  	}
   181  
   182  	for _, c := range cases {
   183  		cfg := hakeeper.Config{}
   184  		cfg.Fill()
   185  		pool := newCNPoolWithCNState(c.infos)
   186  		working := pool.selectCNs(withCPU(c.cpu), withMemory(c.mem))
   187  		assert.Equal(t, c.expectedCN, getUUIDs(working))
   188  	}
   189  }
   190  
   191  func TestContains(t *testing.T) {
   192  	assert.True(t, contains([]string{"a"}, "a"))
   193  	assert.False(t, contains([]string{"a"}, "b"))
   194  }