github.com/blend/go-sdk@v1.20220411.3/retry/retry_test.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package retry
     9  
    10  import (
    11  	"context"
    12  	"fmt"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/blend/go-sdk/assert"
    17  )
    18  
    19  func Test_Retry(t *testing.T) {
    20  	its := assert.New(t)
    21  
    22  	passedArgs := make(chan interface{}, 5)
    23  	results := make(chan interface{}, 5)
    24  
    25  	var internalAttempt int
    26  	action := ActionerFunc(func(ctx context.Context, args interface{}) (interface{}, error) {
    27  		defer func() { internalAttempt++ }()
    28  		passedArgs <- args
    29  		if internalAttempt < 4 {
    30  			err := fmt.Errorf("attempt %d", internalAttempt)
    31  			results <- err
    32  			return nil, err
    33  		}
    34  		result := "OK!"
    35  		results <- result
    36  		return result, nil
    37  	})
    38  
    39  	result, err := New(OptConstantDelay(time.Millisecond)).Intercept(action).Action(its.Background(), "args")
    40  	its.Nil(err)
    41  	its.Equal("OK!", result)
    42  	its.Len(passedArgs, 5)
    43  	its.Equal("args", <-passedArgs)
    44  	its.Equal("args", <-passedArgs)
    45  	its.Equal("args", <-passedArgs)
    46  	its.Equal("args", <-passedArgs)
    47  	its.Equal("args", <-passedArgs)
    48  	its.Len(results, 5)
    49  	its.Equal(fmt.Errorf("attempt 0"), <-results)
    50  	its.Equal(fmt.Errorf("attempt 1"), <-results)
    51  	its.Equal(fmt.Errorf("attempt 2"), <-results)
    52  	its.Equal(fmt.Errorf("attempt 3"), <-results)
    53  	its.Equal("OK!", <-results)
    54  }
    55  
    56  func Test_Retry_ShouldRetryProvider(t *testing.T) {
    57  	its := assert.New(t)
    58  
    59  	passedArgs := make(chan interface{}, 5)
    60  	results := make(chan interface{}, 5)
    61  
    62  	var internalAttempt int
    63  	action := ActionerFunc(func(ctx context.Context, args interface{}) (interface{}, error) {
    64  		defer func() { internalAttempt++ }()
    65  		passedArgs <- args
    66  
    67  		if internalAttempt < 4 {
    68  			err := fmt.Errorf("attempt %d", internalAttempt)
    69  			results <- err
    70  			return nil, err
    71  		}
    72  		result := "OK!"
    73  		results <- result
    74  		return result, nil
    75  	})
    76  
    77  	result, err := New(
    78  		OptConstantDelay(time.Millisecond),
    79  		OptShouldRetryProvider(func(err error) bool {
    80  			return err.Error() != "attempt 3"
    81  		}),
    82  	).Intercept(action).Action(its.Background(), "args")
    83  	its.NotNil(err)
    84  	its.Empty(result)
    85  	its.Len(passedArgs, 4)
    86  	its.Equal("args", <-passedArgs)
    87  	its.Equal("args", <-passedArgs)
    88  	its.Equal("args", <-passedArgs)
    89  	its.Equal("args", <-passedArgs)
    90  	its.Len(results, 4)
    91  	its.Equal(fmt.Errorf("attempt 0"), <-results)
    92  	its.Equal(fmt.Errorf("attempt 1"), <-results)
    93  	its.Equal(fmt.Errorf("attempt 2"), <-results)
    94  	its.Equal(fmt.Errorf("attempt 3"), <-results)
    95  }