Skip to content

Stabilize TestBootstrapClientServerRotation on slow machines - #2787

Open
lechedesnatada23 wants to merge 1 commit into
smallstep:masterfrom
lechedesnatada23:fix-flaky-bootstrap-rotation-test
Open

lechedesnatada23 wants to merge 1 commit into
smallstep:masterfrom
lechedesnatada23:fix-flaky-bootstrap-rotation-test

Conversation

@lechedesnatada23

@lechedesnatada23 lechedesnatada23 commented Sep 4, 2026 •

Copy link
Copy Markdown

Description

Test-only change to make TestBootstrapClientServerRotation stable on slow or loaded machines.

Root cause: the test issues certificates with a 5s lifetime (defaultTLSCertDuration in ca/testdata/rotate-ca-*.json), and TLSRenewer schedules each renewal at ~2/3 of the certificate lifetime (see #873), leaving only ~1.7–2.9s between the scheduled renewal and the expiry of the certificate in use. On a slow or loaded machine, a scheduling stall longer than that margin means the next mTLS handshake presents an already-expired certificate. Since /renew requires a valid client certificate (and the bootstrap token cannot be re-used to re-sign, as OTTs are protected against reuse), the client cannot recover and the test fails — which matches the log in #2713 (a handshake at 15:55:08 hitting a certificate that had just expired at 15:55:08). This is also the same class of instability that led to the test being skipped when CI=true. Fixing the underlying unrecoverable state would be a behavior change (e.g. a grace window on /renew), so it's left to the discussion in #2713/#873; this PR only stabilizes the test.

Change: increase the test certificate lifetime to 15s and the renewal waits from 5s to 12s. This grows the margin before expiry to ~5s while still guaranteeing at least one renewal of both the client and the server certificate on every phase (with 15s certificates, renewals happen every ~9–10s, and the final phase runs ~24s after the first reload).

No production behavior is modified. The only cost is the test itself going from ~21s to ~40s, which only affects local runs (in this repository's CI the test is skipped).

Validation

  • go test ./ca/ -run TestBootstrapClientServerRotation -count=3 passes 3/3 with the machine under full CPU saturation (4 busy loops on 4 cores), ~39.5s per run.
  • go test -short -count=1 ./ca/... passes.
  • golangci-lint run with the project config reports 0 issues; gofmt is clean.

Fixes #2713


Transparency note: this contribution was prepared with AI assistance and validated with the commands above.

The test issues certificates with a 5s lifetime and TLSRenewer
schedules each renewal at ~2/3 of the certificate lifetime, which
leaves only ~1-2s of margin between a renewal and the expiry of
the certificate in use. On slow or loaded machines a scheduling
stall longer than this margin makes the next mTLS handshake
present an already-expired certificate; because /renew requires a
valid client certificate, the client cannot recover and the test
fails (see smallstep#873).

Increase the test certificate lifetime to 15s and the renewal
waits to 12s. This grows the margin to ~5s while still
guaranteeing at least one renewal of both the client and the
server certificate on every test phase. Test-only change; no
production behavior is modified.

Fixes smallstep#2713
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs triage Waiting for discussion / prioritization by team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]:TestBootstrapClientServerRotation: certificate has expired or is not yet valid: current time 2026-06-15T15:55:08Z is after 2026-06-15T15:55:08Z

1 participant