Skip to content

🤖 test: add the CoderAIGatewayKey Kind E2E phases and the #348 follow-ups - #370

Merged
ThomasK33 merged 1 commit into
mainfrom
feat/ai-gateway-key-kind-phase
Oct 14, 2026
Merged

ThomasK33 merged 1 commit into
mainfrom
feat/ai-gateway-key-kind-phase

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Part K11 of #156, and the follow-ups of #348. The Kind E2E driver now tests the CoderAIGatewayKey controller against a real, unlicensed Coder, and the provider phases accept only Coder's own 404 as proof of a delete.

Fixes #348
Refs #156

What the new E2E phases check

Kind runs Coder without a license, so these phases test the unlicensed path: the controller must stall and must send no key create. Each phase checks the CR status for the current generation and the Coder side (API answer and the ai_gateway_keys row count through psql), not only command exits.

Phase Checks
gw-gate Entitlements show aibridge not enabled. GET /api/v2/ai-gateway/keys answers 403 with Coder's Premium message. 0 key rows.
gw-not-allowed Without spec.aiGateway.allowKeys, the object stalls NotAllowed. No Secret, nextSerial 0, no current or pending key, 0 rows.
gw-license-required With the opt-in, it stalls LicenseRequired. Same zero-side-effect checks.
gw-secret-not-owned An object that names an existing unlabeled Secret stalls SecretNotOwned. The Secret's resourceVersion, ownerReferences and data hash do not change.
gw-leak-check The key controller's log lines and both objects hold no 43-character key-shaped value, and nothing holds the synthetic Secret value.
gw-delete Both objects go within 30 s. 0 rows, the hijack Secret is unchanged, and no key Secret exists.

The synthetic Secret value stays in a 0600 file. It never goes to argv or output, and GitHub Actions masks it (::add-mask::, as in #345). A new coder_status helper reads an HTTP status and body without -f. The token stays in the 0600 header file.

#348 follow-ups

  1. P6: after the provider delete, Coder must answer 404 with its own message Resource not found or you do not have access to this resource (rule from 🤖 fix: check a CoderAIProvider's provider ID before Coder calls, and trust only Coder's own delete 404 #325). A proxy 404 or a wrong route now fails the phase.
  2. CI path filter: the full Kind E2E now also runs for internal/controller/credential_checks.go and internal/credentialsecret/**.
  3. P7: after the namespace deletion, the operator log must show the ControlPlaneGone release of provider e2e-ns-keep.

Also: TestCoderAIGatewayKeyDeleteRetries has a "route not found" case. Coder's Route not found. 404 on a key DELETE stalls NotSupported with a 10-minute requeue.

Stub tests

hack/e2e-workspace-lifecycle_test.sh covers the new phases with 9 new failure rows. Each row also checks where the mutations stop: gw-entitled, gw-db-row, gw-secret-created, gw-create-sent, gw-hijack-written, gw-log-leak, gw-finalizer-stuck, ai-delete-foreign-404 (P6) and ai-ns-no-release (P7).

Validation

Local, on head 1bc84d5 (rebased on main 3aedefb):

  • Passed: git diff --exit-code drift, make verify-vendor, make build, make lint, make test, make test-integration, go test -race ./internal/controller/..., actionlint v1.7.10, shellcheck 0.11.0, bash -n on both scripts.
  • bash ./hack/e2e-workspace-lifecycle_test.sh cannot finish on my host: at a load average of 35–110, many scenarios hit the test's 60 s per-scenario limit (exit 124), with no assertion failure. With only that limit raised to 300 s, 110 checks pass and 1 fails (agent-never-ready, 32 s against its own 30 s bound, before the new phases). A run of the pass scenario plus all 9 new rows passed. CI runs the full stub suite and the Kind E2E on this head.

Not verified locally

  • The Kind E2E itself. The CI E2E job on this head runs it.
  • On real Kind, the 43-character check could match a log line or object field that the stub does not produce. The CI run shows it.

Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

The Kind E2E runs Coder without a license, so the new phases test the
unlicensed path of the CoderAIGatewayKey controller (#156, plan 9):

- gate: no aibridge entitlement, and the key LIST answers 403 Premium
- without the control plane opt-in: Stalled NotAllowed, no Secret
- with the opt-in: Stalled LicenseRequired, still no Secret
- an existing unlabeled Secret: Stalled SecretNotOwned, Secret unchanged
- leak check of the operator log and both objects
- delete: both finalizers go within 30 s
- throughout: 0 ai_gateway_keys rows, nextSerial 0, no current or
  pending key

Fixes #348:

- the provider delete phase (P6) requires Coder's own 404 message
- the e2e path filter adds credential_checks.go and credentialsecret
- the namespace phase (P7) checks the ControlPlaneGone release log line
  of AI provider e2e-ns-keep

The delete retry test also covers Coder's "Route not found." answer.

Change-Id: I0329b429eb54192be174daf857618a679b8e08aa
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T15:28:40.743789Z 1bc84d5 PR opened
🔒 Security Review ✅ Completed 2026-10-14T15:17:26.148076Z 1bc84d5 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 1bc84d5093

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33
ThomasK33 added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit 56af177 Oct 14, 2026
10 checks passed
@ThomasK33
ThomasK33 deleted the feat/ai-gateway-key-kind-phase branch October 14, 2026 15:53
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.

CoderAIProvider Kind phases: check Coder's own 404 in P6, widen the E2E path filter, check the P7 reason

1 participant