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 <akeesler@vmware.com>
Co-authored-by: Margo Crawford <margaretc@vmware.com>
Co-authored-by: Monis Khan <i@monis.app>
This commit is contained in:
Andrew Keesler 2021-01-14 10:17:46 -05:00
parent a0546942b8
commit 8a916ce8ae
No known key found for this signature in database
GPG Key ID: 27CE0444346F9413
2 changed files with 30 additions and 5 deletions

View File

@ -258,16 +258,15 @@ func hasOwnerRef(t *testing.T, obj metav1.Object, ref metav1.OwnerReference) {
func isEventuallyDeleted(t *testing.T, f func() error) { func isEventuallyDeleted(t *testing.T, f func() error) {
t.Helper() t.Helper()
require.Eventually(t, func() bool { library.RequireEventuallyWithoutError(t, func() (bool, error) {
err := f() err := f()
switch { switch {
case err == nil: case err == nil:
return false return false, nil
case errors.IsNotFound(err): case errors.IsNotFound(err):
return true return true, nil
default: default:
require.NoError(t, err) return false, err
return false
} }
}, time.Minute, time.Second) }, time.Minute, time.Second)
} }

View File

@ -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...)
}