From 8a916ce8ae87ac4cdbde2301d72841045fe1753d Mon Sep 17 00:00:00 2001 From: Andrew Keesler Date: Thu, 14 Jan 2021 10:17:46 -0500 Subject: [PATCH] test/integration: add test helper to avoid race conditions We were seeing a race in this test code since the require.NoError() and require.Eventually() would write to the same testing.T state on separate goroutines. Hopefully this helper function should cover the cases when we want to require.NoError() inside a require.Eventually() without causing a race. Signed-off-by: Andrew Keesler Co-authored-by: Margo Crawford Co-authored-by: Monis Khan --- test/integration/kubeclient_test.go | 9 ++++----- test/library/assertions.go | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 test/library/assertions.go diff --git a/test/integration/kubeclient_test.go b/test/integration/kubeclient_test.go index 4837604c..f65026ba 100644 --- a/test/integration/kubeclient_test.go +++ b/test/integration/kubeclient_test.go @@ -258,16 +258,15 @@ func hasOwnerRef(t *testing.T, obj metav1.Object, ref metav1.OwnerReference) { func isEventuallyDeleted(t *testing.T, f func() error) { t.Helper() - require.Eventually(t, func() bool { + library.RequireEventuallyWithoutError(t, func() (bool, error) { err := f() switch { case err == nil: - return false + return false, nil case errors.IsNotFound(err): - return true + return true, nil default: - require.NoError(t, err) - return false + return false, err } }, time.Minute, time.Second) } diff --git a/test/library/assertions.go b/test/library/assertions.go new file mode 100644 index 00000000..476e1ff3 --- /dev/null +++ b/test/library/assertions.go @@ -0,0 +1,26 @@ +// Copyright 2021 the Pinniped contributors. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package library + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/util/wait" +) + +// RequireEventuallyWithoutError is a wrapper around require.Eventually() that allows the caller to +// return an error from the condition function. If the condition function returns an error at any +// point, the assertion will immediately fail. +func RequireEventuallyWithoutError( + t *testing.T, + f func() (bool, error), + waitFor time.Duration, + tick time.Duration, + msgAndArgs ...interface{}, +) { + t.Helper() + require.NoError(t, wait.PollImmediate(tick, waitFor, f), msgAndArgs...) +}