From d5f2c0201ed37f5a8716044b5395eb9c980fa4ad Mon Sep 17 00:00:00 2001 From: James Rasell Date: Mon, 1 Sep 2025 07:32:40 +0100 Subject: [PATCH] e2e: Wait for keyring before starting client intro client agents. (#26660) Ensuring the keyring is ready before starting the Nomad client in the client intro e2e test speeds up execution. This is because the client does not have to wait to retry failed registrations due to the keyring not being ready. --- e2e/client_intro/client_intro_test.go | 49 ++++++++++++++++++++------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/e2e/client_intro/client_intro_test.go b/e2e/client_intro/client_intro_test.go index 89ff5fb18..6fa286bf1 100644 --- a/e2e/client_intro/client_intro_test.go +++ b/e2e/client_intro/client_intro_test.go @@ -69,6 +69,14 @@ func testClientIntroEnforcementWarn(t *testing.T) { must.NoError(t, testServer.Start()) t.Cleanup(func() { _ = testServer.Destroy() }) + // Create a Nomad API client to talk to the server. Do it here, so we only + // do this once. + nomadClient, err := testServer.Client() + must.NoError(t, err) + must.NotNil(t, nomadClient) + + waitForKeyring(t, nomadClient) + clientCallbackFn := func(c *execagent.AgentTemplateVars) { c.AgentName = "client-intro-" + uuid.Short() c.LogLevel = hclog.Warn.String() @@ -91,12 +99,6 @@ func testClientIntroEnforcementWarn(t *testing.T) { must.NoError(t, testClient.Start()) t.Cleanup(func() { _ = testClient.Destroy() }) - // Create a Nomad API client to talk to the server. Do it here, so we only - // do this once. - nomadClient, err := testServer.Client() - must.NoError(t, err) - must.NotNil(t, nomadClient) - // Wait for the client to show up in the server's node list. We use the node // name as the identifier to check for since it's unique. must.Wait(t, wait.InitialSuccess( @@ -171,7 +173,15 @@ server { must.NoError(t, testServer.Start()) t.Cleanup(func() { _ = testServer.Destroy() }) - // + // Create a Nomad API client to talk to the server. Do it here, so we only + // do this once. + nomadClient, err := testServer.Client() + must.NoError(t, err) + must.NotNil(t, nomadClient) + + waitForKeyring(t, nomadClient) + + // Generate a unique name for the client node we will be creating. clientAgentName := "client-intro-" + uuid.Short() clientCallbackFn := func(c *execagent.AgentTemplateVars) { @@ -240,12 +250,6 @@ server { }, ) - // Get an API client, so we can create the introduction token that - // the client will use. - nomadClient, err := testServer.Client() - must.NoError(t, err) - must.NotNil(t, nomadClient) - resp, _, err := nomadClient.ACLIdentity().CreateClientIntroductionToken( &api.ACLIdentityClientIntroductionTokenRequest{ NodeName: clientAgentName, @@ -295,6 +299,25 @@ server { )) } +// waitForKeyring blocks until the keyring is initialized. If the keyring is not +// initialized within the timeout period, the test will fail. +func waitForKeyring(t *testing.T, nomadClient *api.Client) { + must.Wait(t, wait.InitialSuccess( + wait.ErrorFunc(func() error { + keyList, _, err := nomadClient.Keyring().List(nil) + if err != nil { + return err + } + if len(keyList) == 0 { + return errors.New("no keys found") + } + return nil + }), + wait.Timeout(10*time.Second), + wait.Gap(500*time.Millisecond), + )) +} + // caputreLogger is a simple logger that captures log lines in memory and also // writes them to stderr. It allows us to caputre output and inspect it for // testing.