sigs.k8s.io/cluster-api-provider-aws@v1.5.5/pkg/cloud/services/wait/wait_test.go (about) 1 /* 2 Copyright 2019 The Kubernetes 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 wait_test 18 19 import ( 20 "errors" 21 "testing" 22 "time" 23 24 "github.com/aws/aws-sdk-go/aws/awserr" 25 "k8s.io/apimachinery/pkg/util/wait" 26 27 . "sigs.k8s.io/cluster-api-provider-aws/pkg/cloud/services/wait" 28 ) 29 30 var ( 31 errRetryable = awserr.New("retryable error", "", nil) 32 errNonRetryable = errors.New("non retryable error") 33 retryableErrorCodes = []string{"retryable error"} 34 ) 35 36 func TestWaitForWithRetryable(t *testing.T) { 37 backoff := wait.Backoff{ 38 Duration: 1 * time.Millisecond, 39 Factor: 0, 40 Jitter: 0, 41 Steps: 2, 42 Cap: 3 * time.Millisecond, 43 } 44 var firstIteration bool 45 46 tests := []struct { 47 name string 48 backoff wait.Backoff 49 condition wait.ConditionFunc 50 retryableErrors []string 51 expectedError error 52 }{ 53 { 54 name: "return nil", 55 backoff: backoff, 56 condition: func() (done bool, err error) { 57 return true, nil 58 }, 59 retryableErrors: retryableErrorCodes, 60 expectedError: nil, 61 }, 62 { 63 name: "returns timeout error", 64 backoff: backoff, 65 condition: func() (done bool, err error) { 66 return false, nil 67 }, 68 retryableErrors: retryableErrorCodes, 69 expectedError: wait.ErrWaitTimeout, 70 }, 71 { 72 name: "error occurred in conditionFunc, returns actual error", 73 backoff: backoff, 74 condition: func() (done bool, err error) { 75 return false, errNonRetryable 76 }, 77 retryableErrors: retryableErrorCodes, 78 expectedError: errNonRetryable, 79 }, 80 { 81 name: "timed out in retryable error, returns the retryable error", 82 backoff: backoff, 83 condition: func() (done bool, err error) { 84 return false, errRetryable 85 }, 86 retryableErrors: retryableErrorCodes, 87 expectedError: errRetryable, 88 }, 89 { 90 name: "retryable err at first, non-retryable err after that, returns latest error", 91 backoff: backoff, 92 condition: func() (done bool, err error) { 93 if firstIteration { 94 firstIteration = false 95 return false, errRetryable 96 } 97 firstIteration = false 98 return false, errNonRetryable 99 }, 100 retryableErrors: retryableErrorCodes, 101 expectedError: errNonRetryable, 102 }, 103 { 104 name: "retryable err at first, failure but no error after that, returns timeout error", 105 backoff: backoff, 106 condition: func() (done bool, err error) { 107 if firstIteration { 108 firstIteration = false 109 return false, errRetryable 110 } 111 return false, nil 112 }, 113 retryableErrors: retryableErrorCodes, 114 expectedError: wait.ErrWaitTimeout, 115 }, 116 { 117 name: "retryable error at first, success after that, returns nil", 118 backoff: backoff, 119 condition: func() (done bool, err error) { 120 if firstIteration { 121 firstIteration = false 122 return false, errRetryable 123 } 124 return true, nil 125 }, 126 retryableErrors: retryableErrorCodes, 127 expectedError: nil, 128 }, 129 } 130 for _, tt := range tests { 131 t.Run(tt.name, func(t *testing.T) { 132 firstIteration = true 133 134 err := WaitForWithRetryable(tt.backoff, tt.condition, tt.retryableErrors...) 135 136 var expected, actual string 137 if err != nil { 138 actual = err.Error() 139 } 140 if tt.expectedError != nil { 141 expected = tt.expectedError.Error() 142 } 143 144 if expected != actual { 145 t.Errorf("expected error: %v, got error: %v", expected, actual) 146 } 147 }) 148 } 149 }