Skip to content

Commit

Permalink
Merge pull request #2131 from smallstep/herman/unflake-request-id-int…
Browse files Browse the repository at this point in the history
…egration-test

Wait and retry connection to test CA server instead of failing (immediately)
  • Loading branch information
hslatman authored Jan 8, 2025
2 parents cda0eec + b3fb927 commit 47c08d5
Showing 1 changed file with 38 additions and 3 deletions.
41 changes: 38 additions & 3 deletions test/integration/requestid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ func reservePort(t *testing.T) (host, port string) {
}

func Test_reflectRequestID(t *testing.T) {
ctx := context.Background()

dir := t.TempDir()
m, err := minica.New(minica.WithName("Step E2E"))
require.NoError(t, err)
Expand Down Expand Up @@ -133,8 +135,11 @@ func Test_reflectRequestID(t *testing.T) {
require.ErrorIs(t, err, http.ErrServerClosed)
}()

// require the CA server to be available within 10 seconds,
// failing the test if it doesn't.
requireCAServerToBeAvailable(t, net.JoinHostPort("localhost", port), 10*time.Second)

// require OK health response as the baseline
ctx := context.Background()
healthResponse, err := caClient.HealthWithContext(ctx)
require.NoError(t, err)
if assert.NotNil(t, healthResponse) {
Expand Down Expand Up @@ -262,8 +267,8 @@ func newAuthorizingServer(t *testing.T, mca *minica.CA) *httptest.Server {

srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if assert.Equal(t, "signRequestID", r.Header.Get("X-Request-Id")) {
json.NewEncoder(w).Encode(struct{ Allow bool }{Allow: true})
w.WriteHeader(http.StatusOK)
err := json.NewEncoder(w).Encode(struct{ Allow bool }{Allow: true})
require.NoError(t, err)
return
}

Expand All @@ -287,3 +292,33 @@ func newAuthorizingServer(t *testing.T, mca *minica.CA) *httptest.Server {

return srv
}

// requireCAServerToBeAvailable tries to connect to address to check a server
// is available. It will retry the connection every ~100ms, until timeout occurs.
// If no connection can be made, the test is failed.
func requireCAServerToBeAvailable(t *testing.T, address string, timeout time.Duration) {
t.Helper()

ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

for !canConnect(ctx, address) {
select {
case <-ctx.Done():
require.FailNow(t, fmt.Sprintf("CA server failed to start at https://%s within %s", address, timeout.String()))
case <-time.After(100 * time.Millisecond):
}
}
}

func canConnect(ctx context.Context, address string) bool {
d := net.Dialer{}
conn, err := d.DialContext(ctx, "tcp", address)
if err != nil {
return false
}

conn.Close()

return true
}

0 comments on commit 47c08d5

Please sign in to comment.