Skip to content

test(adminapi): add complete integration test suite for KMS and Public Keys#53

Open
hmffa wants to merge 17 commits intogo-oidfed:lighthouse-20from
hmffa:tests/admin-api-keys
Open

test(adminapi): add complete integration test suite for KMS and Public Keys#53
hmffa wants to merge 17 commits intogo-oidfed:lighthouse-20from
hmffa:tests/admin-api-keys

Conversation

@hmffa
Copy link

@hmffa hmffa commented Mar 2, 2026

This PR introduces a complete, production-grade integration test suite for the api/adminapi/keys.go endpoints.

🛠️ Key Changes:

  • Test Setup: Added a temporary SQLite database and Fiber app setup to test the endpoints against a real database instance (DBPublicKeyStorage).
  • KMS Mocking: Created 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 /keys
  • POST /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 /alg
  • PUT /rsa-key-len
  • GET /rotation
  • PUT /rotation
  • PATCH /rotation
  • POST /rotate

The test suite also includes exhaustive "sad path" testing for malformed JSON and 400/404 states.

hmffa added 12 commits February 25, 2026 17:04
- 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.
Copilot AI review requested due to automatic review settings March 2, 2026 21:33
@deepsource-io
Copy link
Contributor

deepsource-io bot commented Mar 2, 2026

DeepSource Code Review

We reviewed changes in 6a9b497...31f54c0 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
Go Mar 4, 2026 1:41p.m. Review ↗

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.go covering 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.

registerKeys(app, km, store.KeyValue())

initialConfig := kms.KeyRotationConfig{Enabled: true}
_ = storage.SetKeyRotation(store.KeyValue(), initialConfig)
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
_ = storage.SetKeyRotation(store.KeyValue(), initialConfig)
if err := storage.SetKeyRotation(store.KeyValue(), initialConfig); err != nil {
t.Fatalf("failed to set key rotation config: %v", err)
}

Copilot uses AI. Check for mistakes.
Comment on lines +1001 to +1003
// Set initial config
_ = storage.SetKeyRotation(store.KeyValue(), kms.KeyRotationConfig{Enabled: false})

Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +1030 to +1032

_ = storage.SetKeyRotation(store.KeyValue(), kms.KeyRotationConfig{Enabled: true})

Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error return from storage.SetKeyRotation is ignored here. This setup step should be asserted so later expectations about the PATCH behavior are trustworthy.

Copilot uses AI. Check for mistakes.
Comment on lines +60 to +69
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,
})
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +534 to +535
_ = km.APIManagedPKs.Load()
_ = km.KMSManagedPKs.Load()
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
_ = 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)
}

Copilot uses AI. Check for mistakes.
Comment on lines +568 to +569
_ = km.APIManagedPKs.Load()
_ = km.KMSManagedPKs.Load()
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +598 to +599
_ = km.APIManagedPKs.Load()
_ = km.KMSManagedPKs.Load()
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants