diff --git a/pkg/test/utils/kubernetes.go b/pkg/test/utils/kubernetes.go index 5f71c607..de36005e 100644 --- a/pkg/test/utils/kubernetes.go +++ b/pkg/test/utils/kubernetes.go @@ -102,12 +102,26 @@ func Retry(ctx context.Context, fn func(context.Context) error, errValidationFun errCh := make(chan error) doneCh := make(chan struct{}) + if fn == nil { + log.Println("retry func is nil and will be ignored") + return nil + } + // do { } while (err != nil): https://stackoverflow.com/a/32844744/10892393 for ok := true; ok; ok = lastErr != nil { // run the function in a goroutine and close it once it is finished so that // we can use select to wait for both the function return and the context deadline. go func() { + // if the func we are calling panics, clean up and call it done + // the common case is when a shared reference, like a client, is nil and is called in the function + defer func() { + if r := recover(); r != nil { + //log.Println("retry func has panicked and will be ignored") + errCh <- errors.New("func passed to retry panicked. expected if testsuite is shutting down") + } + }() + if err := fn(ctx); err != nil { errCh <- err } else { diff --git a/pkg/test/utils/kubernetes_test.go b/pkg/test/utils/kubernetes_test.go index 69fca27f..1760c0fb 100644 --- a/pkg/test/utils/kubernetes_test.go +++ b/pkg/test/utils/kubernetes_test.go @@ -118,6 +118,24 @@ func TestRetryWithUnexpectedError(t *testing.T) { assert.Equal(t, 1, index) } +func TestRetryWithNil(t *testing.T) { + assert.Equal(t, nil, Retry(context.TODO(), nil, IsJSONSyntaxError)) +} + +func TestRetryWithNilFromFn(t *testing.T) { + assert.Equal(t, nil, Retry(context.TODO(), func(ctx context.Context) error { + return nil + }, IsJSONSyntaxError)) +} + +func TestRetryWithNilInFn(t *testing.T) { + client := RetryClient{} + var list runtime.Object + assert.Error(t, Retry(context.TODO(), func(ctx context.Context) error { + return client.Client.List(ctx, list) + }, IsJSONSyntaxError)) +} + func TestRetryWithTimeout(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel()