github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/framework/registry/registry_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 registry
    15  
    16  import (
    17  	"testing"
    18  
    19  	"github.com/pingcap/tiflow/engine/framework"
    20  	frameModel "github.com/pingcap/tiflow/engine/framework/model"
    21  	dcontext "github.com/pingcap/tiflow/engine/pkg/context"
    22  	pkgOrm "github.com/pingcap/tiflow/engine/pkg/orm"
    23  	"github.com/pingcap/tiflow/pkg/errors"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  var fakeWorkerFactory WorkerFactory = NewSimpleWorkerFactory(newFakeWorker)
    28  
    29  const (
    30  	fakeWorkerType = frameModel.FakeJobMaster
    31  )
    32  
    33  func TestGlobalRegistry(t *testing.T) {
    34  	GlobalWorkerRegistry().MustRegisterWorkerType(fakeWorkerType, fakeWorkerFactory)
    35  
    36  	ctx, cancel := makeCtxWithMockDeps(t)
    37  	defer cancel()
    38  	metaCli, err := ctx.Deps().Construct(
    39  		func(cli pkgOrm.Client) (pkgOrm.Client, error) {
    40  			return cli, nil
    41  		},
    42  	)
    43  	require.NoError(t, err)
    44  	defer metaCli.(pkgOrm.Client).Close()
    45  	epoch, err := metaCli.(pkgOrm.Client).GenEpoch(ctx)
    46  	require.NoError(t, err)
    47  	worker, err := GlobalWorkerRegistry().CreateWorker(
    48  		ctx,
    49  		fakeWorkerType,
    50  		"worker-1",
    51  		"master-1",
    52  		[]byte(`{"target-tick":10}`),
    53  		epoch,
    54  	)
    55  	require.NoError(t, err)
    56  	require.IsType(t, &framework.DefaultBaseWorker{}, worker)
    57  	impl := worker.(*framework.DefaultBaseWorker).Impl
    58  	require.IsType(t, &fakeWorker{}, impl)
    59  	require.NotNil(t, impl.(*fakeWorker).BaseWorker)
    60  	require.Equal(t, "worker-1", worker.ID())
    61  }
    62  
    63  func TestRegistryDuplicateType(t *testing.T) {
    64  	registry := NewRegistry()
    65  	ok := registry.RegisterWorkerType(fakeWorkerType, fakeWorkerFactory)
    66  	require.True(t, ok)
    67  
    68  	ok = registry.RegisterWorkerType(fakeWorkerType, fakeWorkerFactory)
    69  	require.False(t, ok)
    70  
    71  	require.Panics(t, func() {
    72  		registry.MustRegisterWorkerType(fakeWorkerType, fakeWorkerFactory)
    73  	})
    74  }
    75  
    76  func TestRegistryWorkerTypeNotFound(t *testing.T) {
    77  	registry := NewRegistry()
    78  	ctx := dcontext.Background()
    79  	_, err := registry.CreateWorker(ctx, fakeWorkerType, "worker-1", "master-1",
    80  		[]byte(`{"Val"":0}`), int64(2))
    81  	require.Error(t, err)
    82  }
    83  
    84  func TestGetTypeNameOfVarPtr(t *testing.T) {
    85  	t.Parallel()
    86  
    87  	type myType struct{}
    88  
    89  	var (
    90  		a int
    91  		b myType
    92  	)
    93  	require.Equal(t, "int", getTypeNameOfVarPtr(&a))
    94  	require.Equal(t, "myType", getTypeNameOfVarPtr(&b))
    95  }
    96  
    97  func TestImplHasMember(t *testing.T) {
    98  	t.Parallel()
    99  
   100  	type myImpl struct {
   101  		MyMember int
   102  	}
   103  	type myIface interface{}
   104  
   105  	var iface myIface = &myImpl{}
   106  	require.True(t, implHasMember(iface, "MyMember"))
   107  	require.False(t, implHasMember(iface, "notFound"))
   108  }
   109  
   110  func TestSetImplMember(t *testing.T) {
   111  	t.Parallel()
   112  
   113  	type MyBase interface{}
   114  
   115  	type myImpl struct {
   116  		MyBase
   117  	}
   118  	type myImplIface interface{}
   119  
   120  	var iface myImplIface = &myImpl{}
   121  
   122  	setImplMember(iface, "MyBase", 2)
   123  	require.Equal(t, 2, iface.(*myImpl).MyBase.(int))
   124  }
   125  
   126  func TestIsRetryableError(t *testing.T) {
   127  	t.Parallel()
   128  
   129  	registry := NewRegistry()
   130  	ok := registry.RegisterWorkerType(frameModel.FakeJobMaster, NewSimpleWorkerFactory(newFakeWorker))
   131  	require.True(t, ok)
   132  
   133  	testCases := []struct {
   134  		err         error
   135  		isRetryable bool
   136  	}{
   137  		{errors.ErrDeserializeConfig.GenWithStackByArgs(), false},
   138  		{errors.New("normal error"), true},
   139  	}
   140  
   141  	for _, tc := range testCases {
   142  		retryable, err := registry.IsRetryableError(tc.err, frameModel.FakeJobMaster)
   143  		require.NoError(t, err)
   144  		require.Equal(t, tc.isRetryable, retryable)
   145  	}
   146  }