...

Source file src/github.com/google/s2a-go/retry/retry_test.go

Documentation: github.com/google/s2a-go/retry

     1  /*
     2   *
     3   * Copyright 2023 Google LLC
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     https://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package retry
    20  
    21  import (
    22  	"context"
    23  	"errors"
    24  	"testing"
    25  	"time"
    26  )
    27  
    28  var errTest error = errors.New("test error")
    29  
    30  type constantBackoff struct{}
    31  
    32  func (b constantBackoff) Pause() time.Duration { return 100 }
    33  
    34  func TestS2ARetryer(t *testing.T) {
    35  	tests := []struct {
    36  		name            string
    37  		err             error
    38  		wantDelay       time.Duration
    39  		wantShouldRetry bool
    40  	}{
    41  		{
    42  			name:            "retry on err",
    43  			err:             errTest,
    44  			wantDelay:       100,
    45  			wantShouldRetry: true,
    46  		},
    47  		{
    48  			name:            "don't retry if err is nil",
    49  			err:             nil,
    50  			wantDelay:       0,
    51  			wantShouldRetry: false,
    52  		},
    53  	}
    54  
    55  	for _, tc := range tests {
    56  		t.Run(tc.name, func(t *testing.T) {
    57  			retryer := S2ARetryer{bo: constantBackoff{}}
    58  			delay, shouldRetry := retryer.Retry(tc.err)
    59  			if delay != tc.wantDelay {
    60  				t.Fatalf("retryer.Retry(%v) = %v, want %v", tc.err, delay, tc.wantDelay)
    61  			}
    62  			if shouldRetry != tc.wantShouldRetry {
    63  				t.Fatalf("retryer.Retry(%v) = %v, want %v", tc.err, shouldRetry, tc.wantShouldRetry)
    64  			}
    65  		})
    66  	}
    67  }
    68  
    69  func TestS2ARetryerAttempts(t *testing.T) {
    70  	retryer := S2ARetryer{bo: constantBackoff{}}
    71  	for i := 1; i <= 5; i++ {
    72  		_, shouldRetry := retryer.Retry(errTest)
    73  		if !shouldRetry {
    74  			t.Fatalf("retryer.Retry(errTest) = false, want true")
    75  		}
    76  	}
    77  	_, shouldRetry := retryer.Retry(errTest)
    78  	if shouldRetry {
    79  		t.Fatal("an error should only be retried 5 times")
    80  	}
    81  }
    82  
    83  func TestDefaultBackoff(t *testing.T) {
    84  	bo := defaultBackoff{
    85  		cur: 100 * time.Millisecond,
    86  		max: 30 * time.Second,
    87  		mul: 2,
    88  	}
    89  	pauseOne := bo.Pause()
    90  	pauseTwo := bo.Pause()
    91  	if pauseOne > 100*time.Millisecond {
    92  		t.Fatal("first backoff should be less than 100 milli seconds")
    93  	}
    94  	if pauseTwo > 2*100*time.Millisecond {
    95  		t.Fatal("second backoff should be less than 200 milli seconds")
    96  	}
    97  }
    98  
    99  func TestSuccessAfterRetry(t *testing.T) {
   100  	oldRetry := NewRetryer
   101  	defer func() { NewRetryer = oldRetry }()
   102  	testRetryer := NewRetryer()
   103  	NewRetryer = func() *S2ARetryer {
   104  		return testRetryer
   105  	}
   106  
   107  	cnt := 1
   108  	f := func() error {
   109  		if cnt == 1 {
   110  			cnt++
   111  			return errTest
   112  		}
   113  		return nil
   114  	}
   115  	if testRetryer.Attempts() != 0 {
   116  		t.Fatal("before execution, retry attempt count should be 0")
   117  	}
   118  
   119  	Run(context.Background(), f)
   120  
   121  	if testRetryer.Attempts() != 1 {
   122  		t.Fatal("execution should've succeeded after 1 retry")
   123  	}
   124  }
   125  

View as plain text