...

Source file src/github.com/aws/smithy-go/waiter/waiter_test.go

Documentation: github.com/aws/smithy-go/waiter

     1  package waiter
     2  
     3  import (
     4  	mathrand "math/rand"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/aws/smithy-go/rand"
    10  )
    11  
    12  func TestComputeDelay(t *testing.T) {
    13  	cases := map[string]struct {
    14  		totalAttempts       int64
    15  		minDelay            time.Duration
    16  		maxDelay            time.Duration
    17  		maxWaitTime         time.Duration
    18  		expectedMaxDelays   []time.Duration
    19  		expectedError       string
    20  		expectedMinAttempts int
    21  	}{
    22  		"standard": {
    23  			totalAttempts:       8,
    24  			minDelay:            2 * time.Second,
    25  			maxDelay:            120 * time.Second,
    26  			maxWaitTime:         300 * time.Second,
    27  			expectedMaxDelays:   []time.Duration{2, 4, 8, 16, 32, 64, 120, 120},
    28  			expectedMinAttempts: 8,
    29  		},
    30  		"zero minDelay": {
    31  			totalAttempts: 3,
    32  			minDelay:      0,
    33  			maxDelay:      120 * time.Second,
    34  			maxWaitTime:   300 * time.Second,
    35  			expectedError: "minDelay must be greater than zero",
    36  		},
    37  		"zero maxDelay": {
    38  			totalAttempts: 3,
    39  			minDelay:      10 * time.Second,
    40  			maxDelay:      0,
    41  			maxWaitTime:   300 * time.Second,
    42  			expectedError: "maxDelay must be greater than zero",
    43  		},
    44  		"zero remaining time": {
    45  			totalAttempts:       3,
    46  			minDelay:            10 * time.Second,
    47  			maxDelay:            20 * time.Second,
    48  			maxWaitTime:         0,
    49  			expectedMaxDelays:   []time.Duration{0},
    50  			expectedMinAttempts: 1,
    51  		},
    52  		"max wait time is less than min delay": {
    53  			totalAttempts:       3,
    54  			minDelay:            10 * time.Second,
    55  			maxDelay:            20 * time.Second,
    56  			maxWaitTime:         5 * time.Second,
    57  			expectedMaxDelays:   []time.Duration{0},
    58  			expectedMinAttempts: 1,
    59  		},
    60  		"large minDelay": {
    61  			totalAttempts:       80,
    62  			minDelay:            150 * time.Minute,
    63  			maxDelay:            200 * time.Minute,
    64  			maxWaitTime:         250 * time.Minute,
    65  			expectedMinAttempts: 1,
    66  		},
    67  		"large maxDelay": {
    68  			totalAttempts:       80,
    69  			minDelay:            15 * time.Minute,
    70  			maxDelay:            2000 * time.Minute,
    71  			maxWaitTime:         250 * time.Minute,
    72  			expectedMinAttempts: 5,
    73  		},
    74  	}
    75  
    76  	for name, c := range cases {
    77  		t.Run(name, func(t *testing.T) {
    78  			// mock smithy-go rand/#Reader
    79  			r := rand.Reader
    80  			defer func() {
    81  				rand.Reader = r
    82  			}()
    83  			rand.Reader = mathrand.New(mathrand.NewSource(1))
    84  
    85  			// mock waiter call
    86  			delays, err := mockwait(c.totalAttempts, c.minDelay, c.maxDelay, c.maxWaitTime)
    87  
    88  			if len(c.expectedError) != 0 {
    89  				if err == nil {
    90  					t.Fatalf("expected error, got none")
    91  				}
    92  				if e, a := c.expectedError, err.Error(); !strings.Contains(a, e) {
    93  					t.Fatalf("expected error %v, got %v instead", e, a)
    94  				}
    95  			} else if err != nil {
    96  				t.Fatalf("expected no error, got %v", err)
    97  			}
    98  
    99  			if e, a := c.expectedMinAttempts, len(delays); e > a {
   100  				t.Logf("%v", delays)
   101  				t.Fatalf("expected minimum attempts to be %v, got %v", e, a)
   102  			}
   103  
   104  			for i, expectedDelay := range c.expectedMaxDelays {
   105  				if e, a := expectedDelay*time.Second, delays[i]; e < a {
   106  					t.Fatalf("attempt %d : expected delay to be less than %v, got %v", i+1, e, a)
   107  				}
   108  
   109  				if e, a := c.minDelay, delays[i]; e > a && c.maxWaitTime > c.minDelay {
   110  					t.Fatalf("attempt %d : expected delay to be more than %v, got %v", i+1, e, a)
   111  				}
   112  			}
   113  			t.Logf("delays : %v", delays)
   114  		})
   115  	}
   116  }
   117  
   118  func mockwait(maxAttempts int64, minDelay, maxDelay, maxWaitTime time.Duration) ([]time.Duration, error) {
   119  	delays := make([]time.Duration, 0)
   120  	remainingTime := maxWaitTime
   121  	var attempt int64
   122  
   123  	for {
   124  		attempt++
   125  
   126  		if maxAttempts < attempt {
   127  			break
   128  		}
   129  
   130  		delay, err := ComputeDelay(attempt, minDelay, maxDelay, remainingTime)
   131  		if err != nil {
   132  			return delays, err
   133  		}
   134  
   135  		delays = append(delays, delay)
   136  
   137  		remainingTime -= delay
   138  		if remainingTime < minDelay {
   139  			break
   140  		}
   141  	}
   142  
   143  	return delays, nil
   144  }
   145  

View as plain text