github.com/cloudwego/kitex@v0.9.0/pkg/retry/policy_test.go (about)

     1  /*
     2   * Copyright 2021 CloudWeGo Authors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package retry
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	jsoniter "github.com/json-iterator/go"
    24  
    25  	"github.com/cloudwego/kitex/internal/test"
    26  	"github.com/cloudwego/kitex/pkg/rpcinfo"
    27  	"github.com/cloudwego/kitex/pkg/rpcinfo/remoteinfo"
    28  	"github.com/cloudwego/kitex/pkg/stats"
    29  )
    30  
    31  var (
    32  	jsoni  = jsoniter.ConfigCompatibleWithStandardLibrary
    33  	method = "test"
    34  )
    35  
    36  // test new failurePolicy
    37  func TestFailureRetryPolicy(t *testing.T) {
    38  	fp := NewFailurePolicy()
    39  
    40  	// case 1
    41  	fp.WithMaxRetryTimes(3)
    42  	jsonRet, err := jsoni.MarshalToString(fp)
    43  	test.Assert(t, err == nil, err)
    44  
    45  	var fp2 FailurePolicy
    46  	err = jsoni.UnmarshalFromString(jsonRet, &fp2)
    47  	test.Assert(t, err == nil, err)
    48  	test.Assert(t, fp.Equals(&fp2))
    49  
    50  	// case 2
    51  	fp.WithMaxRetryTimes(2)
    52  	fp.WithRetrySameNode()
    53  	fp.WithFixedBackOff(10)
    54  	jsonRet, err = jsoni.MarshalToString(fp)
    55  	test.Assert(t, err == nil, err)
    56  
    57  	// case 3
    58  	var fp3 FailurePolicy
    59  	err = jsoni.UnmarshalFromString(jsonRet, &fp3)
    60  	test.Assert(t, err == nil, err)
    61  	test.Assert(t, fp.Equals(&fp3), fp3)
    62  
    63  	// case 4
    64  	fp.WithRetrySameNode()
    65  	fp.WithRandomBackOff(10, 20)
    66  	jsonRet, err = jsoni.MarshalToString(fp)
    67  	test.Assert(t, err == nil, err)
    68  
    69  	var fp4 FailurePolicy
    70  	err = jsoni.UnmarshalFromString(jsonRet, &fp4)
    71  	test.Assert(t, err == nil, err)
    72  	test.Assert(t, fp.Equals(&fp4), fp4)
    73  
    74  	// case 5
    75  	fp.WithRetryBreaker(0.1)
    76  	fp.WithDDLStop()
    77  	fp.WithMaxDurationMS(100)
    78  	jsonRet, err = jsoni.MarshalToString(fp)
    79  	test.Assert(t, err == nil, err)
    80  
    81  	var fp5 FailurePolicy
    82  	err = jsoni.UnmarshalFromString(jsonRet, &fp5)
    83  	test.Assert(t, err == nil, err)
    84  	test.Assert(t, fp.Equals(&fp5), fp5)
    85  
    86  	// case 6
    87  	fp = &FailurePolicy{
    88  		StopPolicy: StopPolicy{
    89  			MaxRetryTimes:    2,
    90  			DisableChainStop: false,
    91  			CBPolicy: CBPolicy{
    92  				ErrorRate: defaultCBErrRate,
    93  			},
    94  		},
    95  		Extra: "{}",
    96  	}
    97  	jsonRet, err = jsoni.MarshalToString(fp)
    98  	test.Assert(t, err == nil, err)
    99  	var fp6 FailurePolicy
   100  	err = jsoni.UnmarshalFromString(jsonRet, &fp6)
   101  	test.Assert(t, err == nil, err)
   102  	test.Assert(t, fp6.BackOffPolicy == nil)
   103  	test.Assert(t, fp.Equals(&fp6), fp6)
   104  
   105  	// case 7
   106  	fp.DisableChainRetryStop()
   107  	jsonRet, err = jsoni.MarshalToString(fp)
   108  	test.Assert(t, err == nil, err)
   109  	var fp7 FailurePolicy
   110  	err = jsoni.UnmarshalFromString(jsonRet, &fp7)
   111  	test.Assert(t, err == nil, err)
   112  	test.Assert(t, fp7.BackOffPolicy == nil)
   113  	test.Assert(t, fp.Equals(&fp7), fp7)
   114  
   115  	// case 8
   116  	test.Assert(t, fp.String() == "{StopPolicy:{MaxRetryTimes:2 MaxDurationMS:0 DisableChainStop:true "+
   117  		"DDLStop:false CBPolicy:{ErrorRate:0.1}} BackOffPolicy:<nil> RetrySameNode:false ShouldResultRetry:{ErrorRetry:false, RespRetry:false}}", fp)
   118  
   119  	// case 9
   120  	fp.WithSpecifiedResultRetry(&ShouldResultRetry{ErrorRetry: func(err error, ri rpcinfo.RPCInfo) bool {
   121  		return false
   122  	}})
   123  	test.Assert(t, fp.String() == "{StopPolicy:{MaxRetryTimes:2 MaxDurationMS:0 DisableChainStop:true "+
   124  		"DDLStop:false CBPolicy:{ErrorRate:0.1}} BackOffPolicy:<nil> RetrySameNode:false ShouldResultRetry:{ErrorRetry:true, RespRetry:false}}", fp)
   125  	jsonRet, err = jsoni.MarshalToString(fp)
   126  	test.Assert(t, err == nil, err)
   127  	var fp9 FailurePolicy
   128  	err = jsoni.UnmarshalFromString(jsonRet, &fp9)
   129  	test.Assert(t, err == nil, err)
   130  	test.Assert(t, fp.Equals(&fp9), fp9)
   131  	test.Assert(t, fp9.ShouldResultRetry == nil)
   132  }
   133  
   134  // test new failurePolicy with result retry
   135  func TestFailureRetryPolicyWithResultRetry(t *testing.T) {
   136  	fp := NewFailurePolicyWithResultRetry(&ShouldResultRetry{RespRetry: func(resp interface{}, ri rpcinfo.RPCInfo) bool {
   137  		return false
   138  	}, ErrorRetry: func(err error, ri rpcinfo.RPCInfo) bool {
   139  		return false
   140  	}})
   141  
   142  	test.Assert(t, fp.String() == "{StopPolicy:{MaxRetryTimes:2 MaxDurationMS:0 DisableChainStop:false DDLStop:false "+
   143  		"CBPolicy:{ErrorRate:0.1}} BackOffPolicy:&{BackOffType:none CfgItems:map[]} RetrySameNode:false ShouldResultRetry:{ErrorRetry:true, RespRetry:true}}", fp)
   144  	jsonRet, err := jsoni.MarshalToString(fp)
   145  	test.Assert(t, err == nil, err)
   146  	var fp10 FailurePolicy
   147  	err = jsoni.UnmarshalFromString(jsonRet, &fp10)
   148  	test.Assert(t, err == nil, err)
   149  	test.Assert(t, fp.Equals(&fp10), fp10)
   150  	test.Assert(t, fp10.ShouldResultRetry == nil)
   151  
   152  	t.Run("not-equal-extra", func(t *testing.T) {
   153  		p1 := &FailurePolicy{
   154  			Extra: "1",
   155  		}
   156  		p2 := &FailurePolicy{
   157  			Extra: "2",
   158  		}
   159  		test.Assert(t, !p1.Equals(p2))
   160  	})
   161  }
   162  
   163  // test new backupPolicy
   164  func TestBackupRequest(t *testing.T) {
   165  	bp := NewBackupPolicy(20)
   166  
   167  	// case 1
   168  	bp.WithMaxRetryTimes(2)
   169  	jsonRet, err := jsoni.MarshalToString(bp)
   170  	test.Assert(t, err == nil, err)
   171  
   172  	var bp2 BackupPolicy
   173  	err = jsoni.UnmarshalFromString(jsonRet, &bp2)
   174  	test.Assert(t, err == nil, err)
   175  	test.Assert(t, bp.Equals(&bp2))
   176  
   177  	// case 2
   178  	bp.DisableChainRetryStop()
   179  	jsonRet, err = jsoni.MarshalToString(bp)
   180  	test.Assert(t, err == nil, err)
   181  
   182  	var bp3 BackupPolicy
   183  	err = jsoni.UnmarshalFromString(jsonRet, &bp3)
   184  	test.Assert(t, err == nil, err)
   185  	test.Assert(t, bp.Equals(&bp3))
   186  }
   187  
   188  // test new policy both not nil
   189  func TestRetryPolicyBothNotNil(t *testing.T) {
   190  	p := Policy{
   191  		Enable:        true,
   192  		FailurePolicy: NewFailurePolicy(),
   193  		BackupPolicy:  NewBackupPolicy(20),
   194  	}
   195  	jsonRet, err := jsoni.MarshalToString(p)
   196  	test.Assert(t, err == nil, err)
   197  
   198  	var p2 Policy
   199  	err = jsoni.UnmarshalFromString(jsonRet, &p2)
   200  	test.Assert(t, err == nil, err)
   201  	test.Assert(t, p2.Enable == true)
   202  	test.Assert(t, p.Equals(p2))
   203  
   204  	ri := genRPCInfo()
   205  	rc := Container{}
   206  	rc.NotifyPolicyChange(ri.To().Method(), p2)
   207  
   208  	r := rc.getRetryer(ri)
   209  	fr, ok := r.(*failureRetryer)
   210  	test.Assert(t, ok)
   211  	test.Assert(t, fr.enable)
   212  	test.Assert(t, fr.policy.Equals(p.FailurePolicy), fr.policy, p.FailurePolicy)
   213  
   214  	p2.Enable = false
   215  	rc.NotifyPolicyChange(ri.To().Method(), p2)
   216  	test.Assert(t, !fr.enable)
   217  }
   218  
   219  // test new policy both nil
   220  func TestRetryPolicyBothNil(t *testing.T) {
   221  	p := Policy{}
   222  	jsonRet, err := jsoni.MarshalToString(p)
   223  	test.Assert(t, err == nil, err)
   224  
   225  	var p2 Policy
   226  	err = jsoni.UnmarshalFromString(jsonRet, &p2)
   227  	test.Assert(t, err == nil, err)
   228  	test.Assert(t, p.Equals(p2))
   229  
   230  	ri := genRPCInfo()
   231  	rc := Container{}
   232  	rc.NotifyPolicyChange(ri.To().Method(), p2)
   233  
   234  	r := rc.getRetryer(ri)
   235  	test.Assert(t, r != nil, r)
   236  }
   237  
   238  // test failurePolicy update
   239  func TestRetryPolicyFailure(t *testing.T) {
   240  	p := Policy{
   241  		Enable:        true,
   242  		FailurePolicy: NewFailurePolicy(),
   243  	}
   244  	jsonRet := `{"enable":true,"type":0,"failure_policy":{"stop_policy":{"max_retry_times":2,"max_duration_ms":0,"disable_chain_stop":false,"ddl_stop":false,"cb_policy":{"error_rate":0.1,"min_sample":200}},"backoff_policy":{"backoff_type":"none"},"retry_same_node":false}}`
   245  	var p2 Policy
   246  	err := jsoni.UnmarshalFromString(jsonRet, &p2)
   247  	test.Assert(t, err == nil, err)
   248  	test.Assert(t, p2.Enable)
   249  	test.Assert(t, p.Equals(p2))
   250  	test.Assert(t, p.FailurePolicy.StopPolicy.CBPolicy.ErrorRate == 0.1)
   251  
   252  	ri := genRPCInfo()
   253  	rc := Container{}
   254  	rc.NotifyPolicyChange(ri.To().Method(), p2)
   255  	r := rc.getRetryer(ri)
   256  	fr, ok := r.(*failureRetryer)
   257  	test.Assert(t, ok)
   258  	test.Assert(t, fr.policy.Equals(p.FailurePolicy))
   259  
   260  	// 模拟配置变更
   261  	fp := NewFailurePolicy()
   262  	fp.WithMaxRetryTimes(1)
   263  	fp.WithMaxRetryTimes(2)
   264  	fp.WithRetrySameNode()
   265  	fp.WithFixedBackOff(10)
   266  	p = Policy{
   267  		Enable:        true,
   268  		FailurePolicy: fp,
   269  	}
   270  	jsonRet, err = jsoni.MarshalToString(p)
   271  	test.Assert(t, err == nil, err)
   272  
   273  	var p3 Policy
   274  	err = jsoni.UnmarshalFromString(jsonRet, &p3)
   275  	test.Assert(t, err == nil, err)
   276  	test.Assert(t, p.Equals(p3))
   277  
   278  	// 更新配置
   279  	rc.NotifyPolicyChange(ri.To().Method(), p3)
   280  	r = rc.getRetryer(ri)
   281  	fr, ok = r.(*failureRetryer)
   282  	test.Assert(t, ok)
   283  	test.Assert(t, fr.policy.Equals(p.FailurePolicy))
   284  }
   285  
   286  // test policy equal
   287  func TestPolicyNotEqual(t *testing.T) {
   288  	var p, policy Policy
   289  
   290  	// create failurePolicy
   291  	policy = Policy{
   292  		Enable: true,
   293  		Type:   FailureType,
   294  		FailurePolicy: &FailurePolicy{
   295  			StopPolicy: StopPolicy{
   296  				MaxRetryTimes:    1,
   297  				MaxDurationMS:    2,
   298  				DisableChainStop: false,
   299  				DDLStop:          false,
   300  				CBPolicy: CBPolicy{
   301  					ErrorRate: defaultCBErrRate,
   302  				},
   303  			},
   304  			BackOffPolicy: &BackOffPolicy{
   305  				BackOffType: FixedBackOffType,
   306  				CfgItems: map[BackOffCfgKey]float64{
   307  					FixMSBackOffCfgKey: 100.0,
   308  				},
   309  			},
   310  			RetrySameNode: false,
   311  		},
   312  	}
   313  	jsonRet, err := jsoni.MarshalToString(policy)
   314  	test.Assert(t, err == nil, err)
   315  
   316  	// case1 enable not equal
   317  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   318  	test.Assert(t, err == nil, err)
   319  	p.Enable = false
   320  	test.Assert(t, !p.Equals(policy))
   321  
   322  	// case2 type not equal
   323  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   324  	test.Assert(t, err == nil, err)
   325  	p.Type = BackupType
   326  	test.Assert(t, !p.Equals(policy))
   327  
   328  	// case3 failurePolicy not equal
   329  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   330  	test.Assert(t, err == nil, err)
   331  	p.FailurePolicy = nil
   332  	test.Assert(t, !p.Equals(policy))
   333  	test.Assert(t, !policy.Equals(p))
   334  
   335  	// case4 failurePolicy stopPolicy not equal
   336  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   337  	test.Assert(t, err == nil, err)
   338  	p.FailurePolicy.StopPolicy.MaxRetryTimes = 2
   339  	test.Assert(t, !p.Equals(policy))
   340  
   341  	// case5 failurePolicy backOffPolicy not equal
   342  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   343  	test.Assert(t, err == nil, err)
   344  	p.FailurePolicy.BackOffPolicy = nil
   345  	test.Assert(t, !p.Equals(policy))
   346  	test.Assert(t, !policy.Equals(p))
   347  
   348  	// case6 failurePolicy backOffPolicy backOffType not equal
   349  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   350  	test.Assert(t, err == nil, err)
   351  	p.FailurePolicy.BackOffPolicy.BackOffType = RandomBackOffType
   352  	test.Assert(t, !p.Equals(policy))
   353  
   354  	// case7 failurePolicy backOffPolicy len(cfgItems) not equal
   355  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   356  	test.Assert(t, err == nil, err)
   357  	p.FailurePolicy.BackOffPolicy.CfgItems[MinMSBackOffCfgKey] = 100
   358  	test.Assert(t, !p.Equals(policy))
   359  
   360  	// case8 failurePolicy backOffPolicy cfgItems not equal
   361  	p = Policy{}
   362  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   363  	test.Assert(t, err == nil, err)
   364  	p.FailurePolicy.BackOffPolicy.CfgItems[FixMSBackOffCfgKey] = 101
   365  	test.Assert(t, !p.Equals(policy))
   366  
   367  	// case9 failurePolicy retrySameNode not equal
   368  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   369  	test.Assert(t, err == nil, err)
   370  	p.FailurePolicy.RetrySameNode = true
   371  	test.Assert(t, !p.Equals(policy))
   372  
   373  	// create backupPolicy
   374  	policy = Policy{
   375  		Enable: true,
   376  		Type:   BackupType,
   377  		BackupPolicy: &BackupPolicy{
   378  			RetryDelayMS: 1,
   379  			StopPolicy: StopPolicy{
   380  				MaxRetryTimes:    2,
   381  				MaxDurationMS:    3,
   382  				DisableChainStop: false,
   383  				DDLStop:          false,
   384  				CBPolicy: CBPolicy{
   385  					ErrorRate: defaultCBErrRate,
   386  				},
   387  			},
   388  			RetrySameNode: false,
   389  		},
   390  	}
   391  	jsonRet, err = jsoni.MarshalToString(policy)
   392  	test.Assert(t, err == nil, err)
   393  
   394  	// case10 backupPolicy not equal
   395  	p = Policy{}
   396  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   397  	test.Assert(t, err == nil, err)
   398  	p.BackupPolicy = nil
   399  	test.Assert(t, !p.Equals(policy))
   400  	test.Assert(t, !policy.Equals(p))
   401  
   402  	// case11 backupPolicy retryDelayMS not equal
   403  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   404  	test.Assert(t, err == nil, err)
   405  	p.BackupPolicy.RetryDelayMS = 2
   406  	test.Assert(t, !p.Equals(policy))
   407  
   408  	// case12 backupPolicy stopPolicy not equal
   409  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   410  	test.Assert(t, err == nil, err)
   411  	p.BackupPolicy.StopPolicy.MaxRetryTimes = 3
   412  	test.Assert(t, !p.Equals(policy))
   413  
   414  	// case13 backupPolicy retrySameNode not equal
   415  	err = jsoni.UnmarshalFromString(jsonRet, &p)
   416  	test.Assert(t, err == nil, err)
   417  	p.BackupPolicy.RetrySameNode = true
   418  	test.Assert(t, !p.Equals(policy))
   419  }
   420  
   421  func TestPolicyNotRetryForTimeout(t *testing.T) {
   422  	// create failurePolicy
   423  	fp := &FailurePolicy{StopPolicy: StopPolicy{
   424  		MaxRetryTimes:    1,
   425  		MaxDurationMS:    2,
   426  		DisableChainStop: false,
   427  		DDLStop:          false,
   428  		CBPolicy: CBPolicy{
   429  			ErrorRate: defaultCBErrRate,
   430  		},
   431  	}}
   432  	// case 1: ShouldResultRetry is nil, retry for timeout
   433  	test.Assert(t, fp.IsRetryForTimeout())
   434  
   435  	// case 2: ShouldResultRetry is not nil, NotRetryForTimeout is false, retry for timeout
   436  	fp.ShouldResultRetry = &ShouldResultRetry{
   437  		ErrorRetry: nil,
   438  		RespRetry:  nil,
   439  	}
   440  
   441  	// case 3: ShouldResultRetry is not nil, NotRetryForTimeout is true, not retry for timeout
   442  	fp.ShouldResultRetry.NotRetryForTimeout = true
   443  	test.Assert(t, !fp.IsRetryForTimeout())
   444  }
   445  
   446  func genRPCInfo() rpcinfo.RPCInfo {
   447  	to := remoteinfo.NewRemoteInfo(&rpcinfo.EndpointBasicInfo{Method: method}, method).ImmutableView()
   448  	riStats := rpcinfo.AsMutableRPCStats(rpcinfo.NewRPCStats())
   449  	riStats.SetLevel(stats.LevelDetailed)
   450  	ri := rpcinfo.NewRPCInfo(to, to, rpcinfo.NewInvocation("", method), rpcinfo.NewRPCConfig(), riStats.ImmutableView())
   451  	return ri
   452  }
   453  
   454  func genRPCInfoWithFirstStats(firstRI rpcinfo.RPCInfo) rpcinfo.RPCInfo {
   455  	to := remoteinfo.NewRemoteInfo(&rpcinfo.EndpointBasicInfo{Method: method}, method).ImmutableView()
   456  	riStats := rpcinfo.AsMutableRPCStats(firstRI.Stats().CopyForRetry())
   457  	riStats.SetLevel(stats.LevelDetailed)
   458  	ri := rpcinfo.NewRPCInfo(to, to, rpcinfo.NewInvocation("", method), rpcinfo.NewRPCConfig(), riStats.ImmutableView())
   459  	return ri
   460  }
   461  
   462  func genRPCInfoWithRemoteTag(tags map[string]string) rpcinfo.RPCInfo {
   463  	to := remoteinfo.NewRemoteInfo(&rpcinfo.EndpointBasicInfo{Method: method, Tags: tags}, method).ImmutableView()
   464  	ri := rpcinfo.NewRPCInfo(to, to, rpcinfo.NewInvocation("", method), rpcinfo.NewRPCConfig(), rpcinfo.NewRPCStats())
   465  	return ri
   466  }
   467  
   468  func TestBackOffPolicy_copyCfgItems(t *testing.T) {
   469  	type fields struct {
   470  		BackOffType BackOffType
   471  		CfgItems    map[BackOffCfgKey]float64
   472  	}
   473  	tests := []struct {
   474  		name   string
   475  		fields fields
   476  		want   map[BackOffCfgKey]float64
   477  	}{
   478  		{
   479  			name: "nil_map",
   480  			fields: fields{
   481  				BackOffType: NoneBackOffType,
   482  				CfgItems:    nil,
   483  			},
   484  			want: nil,
   485  		},
   486  		{
   487  			name: "empty_map",
   488  			fields: fields{
   489  				BackOffType: NoneBackOffType,
   490  				CfgItems:    make(map[BackOffCfgKey]float64),
   491  			},
   492  			want: make(map[BackOffCfgKey]float64),
   493  		},
   494  		{
   495  			name: "not_empty_map",
   496  			fields: fields{
   497  				BackOffType: NoneBackOffType,
   498  				CfgItems: map[BackOffCfgKey]float64{
   499  					MinMSBackOffCfgKey: 1,
   500  					MaxMSBackOffCfgKey: 2,
   501  				},
   502  			},
   503  			want: map[BackOffCfgKey]float64{
   504  				MinMSBackOffCfgKey: 1,
   505  				MaxMSBackOffCfgKey: 2,
   506  			},
   507  		},
   508  	}
   509  	for _, tt := range tests {
   510  		t.Run(tt.name, func(t *testing.T) {
   511  			p := &BackOffPolicy{
   512  				BackOffType: tt.fields.BackOffType,
   513  				CfgItems:    tt.fields.CfgItems,
   514  			}
   515  			if got := p.copyCfgItems(); !reflect.DeepEqual(got, tt.want) {
   516  				t.Errorf("copyCfgItems() = %v, want %v", got, tt.want)
   517  			}
   518  		})
   519  	}
   520  }
   521  
   522  func TestBackOffPolicy_DeepCopy(t *testing.T) {
   523  	type fields struct {
   524  		p *BackOffPolicy
   525  	}
   526  	tests := []struct {
   527  		name   string
   528  		fields fields
   529  		want   *BackOffPolicy
   530  	}{
   531  		{
   532  			name: "nil_policy",
   533  			fields: fields{
   534  				p: nil,
   535  			},
   536  			want: nil,
   537  		},
   538  		{
   539  			name: "empty_policy",
   540  			fields: fields{
   541  				p: &BackOffPolicy{
   542  					BackOffType: NoneBackOffType,
   543  					CfgItems:    make(map[BackOffCfgKey]float64),
   544  				},
   545  			},
   546  			want: &BackOffPolicy{
   547  				BackOffType: NoneBackOffType,
   548  				CfgItems:    make(map[BackOffCfgKey]float64),
   549  			},
   550  		},
   551  		{
   552  			name: "not_empty_policy",
   553  			fields: fields{
   554  				p: &BackOffPolicy{
   555  					BackOffType: NoneBackOffType,
   556  					CfgItems: map[BackOffCfgKey]float64{
   557  						MinMSBackOffCfgKey: 1,
   558  						MaxMSBackOffCfgKey: 2,
   559  					},
   560  				},
   561  			},
   562  			want: &BackOffPolicy{
   563  				BackOffType: NoneBackOffType,
   564  				CfgItems: map[BackOffCfgKey]float64{
   565  					MinMSBackOffCfgKey: 1,
   566  					MaxMSBackOffCfgKey: 2,
   567  				},
   568  			},
   569  		},
   570  	}
   571  	for _, tt := range tests {
   572  		t.Run(tt.name, func(t *testing.T) {
   573  			if got := tt.fields.p.DeepCopy(); !reflect.DeepEqual(got, tt.want) {
   574  				t.Errorf("DeepCopy() = %v, want %v", got, tt.want)
   575  			}
   576  		})
   577  	}
   578  }
   579  
   580  func TestBackupPolicy_DeepCopy(t *testing.T) {
   581  	type fields struct {
   582  		p *BackupPolicy
   583  	}
   584  	tests := []struct {
   585  		name   string
   586  		fields fields
   587  		want   *BackupPolicy
   588  	}{
   589  		{
   590  			name: "nil_policy",
   591  			fields: fields{
   592  				p: nil,
   593  			},
   594  			want: nil,
   595  		},
   596  		{
   597  			name: "empty_policy",
   598  			fields: fields{
   599  				p: &BackupPolicy{
   600  					RetryDelayMS:  0,
   601  					StopPolicy:    StopPolicy{},
   602  					RetrySameNode: false,
   603  				},
   604  			},
   605  			want: &BackupPolicy{
   606  				RetryDelayMS:  0,
   607  				StopPolicy:    StopPolicy{},
   608  				RetrySameNode: false,
   609  			},
   610  		},
   611  		{
   612  			name: "not_empty_policy",
   613  			fields: fields{
   614  				p: &BackupPolicy{
   615  					RetryDelayMS:  1,
   616  					StopPolicy:    StopPolicy{},
   617  					RetrySameNode: true,
   618  				},
   619  			},
   620  			want: &BackupPolicy{
   621  				RetryDelayMS:  1,
   622  				StopPolicy:    StopPolicy{},
   623  				RetrySameNode: true,
   624  			},
   625  		},
   626  	}
   627  	for _, tt := range tests {
   628  		t.Run(tt.name, func(t *testing.T) {
   629  			p := tt.fields.p
   630  			if got := p.DeepCopy(); !reflect.DeepEqual(got, tt.want) {
   631  				t.Errorf("DeepCopy() = %v, want %v", got, tt.want)
   632  			}
   633  		})
   634  	}
   635  }
   636  
   637  func TestFailurePolicy_DeepCopy(t *testing.T) {
   638  	type fields struct {
   639  		p *FailurePolicy
   640  	}
   641  	tests := []struct {
   642  		name   string
   643  		fields fields
   644  		want   *FailurePolicy
   645  	}{
   646  		{
   647  			name: "nil_policy",
   648  			fields: fields{
   649  				p: nil,
   650  			},
   651  			want: nil,
   652  		},
   653  		{
   654  			name: "empty_policy",
   655  			fields: fields{
   656  				p: &FailurePolicy{},
   657  			},
   658  			want: &FailurePolicy{},
   659  		},
   660  		{
   661  			name: "not_empty_policy",
   662  			fields: fields{
   663  				p: &FailurePolicy{
   664  					StopPolicy:        StopPolicy{},
   665  					BackOffPolicy:     &BackOffPolicy{},
   666  					RetrySameNode:     true,
   667  					ShouldResultRetry: &ShouldResultRetry{},
   668  					Extra:             "{}",
   669  				},
   670  			},
   671  			want: &FailurePolicy{
   672  				StopPolicy:        StopPolicy{},
   673  				BackOffPolicy:     &BackOffPolicy{},
   674  				RetrySameNode:     true,
   675  				ShouldResultRetry: &ShouldResultRetry{},
   676  				Extra:             "{}",
   677  			},
   678  		},
   679  	}
   680  	for _, tt := range tests {
   681  		t.Run(tt.name, func(t *testing.T) {
   682  			if got := tt.fields.p.DeepCopy(); !reflect.DeepEqual(got, tt.want) {
   683  				t.Errorf("DeepCopy() = %v, want %v", got, tt.want)
   684  			}
   685  		})
   686  	}
   687  }
   688  
   689  func TestPolicy_DeepCopy(t *testing.T) {
   690  	type fields struct {
   691  		p *Policy
   692  	}
   693  	tests := []struct {
   694  		name   string
   695  		fields fields
   696  		want   *Policy
   697  	}{
   698  		{
   699  			name: "nil_policy",
   700  			fields: fields{
   701  				p: nil,
   702  			},
   703  			want: nil,
   704  		},
   705  		{
   706  			name: "empty_policy",
   707  			fields: fields{
   708  				p: &Policy{},
   709  			},
   710  			want: &Policy{},
   711  		},
   712  		{
   713  			name: "not_empty_policy",
   714  			fields: fields{
   715  				p: &Policy{
   716  					Enable: true,
   717  					Type:   BackupType,
   718  					FailurePolicy: &FailurePolicy{
   719  						RetrySameNode: true,
   720  						Extra:         "{}",
   721  					},
   722  					BackupPolicy: &BackupPolicy{
   723  						RetryDelayMS: 1000,
   724  					},
   725  				},
   726  			},
   727  			want: &Policy{
   728  				Enable: true,
   729  				Type:   BackupType,
   730  				FailurePolicy: &FailurePolicy{
   731  					RetrySameNode: true,
   732  					Extra:         "{}",
   733  				},
   734  				BackupPolicy: &BackupPolicy{
   735  					RetryDelayMS: 1000,
   736  				},
   737  			},
   738  		},
   739  	}
   740  	for _, tt := range tests {
   741  		t.Run(tt.name, func(t *testing.T) {
   742  			if got := tt.fields.p.DeepCopy(); !reflect.DeepEqual(got, tt.want) {
   743  				t.Errorf("DeepCopy() = %v, want %v", got, tt.want)
   744  			}
   745  		})
   746  	}
   747  }