github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/framework/model/master_test.go (about) 1 // Copyright 2022 PingCAP, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package model 15 16 import ( 17 "fmt" 18 "regexp" 19 "testing" 20 21 ormModel "github.com/pingcap/tiflow/engine/pkg/orm/model" 22 "github.com/pingcap/tiflow/pkg/label" 23 "github.com/stretchr/testify/require" 24 ) 25 26 // This test case aims to check MasterMetaExt implements 27 // Scan() correctly so that it can work with the SQL driver. 28 func TestMasterMetaExtScan(t *testing.T) { 29 t.Parallel() 30 31 expectNoError := func(t *testing.T, err error) { 32 require.NoError(t, err) 33 } 34 35 cases := []struct { 36 input any 37 checkErr func(*testing.T, error) 38 result *MasterMetaExt 39 }{ 40 { 41 input: nil, 42 checkErr: expectNoError, 43 result: &MasterMetaExt{}, 44 }, 45 { 46 input: "", 47 checkErr: expectNoError, 48 result: &MasterMetaExt{}, 49 }, 50 { 51 input: []byte(""), 52 checkErr: expectNoError, 53 result: &MasterMetaExt{}, 54 }, 55 { 56 input: 123, 57 checkErr: func(t *testing.T, err error) { 58 require.Regexp( 59 t, 60 regexp.QuoteMeta("failed to scan MasterMetaExt. Expected string or []byte, got int"), 61 err) 62 }, 63 result: &MasterMetaExt{}, 64 }, 65 { 66 input: `{"selectors":[{"label":"test","target":"test-val","op":"eq"}]}`, 67 checkErr: expectNoError, 68 result: &MasterMetaExt{ 69 Selectors: []*label.Selector{ 70 { 71 Key: "test", 72 Target: "test-val", 73 Op: label.OpEq, 74 }, 75 }, 76 }, 77 }, 78 { 79 input: []byte(`{"selectors":[{"label":"test","target":"test-val","op":"eq"}]}`), 80 checkErr: expectNoError, 81 result: &MasterMetaExt{ 82 Selectors: []*label.Selector{ 83 { 84 Key: "test", 85 Target: "test-val", 86 Op: label.OpEq, 87 }, 88 }, 89 }, 90 }, 91 { 92 input: []byte(`{"selecto`), 93 checkErr: func(t *testing.T, err error) { 94 require.Regexp(t, "failed to unmarshal MasterMetaExt", err) 95 }, 96 result: &MasterMetaExt{}, 97 }, 98 } 99 100 for i := range cases { 101 i := i 102 t.Run(fmt.Sprintf("subcase-%d", i), func(t *testing.T) { 103 t.Parallel() 104 var ext MasterMetaExt 105 c := cases[i] 106 c.checkErr(t, ext.Scan(c.input)) 107 require.Equal(t, c.result, &ext) 108 }) 109 } 110 } 111 112 func TestMasterMetaExtValue(t *testing.T) { 113 t.Parallel() 114 115 ext := &MasterMetaExt{Selectors: []*label.Selector{ 116 { 117 Key: "test", 118 Target: "test-val", 119 Op: label.OpEq, 120 }, 121 }} 122 val, err := ext.Value() 123 require.NoError(t, err) 124 require.IsType(t, "" /* string */, val) 125 require.Equal(t, `{"selectors":[{"label":"test","target":"test-val","op":"eq"}]}`, val) 126 } 127 128 func TestMasterStateIsTerminated(t *testing.T) { 129 t.Parallel() 130 131 testCases := []struct { 132 code MasterState 133 isTerminated bool 134 }{ 135 {MasterStateUninit, false}, 136 {MasterStateInit, false}, 137 {MasterStateFinished, true}, 138 {MasterStateStopped, true}, 139 {MasterStateFailed, true}, 140 } 141 for _, tc := range testCases { 142 require.Equal(t, tc.isTerminated, tc.code.IsTerminatedState()) 143 } 144 } 145 146 func TestOrmKeyValues(t *testing.T) { 147 t.Parallel() 148 meta := &MasterMeta{ 149 ProjectID: "p-id", 150 ID: "job-id", 151 Type: 1, 152 NodeID: "node-id", 153 Epoch: 1, 154 State: 1, 155 Addr: "127.0.0.1", 156 Config: []byte{0x11, 0x22}, 157 ErrorMsg: "error message", 158 Detail: []byte("job detail"), 159 } 160 require.Equal(t, ormModel.KeyValueMap{ 161 "node_id": meta.NodeID, 162 "address": meta.Addr, 163 "epoch": meta.Epoch, 164 }, meta.RefreshValues()) 165 166 require.Equal(t, ormModel.KeyValueMap{ 167 "state": meta.State, 168 }, meta.UpdateStateValues()) 169 170 require.Equal(t, ormModel.KeyValueMap{ 171 "error_message": meta.ErrorMsg, 172 }, meta.UpdateErrorValues()) 173 174 require.Equal(t, ormModel.KeyValueMap{ 175 "state": meta.State, 176 "error_message": meta.ErrorMsg, 177 "detail": meta.Detail, 178 }, meta.ExitValues()) 179 }