Skip to content

test(auth): add TC-13/28/29/42 and wrong-audience JWT subsystem tests - #58

Open
vkolodny wants to merge 2 commits into
dcm-project:mainfrom
vkolodny:test/tc28-tc29-tc13-tc42-audience-auth
Open

test(auth): add TC-13/28/29/42 and wrong-audience JWT subsystem tests#58
vkolodny wants to merge 2 commits into
dcm-project:mainfrom
vkolodny:test/tc28-tc29-tc13-tc42-audience-auth

Conversation

@vkolodny

Copy link
Copy Markdown
Contributor

Adds subsystem coverage for the remaining runnable authentication test plan gaps: no-JWTValidator fallback (TC-13), admin seeding idempotency across restart (TC-28) and with an empty DCM_ADMIN_SUBJECT (TC-29), Keycloak restart resilience (TC-42), and a wrong-audience JWT rejection test. TC-13/TC-29 run against dedicated compose services (control-plane-configc/-configa) sharing the main control-plane image.

Adds subsystem coverage for the remaining runnable authentication test
plan gaps: no-JWTValidator fallback (TC-13), admin seeding idempotency
across restart (TC-28) and with an empty DCM_ADMIN_SUBJECT (TC-29),
Keycloak restart resilience (TC-42), and a wrong-audience JWT rejection
test. TC-13/TC-29 run against dedicated compose services
(control-plane-configc/-configa) sharing the main control-plane image.

Signed-off-by: Vladislav Kolodny <vkolodny@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Expand auth subsystem tests for fallback, restarts, and JWT audience

🧪 Tests ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Covers authentication fallbacks, admin seeding, restart resilience, and JWT audience validation.
• Adds dedicated Compose variants and isolated database state for configuration-specific scenarios.
• Introduces Docker- and Podman-compatible restart and readiness helpers.
Diagram

graph TD
  T["Ginkgo suite"] --> M["Main control-plane"] --> K["Keycloak"]
  T --> C["Proxy-only plane"] --> D1[("Primary database")]
  T --> A["Auth-disabled plane"] --> D2[("Isolated database")]
  M --> D1
Loading
High-Level Assessment

Dedicated Compose services are appropriate because the tested authentication modes are startup-bound configurations and require simultaneous, deterministic endpoints. Reusing one image avoids redundant builds, while isolating TC-29 in a separate database prevents seeded state from invalidating its assertion; runtime reconfiguration or a shared database would weaken test fidelity and isolation.

Files changed (8) +511 / -0

Tests (7) +426 / -0
admin_seed_restart_test.goVerify admin seeding remains idempotent after restart +30/-0

Verify admin seeding remains idempotent after restart

• Adds TC-28 coverage that restarts the main control-plane container and verifies exactly one active admin actor remains with the expected username.

test/subsystem/auth/admin_seed_restart_test.go

container_helpers_test.goAdd portable container restart and readiness helpers +109/-0

Add portable container restart and readiness helpers

• Adds Docker/Podman engine detection, Compose-project-scoped container lookup, restart handling, and polling helpers for control-plane and Keycloak health. Closing idle HTTP connections prevents requests from reusing sockets tied to restarted processes.

test/subsystem/auth/container_helpers_test.go

keycloak_restart_test.goVerify authentication survives a Keycloak restart +40/-0

Verify authentication survives a Keycloak restart

• Adds TC-42 coverage that validates API access before and after bouncing Keycloak with newly issued tokens. The test explicitly covers restart resilience rather than signing-key rotation.

test/subsystem/auth/keycloak_restart_test.go

no_admin_subject_test.goVerify empty admin subject skips seeding +51/-0

Verify empty admin subject skips seeding

• Adds TC-29 assertions against the isolated Config A service, confirming no admin actor is created while API requests remain available with authentication disabled.

test/subsystem/auth/no_admin_subject_test.go

no_validator_test.goVerify proxy fallback without a JWT validator +60/-0

Verify proxy fallback without a JWT validator

• Adds TC-13 coverage for Config C, proving an invalid bearer token is ignored when proxy headers authenticate the request. Also confirms requests without any valid authentication remain unauthorized.

test/subsystem/auth/no_validator_test.go

suite_test.goInitialize alternate service endpoints and isolated database +19/-0

Initialize alternate service endpoints and isolated database

• Extends suite setup with configurable Config A and Config C URLs plus a second database connection. It retries isolated-database readiness and closes the additional connection during teardown.

test/subsystem/auth/suite_test.go

wrong_audience_test.goReject valid JWTs with an untrusted audience +117/-0

Reject valid JWTs with an untrusted audience

• Adds a wrong-audience JWT scenario by creating a temporary confidential Keycloak client without the dcm-api audience mapper. It obtains a signed client-credentials token, verifies rejection as an invalid bearer token, and deletes the temporary client afterward.

test/subsystem/auth/wrong_audience_test.go

Other (1) +85 / -0
docker-compose.yamlProvision dedicated auth configurations and isolated test database +85/-0

Provision dedicated auth configurations and isolated test database

• Names the reusable control-plane image and adds proxy-only Config C plus auth-disabled Config A services. Adds an idempotent database initializer and isolated database for empty-admin-subject coverage, while enabling PostgreSQL administrative access for database creation.

test/subsystem/auth/docker-compose.yaml

@qodo-code-review

qodo-code-review Bot commented Aug 26, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Concurrent admin seeding race ✓ Resolved 🐞 Bug ☼ Reliability
Description
control-plane-configc waits only for control-plane to start, so both processes can concurrently
seed their shared auth_test database. Their check-then-insert admin seeding can hit the unique
username or identity constraint, causing one control-plane process to exit and making subsystem
startup nondeterministic.
Code

test/subsystem/auth/docker-compose.yaml[R121-122]

+      control-plane:
+        condition: service_started
Evidence
Both services use auth_test. Application startup calls auth seeding and exits on any seed error;
seeding queries for an existing admin and then inserts without duplicate handling, while actor
usernames and identity provider/external-ID pairs are unique. Thus service_started permits the two
startup transactions to overlap and one can fail its insert.

test/subsystem/auth/docker-compose.yaml[101-122]
internal/app/run.go[194-205]
internal/auth/service/service.go[133-177]
internal/auth/service/service.go[181-201]
internal/auth/store/model/actor.go[17-23]
internal/auth/store/model/actor_identity.go[11-16]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new config-C service shares `auth_test` with the main control-plane but starts once that container is merely started. Both processes can then run non-concurrency-safe admin seeding simultaneously, and a unique-constraint failure terminates startup.

## Issue Context
The main service already has a healthcheck that becomes ready only after startup migrations and seeding complete. Make config C depend on that healthy state rather than `service_started`.

## Fix Focus Areas
- test/subsystem/auth/docker-compose.yaml[118-122]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 13/18, lines 511/200; both must reach the floor). Router rationale: This adds substantial, behavior-sensitive authentication subsystem tests and compose infrastructure across multiple independent paths, creating a dense set of easy-to-miss integration and test-isolation defects.

Grey Divider

Tip of the day
💡 Did you know, you can start a comment with 'qodo' or '@qodo' to chat about any finding

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread test/subsystem/auth/docker-compose.yaml Outdated
…figa

control-plane-configc shares the auth_test DB with control-plane and both
run non-concurrency-safe (check-then-insert) admin seeding on startup.
Waiting only for service_started let both race to insert the admin actor,
crashing the loser on a unique constraint. Wait for service_healthy
instead, which only passes after Seed() completes.

Found by Qodo review on PR dcm-project#58.

Signed-off-by: Vladislav Kolodny <vkolodny@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

@chadcrum chadcrum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

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