github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/retry/retry_test.go (about)

     1  package retry
     2  
     3  import (
     4  	"net/http"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/pkg/errors"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  var defaultConfig = Config{
    13  	Attempts: 3,
    14  	Delay:    100 * time.Millisecond,
    15  }
    16  
    17  var mockedErr = errors.New("error")
    18  var mockedResp = &http.Response{StatusCode: http.StatusOK}
    19  
    20  func TestExecuteSuccessfulWhenNoErrors(t *testing.T) {
    21  	t.Run("should finish successfully when there are no errors when executing the http request", func(t *testing.T) {
    22  		retryExecutor := NewHTTPExecutor(&defaultConfig)
    23  
    24  		invocations := 0
    25  		resp, err := retryExecutor.Execute(func() (*http.Response, error) {
    26  			defer func() {
    27  				invocations++
    28  			}()
    29  
    30  			return mockedResp, nil
    31  		})
    32  
    33  		require.Equal(t, mockedResp, resp)
    34  		require.NoError(t, err)
    35  		require.Equal(t, 1, invocations)
    36  	})
    37  }
    38  
    39  func TestExecuteFailsInitiallyButSucceedsOnLastTryWithNoErrors(t *testing.T) {
    40  	t.Run("should finish successfully on the last retry attempt", func(t *testing.T) {
    41  		retryExecutor := NewHTTPExecutor(&defaultConfig)
    42  
    43  		invocations := 0
    44  		resp, err := retryExecutor.Execute(func() (*http.Response, error) {
    45  			defer func() {
    46  				invocations++
    47  			}()
    48  
    49  			if invocations != (int(defaultConfig.Attempts) - 1) {
    50  				return nil, mockedErr
    51  			}
    52  
    53  			return mockedResp, nil
    54  		})
    55  
    56  		require.Equal(t, mockedResp, resp)
    57  		require.NoError(t, err)
    58  		require.Equal(t, int(defaultConfig.Attempts), invocations)
    59  	})
    60  }
    61  
    62  func TestExecuteFailsWhenAllRetryAttemptsFinishWithFailureDueToError(t *testing.T) {
    63  	t.Run("should finish with failure when all retry attempts fail", func(t *testing.T) {
    64  		retryExecutor := NewHTTPExecutor(&defaultConfig)
    65  
    66  		invocations := 0
    67  		resp, err := retryExecutor.Execute(func() (*http.Response, error) {
    68  			defer func() {
    69  				invocations++
    70  			}()
    71  			return nil, mockedErr
    72  		})
    73  
    74  		require.Nil(t, resp)
    75  		require.Error(t, err)
    76  		require.Equal(t, int(defaultConfig.Attempts), invocations)
    77  	})
    78  }
    79  
    80  func TestExecuteFailsWhenAllRetryAttemptsFinishWithFailureDueToUnexpectedStatusCode(t *testing.T) {
    81  	t.Run("should finish with failure when all retry attempts fail", func(t *testing.T) {
    82  		retryExecutor := NewHTTPExecutor(&defaultConfig)
    83  
    84  		invocations := 0
    85  		mockedErrResp := http.Response{StatusCode: http.StatusInternalServerError}
    86  		resp, err := retryExecutor.Execute(func() (*http.Response, error) {
    87  			defer func() {
    88  				invocations++
    89  			}()
    90  			return &mockedErrResp, nil
    91  		})
    92  
    93  		require.Equal(t, &mockedErrResp, resp)
    94  		require.Error(t, err)
    95  		require.Equal(t, int(defaultConfig.Attempts), invocations)
    96  	})
    97  }