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  }