go.temporal.io/server@v1.23.0/common/util_test.go (about)

     1  // The MIT License
     2  //
     3  // Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
     4  //
     5  // Copyright (c) 2020 Uber Technologies, Inc.
     6  //
     7  // Permission is hereby granted, free of charge, to any person obtaining a copy
     8  // of this software and associated documentation files (the "Software"), to deal
     9  // in the Software without restriction, including without limitation the rights
    10  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  // copies of the Software, and to permit persons to whom the Software is
    12  // furnished to do so, subject to the following conditions:
    13  //
    14  // The above copyright notice and this permission notice shall be included in
    15  // all copies or substantial portions of the Software.
    16  //
    17  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  // THE SOFTWARE.
    24  
    25  package common
    26  
    27  import (
    28  	"context"
    29  	"errors"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/pborman/uuid"
    34  	"github.com/stretchr/testify/assert"
    35  	"github.com/stretchr/testify/require"
    36  	commonpb "go.temporal.io/api/common/v1"
    37  	enumspb "go.temporal.io/api/enums/v1"
    38  	"go.temporal.io/api/serviceerror"
    39  	"google.golang.org/protobuf/types/known/durationpb"
    40  
    41  	"go.temporal.io/server/common/dynamicconfig"
    42  )
    43  
    44  func TestValidateRetryPolicy(t *testing.T) {
    45  	testCases := []struct {
    46  		name          string
    47  		input         *commonpb.RetryPolicy
    48  		wantErr       bool
    49  		wantErrString string
    50  	}{
    51  		{
    52  			name:          "nil policy is okay",
    53  			input:         nil,
    54  			wantErr:       false,
    55  			wantErrString: "",
    56  		},
    57  		{
    58  			name: "maxAttempts is 1, coefficient < 1",
    59  			input: &commonpb.RetryPolicy{
    60  				BackoffCoefficient: 0.5,
    61  				MaximumAttempts:    1,
    62  			},
    63  			wantErr:       false,
    64  			wantErrString: "",
    65  		},
    66  		{
    67  			name: "initial interval negative",
    68  			input: &commonpb.RetryPolicy{
    69  				InitialInterval: durationpb.New(-22 * time.Second),
    70  			},
    71  			wantErr:       true,
    72  			wantErrString: "InitialInterval cannot be negative on retry policy.",
    73  		},
    74  		{
    75  			name: "coefficient < 1",
    76  			input: &commonpb.RetryPolicy{
    77  				BackoffCoefficient: 0.8,
    78  			},
    79  			wantErr:       true,
    80  			wantErrString: "BackoffCoefficient cannot be less than 1 on retry policy.",
    81  		},
    82  		{
    83  			name: "maximum interval in seconds is negative",
    84  			input: &commonpb.RetryPolicy{
    85  				BackoffCoefficient: 2.0,
    86  				MaximumInterval:    durationpb.New(-2 * time.Second),
    87  			},
    88  			wantErr:       true,
    89  			wantErrString: "MaximumInterval cannot be negative on retry policy.",
    90  		},
    91  		{
    92  			name: "maximum interval in less than initial interval",
    93  			input: &commonpb.RetryPolicy{
    94  				BackoffCoefficient: 2.0,
    95  				MaximumInterval:    durationpb.New(5 * time.Second),
    96  				InitialInterval:    durationpb.New(10 * time.Second),
    97  			},
    98  			wantErr:       true,
    99  			wantErrString: "MaximumInterval cannot be less than InitialInterval on retry policy.",
   100  		},
   101  		{
   102  			name: "maximum attempts negative",
   103  			input: &commonpb.RetryPolicy{
   104  				BackoffCoefficient: 2.0,
   105  				MaximumAttempts:    -3,
   106  			},
   107  			wantErr:       true,
   108  			wantErrString: "MaximumAttempts cannot be negative on retry policy.",
   109  		},
   110  		{
   111  			name: "timeout nonretryable error - valid type",
   112  			input: &commonpb.RetryPolicy{
   113  				BackoffCoefficient: 1,
   114  				NonRetryableErrorTypes: []string{
   115  					TimeoutFailureTypePrefix + enumspb.TIMEOUT_TYPE_START_TO_CLOSE.String(),
   116  					TimeoutFailureTypePrefix + enumspb.TIMEOUT_TYPE_SCHEDULE_TO_START.String(),
   117  					TimeoutFailureTypePrefix + enumspb.TIMEOUT_TYPE_SCHEDULE_TO_CLOSE.String(),
   118  					TimeoutFailureTypePrefix + enumspb.TIMEOUT_TYPE_HEARTBEAT.String(),
   119  				},
   120  			},
   121  			wantErr:       false,
   122  			wantErrString: "",
   123  		},
   124  		{
   125  			name: "timeout nonretryable error - unspecified type",
   126  			input: &commonpb.RetryPolicy{
   127  				BackoffCoefficient: 1,
   128  				NonRetryableErrorTypes: []string{
   129  					TimeoutFailureTypePrefix + enumspb.TIMEOUT_TYPE_UNSPECIFIED.String(),
   130  				},
   131  			},
   132  			wantErr:       true,
   133  			wantErrString: "Invalid timeout type value: Unspecified.",
   134  		},
   135  		{
   136  			name: "timeout nonretryable error - unknown type",
   137  			input: &commonpb.RetryPolicy{
   138  				BackoffCoefficient: 1,
   139  				NonRetryableErrorTypes: []string{
   140  					TimeoutFailureTypePrefix + "unknown",
   141  				},
   142  			},
   143  			wantErr:       true,
   144  			wantErrString: "Invalid timeout type value: unknown.",
   145  		},
   146  	}
   147  
   148  	for _, tt := range testCases {
   149  		t.Run(tt.name, func(t *testing.T) {
   150  			err := ValidateRetryPolicy(tt.input)
   151  			if tt.wantErr {
   152  				assert.NotNil(t, err, "expected error - did not get one")
   153  				assert.Equal(t, err.Error(), tt.wantErrString, "unexpected error message")
   154  			} else {
   155  				assert.Nil(t, err, "unexpected error")
   156  			}
   157  		})
   158  	}
   159  }
   160  
   161  func TestEnsureRetryPolicyDefaults(t *testing.T) {
   162  	defaultRetrySettings := DefaultRetrySettings{
   163  		InitialInterval:            time.Second,
   164  		MaximumIntervalCoefficient: 100,
   165  		BackoffCoefficient:         2.0,
   166  		MaximumAttempts:            120,
   167  	}
   168  
   169  	defaultRetryPolicy := &commonpb.RetryPolicy{
   170  		InitialInterval:    durationpb.New(1 * time.Second),
   171  		MaximumInterval:    durationpb.New(100 * time.Second),
   172  		BackoffCoefficient: 2.0,
   173  		MaximumAttempts:    120,
   174  	}
   175  
   176  	testCases := []struct {
   177  		name  string
   178  		input *commonpb.RetryPolicy
   179  		want  *commonpb.RetryPolicy
   180  	}{
   181  		{
   182  			name:  "default fields are set ",
   183  			input: &commonpb.RetryPolicy{},
   184  			want:  defaultRetryPolicy,
   185  		},
   186  		{
   187  			name: "non-default InitialIntervalInSeconds is not set",
   188  			input: &commonpb.RetryPolicy{
   189  				InitialInterval: durationpb.New(2 * time.Second),
   190  			},
   191  			want: &commonpb.RetryPolicy{
   192  				InitialInterval:    durationpb.New(2 * time.Second),
   193  				MaximumInterval:    durationpb.New(200 * time.Second),
   194  				BackoffCoefficient: 2,
   195  				MaximumAttempts:    120,
   196  			},
   197  		},
   198  		{
   199  			name: "non-default MaximumIntervalInSeconds is not set",
   200  			input: &commonpb.RetryPolicy{
   201  				MaximumInterval: durationpb.New(1000 * time.Second),
   202  			},
   203  			want: &commonpb.RetryPolicy{
   204  				InitialInterval:    durationpb.New(1 * time.Second),
   205  				MaximumInterval:    durationpb.New(1000 * time.Second),
   206  				BackoffCoefficient: 2,
   207  				MaximumAttempts:    120,
   208  			},
   209  		},
   210  		{
   211  			name: "non-default BackoffCoefficient is not set",
   212  			input: &commonpb.RetryPolicy{
   213  				BackoffCoefficient: 1.5,
   214  			},
   215  			want: &commonpb.RetryPolicy{
   216  				InitialInterval:    durationpb.New(1 * time.Second),
   217  				MaximumInterval:    durationpb.New(100 * time.Second),
   218  				BackoffCoefficient: 1.5,
   219  				MaximumAttempts:    120,
   220  			},
   221  		},
   222  		{
   223  			name: "non-default Maximum attempts is not set",
   224  			input: &commonpb.RetryPolicy{
   225  				MaximumAttempts: 49,
   226  			},
   227  			want: &commonpb.RetryPolicy{
   228  				InitialInterval:    durationpb.New(1 * time.Second),
   229  				MaximumInterval:    durationpb.New(100 * time.Second),
   230  				BackoffCoefficient: 2,
   231  				MaximumAttempts:    49,
   232  			},
   233  		},
   234  		{
   235  			name: "non-retryable errors are set",
   236  			input: &commonpb.RetryPolicy{
   237  				NonRetryableErrorTypes: []string{"testFailureType"},
   238  			},
   239  			want: &commonpb.RetryPolicy{
   240  				InitialInterval:        durationpb.New(1 * time.Second),
   241  				MaximumInterval:        durationpb.New(100 * time.Second),
   242  				BackoffCoefficient:     2.0,
   243  				MaximumAttempts:        120,
   244  				NonRetryableErrorTypes: []string{"testFailureType"},
   245  			},
   246  		},
   247  	}
   248  
   249  	for _, tt := range testCases {
   250  		t.Run(tt.name, func(t *testing.T) {
   251  			EnsureRetryPolicyDefaults(tt.input, defaultRetrySettings)
   252  			assert.Equal(t, tt.want, tt.input)
   253  		})
   254  	}
   255  }
   256  
   257  func Test_FromConfigToRetryPolicy(t *testing.T) {
   258  	options := map[string]interface{}{
   259  		initialIntervalInSecondsConfigKey:   2,
   260  		maximumIntervalCoefficientConfigKey: 100.0,
   261  		backoffCoefficientConfigKey:         4.0,
   262  		maximumAttemptsConfigKey:            5,
   263  	}
   264  
   265  	defaultSettings := FromConfigToDefaultRetrySettings(options)
   266  	assert.Equal(t, 2*time.Second, defaultSettings.InitialInterval)
   267  	assert.Equal(t, 100.0, defaultSettings.MaximumIntervalCoefficient)
   268  	assert.Equal(t, 4.0, defaultSettings.BackoffCoefficient)
   269  	assert.Equal(t, int32(5), defaultSettings.MaximumAttempts)
   270  }
   271  
   272  func TestIsContextDeadlineExceededErr(t *testing.T) {
   273  	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(-time.Millisecond))
   274  	defer cancel()
   275  	require.True(t, IsContextDeadlineExceededErr(ctx.Err()))
   276  	require.True(t, IsContextDeadlineExceededErr(serviceerror.NewDeadlineExceeded("something")))
   277  
   278  	require.False(t, IsContextDeadlineExceededErr(errors.New("some random error")))
   279  
   280  	ctx, cancel = context.WithCancel(context.Background())
   281  	cancel()
   282  	require.False(t, IsContextDeadlineExceededErr(ctx.Err()))
   283  }
   284  
   285  func TestIsContextCanceledErr(t *testing.T) {
   286  	require.True(t, IsContextCanceledErr(serviceerror.NewCanceled("something")))
   287  	require.False(t, IsContextCanceledErr(errors.New("some random error")))
   288  
   289  	ctx, cancel := context.WithCancel(context.Background())
   290  	cancel()
   291  	require.True(t, IsContextCanceledErr(ctx.Err()))
   292  }
   293  
   294  func TestOverrideWorkflowRunTimeout_InfiniteRunTimeout_InfiniteExecutionTimeout(t *testing.T) {
   295  	runTimeout := time.Duration(0)
   296  	executionTimeout := time.Duration(0)
   297  	require.Equal(t, time.Duration(0), OverrideWorkflowRunTimeout(runTimeout, executionTimeout))
   298  }
   299  
   300  func TestOverrideWorkflowRunTimeout_FiniteRunTimeout_InfiniteExecutionTimeout(t *testing.T) {
   301  	runTimeout := time.Duration(10)
   302  	executionTimeout := time.Duration(0)
   303  	require.Equal(t, time.Duration(10), OverrideWorkflowRunTimeout(runTimeout, executionTimeout))
   304  }
   305  
   306  func TestOverrideWorkflowRunTimeout_InfiniteRunTimeout_FiniteExecutionTimeout(t *testing.T) {
   307  	runTimeout := time.Duration(0)
   308  	executionTimeout := time.Duration(10)
   309  	require.Equal(t, time.Duration(10), OverrideWorkflowRunTimeout(runTimeout, executionTimeout))
   310  }
   311  
   312  func TestOverrideWorkflowRunTimeout_FiniteRunTimeout_FiniteExecutionTimeout(t *testing.T) {
   313  	runTimeout := time.Duration(100)
   314  	executionTimeout := time.Duration(10)
   315  	require.Equal(t, time.Duration(10), OverrideWorkflowRunTimeout(runTimeout, executionTimeout))
   316  
   317  	runTimeout = time.Duration(10)
   318  	executionTimeout = time.Duration(100)
   319  	require.Equal(t, time.Duration(10), OverrideWorkflowRunTimeout(runTimeout, executionTimeout))
   320  }
   321  
   322  func TestOverrideWorkflowTaskTimeout_Infinite(t *testing.T) {
   323  	taskTimeout := time.Duration(0)
   324  	runTimeout := time.Duration(100)
   325  	defaultTimeout := time.Duration(20)
   326  	defaultTimeoutFn := dynamicconfig.GetDurationPropertyFnFilteredByNamespace(defaultTimeout)
   327  	require.Equal(t, time.Duration(20), OverrideWorkflowTaskTimeout("random domain", taskTimeout, runTimeout, defaultTimeoutFn))
   328  
   329  	taskTimeout = time.Duration(0)
   330  	runTimeout = time.Duration(10)
   331  	defaultTimeout = time.Duration(20)
   332  	defaultTimeoutFn = dynamicconfig.GetDurationPropertyFnFilteredByNamespace(defaultTimeout)
   333  	require.Equal(t, time.Duration(10), OverrideWorkflowTaskTimeout("random domain", taskTimeout, runTimeout, defaultTimeoutFn))
   334  
   335  	taskTimeout = time.Duration(0)
   336  	runTimeout = time.Duration(0)
   337  	defaultTimeout = time.Duration(30)
   338  	defaultTimeoutFn = dynamicconfig.GetDurationPropertyFnFilteredByNamespace(defaultTimeout)
   339  	require.Equal(t, time.Duration(30), OverrideWorkflowTaskTimeout("random domain", taskTimeout, runTimeout, defaultTimeoutFn))
   340  
   341  	taskTimeout = time.Duration(0)
   342  	runTimeout = time.Duration(0)
   343  	defaultTimeout = MaxWorkflowTaskStartToCloseTimeout + time.Duration(1)
   344  	defaultTimeoutFn = dynamicconfig.GetDurationPropertyFnFilteredByNamespace(defaultTimeout)
   345  	require.Equal(t, MaxWorkflowTaskStartToCloseTimeout, OverrideWorkflowTaskTimeout("random domain", taskTimeout, runTimeout, defaultTimeoutFn))
   346  }
   347  
   348  func TestOverrideWorkflowTaskTimeout_Finite(t *testing.T) {
   349  	taskTimeout := time.Duration(10)
   350  	runTimeout := MaxWorkflowTaskStartToCloseTimeout - time.Duration(1)
   351  	defaultTimeout := time.Duration(20)
   352  	defaultTimeoutFn := dynamicconfig.GetDurationPropertyFnFilteredByNamespace(defaultTimeout)
   353  	require.Equal(t, time.Duration(10), OverrideWorkflowTaskTimeout("random domain", taskTimeout, runTimeout, defaultTimeoutFn))
   354  
   355  	taskTimeout = MaxWorkflowTaskStartToCloseTimeout - time.Duration(1)
   356  	runTimeout = time.Duration(10)
   357  	defaultTimeout = time.Duration(20)
   358  	defaultTimeoutFn = dynamicconfig.GetDurationPropertyFnFilteredByNamespace(defaultTimeout)
   359  	require.Equal(t, time.Duration(10), OverrideWorkflowTaskTimeout("random domain", taskTimeout, runTimeout, defaultTimeoutFn))
   360  
   361  	taskTimeout = time.Duration(10)
   362  	runTimeout = MaxWorkflowTaskStartToCloseTimeout + time.Duration(1)
   363  	defaultTimeout = time.Duration(20)
   364  	defaultTimeoutFn = dynamicconfig.GetDurationPropertyFnFilteredByNamespace(defaultTimeout)
   365  	require.Equal(t, time.Duration(10), OverrideWorkflowTaskTimeout("random domain", taskTimeout, runTimeout, defaultTimeoutFn))
   366  
   367  	taskTimeout = MaxWorkflowTaskStartToCloseTimeout + time.Duration(1)
   368  	runTimeout = MaxWorkflowTaskStartToCloseTimeout + time.Duration(1)
   369  	defaultTimeout = time.Duration(20)
   370  	defaultTimeoutFn = dynamicconfig.GetDurationPropertyFnFilteredByNamespace(defaultTimeout)
   371  	require.Equal(t, MaxWorkflowTaskStartToCloseTimeout, OverrideWorkflowTaskTimeout("random domain", taskTimeout, runTimeout, defaultTimeoutFn))
   372  }
   373  
   374  func TestMapShardID_ByNamespaceWorkflow_4And16(t *testing.T) {
   375  	namespaceID := uuid.New()
   376  	workflowID := uuid.New()
   377  	shardID4 := WorkflowIDToHistoryShard(namespaceID, workflowID, 4)
   378  	shardID16 := WorkflowIDToHistoryShard(namespaceID, workflowID, 16)
   379  
   380  	targetShardIDs := MapShardID(16, 4, shardID16)
   381  	require.Equal(t, []int32{
   382  		shardID4,
   383  	}, targetShardIDs)
   384  
   385  	targetShardIDs = MapShardID(4, 16, shardID4)
   386  	found := false
   387  	for _, targetShardID := range targetShardIDs {
   388  		if shardID16 == targetShardID {
   389  			found = true
   390  			break
   391  		}
   392  	}
   393  	require.True(t, found)
   394  }
   395  
   396  func TestMapShardID_1To4(t *testing.T) {
   397  	sourceShardCount := int32(1)
   398  	targetShardCount := int32(4)
   399  
   400  	targetShards := MapShardID(sourceShardCount, targetShardCount, 1)
   401  	require.Equal(t, []int32{
   402  		1, 2, 3, 4,
   403  	}, targetShards)
   404  }
   405  
   406  func TestMapShardID_4To1(t *testing.T) {
   407  	sourceShardCount := int32(4)
   408  	targetShardCount := int32(1)
   409  
   410  	targetShards := MapShardID(sourceShardCount, targetShardCount, 4)
   411  	require.Equal(t, []int32{1}, targetShards)
   412  
   413  	targetShards = MapShardID(sourceShardCount, targetShardCount, 3)
   414  	require.Equal(t, []int32{1}, targetShards)
   415  
   416  	targetShards = MapShardID(sourceShardCount, targetShardCount, 2)
   417  	require.Equal(t, []int32{1}, targetShards)
   418  
   419  	targetShards = MapShardID(sourceShardCount, targetShardCount, 1)
   420  	require.Equal(t, []int32{1}, targetShards)
   421  }
   422  
   423  func TestMapShardID_4To16(t *testing.T) {
   424  	sourceShardCount := int32(4)
   425  	targetShardCount := int32(16)
   426  
   427  	targetShards := MapShardID(sourceShardCount, targetShardCount, 1)
   428  	require.Equal(t, []int32{
   429  		1, 5, 9, 13,
   430  	}, targetShards)
   431  
   432  	targetShards = MapShardID(sourceShardCount, targetShardCount, 2)
   433  	require.Equal(t, []int32{
   434  		2, 6, 10, 14,
   435  	}, targetShards)
   436  
   437  	targetShards = MapShardID(sourceShardCount, targetShardCount, 3)
   438  	require.Equal(t, []int32{
   439  		3, 7, 11, 15,
   440  	}, targetShards)
   441  
   442  	targetShards = MapShardID(sourceShardCount, targetShardCount, 4)
   443  	require.Equal(t, []int32{
   444  		4, 8, 12, 16,
   445  	}, targetShards)
   446  }
   447  
   448  func TestMapShardID_16To4(t *testing.T) {
   449  	sourceShardCount := int32(16)
   450  	targetShardCount := int32(4)
   451  
   452  	targetShards := MapShardID(sourceShardCount, targetShardCount, 16)
   453  	require.Equal(t, []int32{4}, targetShards)
   454  
   455  	targetShards = MapShardID(sourceShardCount, targetShardCount, 15)
   456  	require.Equal(t, []int32{3}, targetShards)
   457  
   458  	targetShards = MapShardID(sourceShardCount, targetShardCount, 14)
   459  	require.Equal(t, []int32{2}, targetShards)
   460  
   461  	targetShards = MapShardID(sourceShardCount, targetShardCount, 13)
   462  	require.Equal(t, []int32{1}, targetShards)
   463  
   464  	targetShards = MapShardID(sourceShardCount, targetShardCount, 12)
   465  	require.Equal(t, []int32{4}, targetShards)
   466  
   467  	targetShards = MapShardID(sourceShardCount, targetShardCount, 11)
   468  	require.Equal(t, []int32{3}, targetShards)
   469  
   470  	targetShards = MapShardID(sourceShardCount, targetShardCount, 10)
   471  	require.Equal(t, []int32{2}, targetShards)
   472  
   473  	targetShards = MapShardID(sourceShardCount, targetShardCount, 9)
   474  	require.Equal(t, []int32{1}, targetShards)
   475  
   476  	targetShards = MapShardID(sourceShardCount, targetShardCount, 8)
   477  	require.Equal(t, []int32{4}, targetShards)
   478  
   479  	targetShards = MapShardID(sourceShardCount, targetShardCount, 7)
   480  	require.Equal(t, []int32{3}, targetShards)
   481  
   482  	targetShards = MapShardID(sourceShardCount, targetShardCount, 6)
   483  	require.Equal(t, []int32{2}, targetShards)
   484  
   485  	targetShards = MapShardID(sourceShardCount, targetShardCount, 5)
   486  	require.Equal(t, []int32{1}, targetShards)
   487  
   488  	targetShards = MapShardID(sourceShardCount, targetShardCount, 4)
   489  	require.Equal(t, []int32{4}, targetShards)
   490  
   491  	targetShards = MapShardID(sourceShardCount, targetShardCount, 3)
   492  	require.Equal(t, []int32{3}, targetShards)
   493  
   494  	targetShards = MapShardID(sourceShardCount, targetShardCount, 2)
   495  	require.Equal(t, []int32{2}, targetShards)
   496  
   497  	targetShards = MapShardID(sourceShardCount, targetShardCount, 1)
   498  	require.Equal(t, []int32{1}, targetShards)
   499  }
   500  
   501  func TestVerifyShardIDMapping_1VS4(t *testing.T) {
   502  	require.NoError(t, VerifyShardIDMapping(1, 4, 1, 1))
   503  	require.NoError(t, VerifyShardIDMapping(1, 4, 1, 2))
   504  	require.NoError(t, VerifyShardIDMapping(1, 4, 1, 3))
   505  	require.NoError(t, VerifyShardIDMapping(1, 4, 1, 4))
   506  }
   507  
   508  func TestVerifyShardIDMapping_2VS4(t *testing.T) {
   509  	require.NoError(t, VerifyShardIDMapping(2, 4, 1, 1))
   510  	require.Error(t, VerifyShardIDMapping(2, 4, 1, 2))
   511  	require.NoError(t, VerifyShardIDMapping(2, 4, 1, 3))
   512  	require.Error(t, VerifyShardIDMapping(2, 4, 1, 4))
   513  
   514  	require.Error(t, VerifyShardIDMapping(2, 4, 2, 1))
   515  	require.NoError(t, VerifyShardIDMapping(2, 4, 2, 2))
   516  	require.Error(t, VerifyShardIDMapping(2, 4, 2, 3))
   517  	require.NoError(t, VerifyShardIDMapping(2, 4, 2, 4))
   518  }