mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-06 13:36:54 +00:00
Improve our integration test "Eventually" assertions.
This fixes some rare test flakes caused by a data race inherent in the way we use `assert.Eventually()` with extra variables for followup assertions. This function is tricky to use correctly because it runs the passed function in a separate goroutine, and you have no guarantee that any shared variables are in a coherent state when the `assert.Eventually()` call returns. Even if you add manual mutexes, it's tricky to get the semantics right. This has been a recurring pain point and the cause of several test flakes. This change introduces a new `library.RequireEventually()` that works by internally constructing a per-loop `*require.Assertions` and running everything on a single goroutine (using `wait.PollImmediate()`). This makes it very easy to write eventual assertions. Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
@@ -9,9 +9,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||
|
||||
"go.pinniped.dev/internal/here"
|
||||
"go.pinniped.dev/pkg/conciergeclient"
|
||||
@@ -77,20 +75,17 @@ func TestClient(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
var resp *clientauthenticationv1beta1.ExecCredential
|
||||
assert.Eventually(t, func() bool {
|
||||
resp, err = client.ExchangeToken(ctx, env.TestUser.Token)
|
||||
return err == nil
|
||||
library.RequireEventually(t, func(requireEventually *require.Assertions) {
|
||||
resp, err := client.ExchangeToken(ctx, env.TestUser.Token)
|
||||
requireEventually.NoError(err)
|
||||
requireEventually.NotNil(resp.Status.ExpirationTimestamp)
|
||||
requireEventually.InDelta(5*time.Minute, time.Until(resp.Status.ExpirationTimestamp.Time), float64(time.Minute))
|
||||
|
||||
// Create a client using the certificate and key returned by the token exchange.
|
||||
validClient := library.NewClientsetWithCertAndKey(t, resp.Status.ClientCertificateData, resp.Status.ClientKeyData)
|
||||
|
||||
// Make a version request, which should succeed even without any authorization.
|
||||
_, err = validClient.Discovery().ServerVersion()
|
||||
requireEventually.NoError(err)
|
||||
}, 10*time.Second, 500*time.Millisecond)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, resp.Status.ExpirationTimestamp)
|
||||
require.InDelta(t, 5*time.Minute, time.Until(resp.Status.ExpirationTimestamp.Time), float64(time.Minute))
|
||||
|
||||
// Create a client using the certificate and key returned by the token exchange.
|
||||
validClient := library.NewClientsetWithCertAndKey(t, resp.Status.ClientCertificateData, resp.Status.ClientKeyData)
|
||||
|
||||
// Make a version request, which should succeed even without any authorization.
|
||||
_, err = validClient.Discovery().ServerVersion()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user