test(adminapi): add complete integration test suite for KMS and Public Keys#53
test(adminapi): add complete integration test suite for KMS and Public Keys#53hmffa wants to merge 17 commits intogo-oidfed:lighthouse-20from
Conversation
…ys endpoint to update public key expiration
…on before rotation
…e key rotation config
…ST /kms/rotate endpoints
…key rotation configuration
- Refactored repetitive setup code into reusable test helpers (`setupPublicKeyApp`, `doRequest`, etc.) using `t.Helper()`. - Organized tests into logical sub-tests using `t.Run` for better isolation and cleaner test output. - Added comprehensive "sad path" coverage including invalid JSON bodies, KID mismatches, and 404/400 error states. - Improved KMS mocking by using struct embedding to safely test pending algorithm states. - Extracted large RSA key payload strings into reusable constants to adhere to DRY principles and improve readability.
|
|
Overall Grade |
Security Reliability Complexity Hygiene |
Code Review Summary
| Analyzer | Status | Updated (UTC) | Details |
|---|---|---|---|
| Go | Mar 4, 2026 1:41p.m. | Review ↗ |
There was a problem hiding this comment.
Pull request overview
Adds an integration-style test suite for the Admin API key-management endpoints, exercising public key CRUD/rotation, JWKS publishing behavior, and KMS management/rotation endpoints against a real temporary SQLite-backed storage.
Changes:
- Introduces a new
api/adminapi/keys_test.gocovering 13/13 key + KMS endpoints with happy-path and sad-path cases. - Adds test helpers for building a Fiber app, issuing requests, and seeding public keys.
- Adds lightweight KMS mocks to drive KMS-related handlers (pending changes, rotation config, alg/rsa-len updates, rotate-all).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
api/adminapi/keys_test.go
Outdated
| registerKeys(app, km, store.KeyValue()) | ||
|
|
||
| initialConfig := kms.KeyRotationConfig{Enabled: true} | ||
| _ = storage.SetKeyRotation(store.KeyValue(), initialConfig) |
There was a problem hiding this comment.
The error return from storage.SetKeyRotation is ignored. If persisting the rotation config fails, the test should fail immediately; otherwise later assertions can become misleading.
| _ = storage.SetKeyRotation(store.KeyValue(), initialConfig) | |
| if err := storage.SetKeyRotation(store.KeyValue(), initialConfig); err != nil { | |
| t.Fatalf("failed to set key rotation config: %v", err) | |
| } |
| // Set initial config | ||
| _ = storage.SetKeyRotation(store.KeyValue(), kms.KeyRotationConfig{Enabled: false}) | ||
|
|
There was a problem hiding this comment.
The error return from storage.SetKeyRotation is ignored when setting up the initial state. Please check this error so the test fails with the correct cause if KV persistence breaks.
|
|
||
| _ = storage.SetKeyRotation(store.KeyValue(), kms.KeyRotationConfig{Enabled: true}) | ||
|
|
There was a problem hiding this comment.
The error return from storage.SetKeyRotation is ignored here. This setup step should be asserted so later expectations about the PATCH behavior are trustworthy.
| tempDir, err := os.MkdirTemp("", "lighthouse-test-*") | ||
| if err != nil { | ||
| t.Fatal(err) | ||
| } | ||
| t.Cleanup(func() { os.RemoveAll(tempDir) }) | ||
|
|
||
| store, err := storage.NewStorage(storage.Config{ | ||
| Driver: storage.DriverSQLite, | ||
| DataDir: tempDir, | ||
| }) |
There was a problem hiding this comment.
newTestStorage creates a file-backed SQLite DB but never closes the underlying sql.DB connection; on some platforms (notably Windows) this can keep lighthouse.db locked and make the temp dir cleanup unreliable, and across many subtests it can also accumulate open file handles. Consider switching the SQLite DSN to an in-memory database for tests (e.g. a shared in-memory DSN) or exposing/using a storage Close method to close the connection in t.Cleanup before removing the temp directory.
api/adminapi/keys_test.go
Outdated
| _ = km.APIManagedPKs.Load() | ||
| _ = km.KMSManagedPKs.Load() |
There was a problem hiding this comment.
Errors from Load() are being ignored here. If table creation/migration fails, the test should fail immediately with a clear message rather than proceeding and failing later in less obvious ways.
| _ = km.APIManagedPKs.Load() | |
| _ = km.KMSManagedPKs.Load() | |
| if err := km.APIManagedPKs.Load(); err != nil { | |
| t.Fatalf("failed to load API-managed public keys: %v", err) | |
| } | |
| if err := km.KMSManagedPKs.Load(); err != nil { | |
| t.Fatalf("failed to load KMS-managed public keys: %v", err) | |
| } |
api/adminapi/keys_test.go
Outdated
| _ = km.APIManagedPKs.Load() | ||
| _ = km.KMSManagedPKs.Load() |
There was a problem hiding this comment.
Errors from Load() are ignored here. Please assert these calls succeed (e.g., if err := ...; err != nil { t.Fatalf(...) }) so the test fails with the real root cause.
api/adminapi/keys_test.go
Outdated
| _ = km.APIManagedPKs.Load() | ||
| _ = km.KMSManagedPKs.Load() |
There was a problem hiding this comment.
Errors from Load() are ignored here. These should be checked so the test doesn't silently proceed with an uninitialized storage and fail later with less actionable errors.
This PR introduces a complete, production-grade integration test suite for the
api/adminapi/keys.goendpoints.🛠️ Key Changes:
DBPublicKeyStorage).mockBasicKMS,mockFullKMS, and embedded structs to safely test all KMS interface interactions (including pending algorithm changes and rotation configs).✅ Endpoints Tested (13/13):
Public Key Management (
/entity-configuration/)GET /keysPOST /keys(with Kid validation and missing body checks)PUT /keys/:kid(Expiration updates)POST /keys/:kid(Key rotation)DELETE /keys/:kid(Hard delete and revocation)GET /jwks(Ensuring expired keys are omitted)KMS Management (
/kms/)GET /(Info and pending algorithms)PUT /algPUT /rsa-key-lenGET /rotationPUT /rotationPATCH /rotationPOST /rotateThe test suite also includes exhaustive "sad path" testing for malformed JSON and 400/404 states.