Repository navigation
🤖 test: add the CoderAIGatewayKey Kind E2E phases and the #348 follow-ups - #370
Merged
Merged
Conversation
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>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Member
Author
|
@codex security review |
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part K11 of #156, and the follow-ups of #348. The Kind E2E driver now tests the
CoderAIGatewayKeycontroller 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_keysrow count through psql), not only command exits.gw-gateaibridgenot enabled.GET /api/v2/ai-gateway/keysanswers 403 with Coder's Premium message. 0 key rows.gw-not-allowedspec.aiGateway.allowKeys, the object stallsNotAllowed. No Secret,nextSerial0, no current or pending key, 0 rows.gw-license-requiredLicenseRequired. Same zero-side-effect checks.gw-secret-not-ownedSecretNotOwned. The Secret's resourceVersion, ownerReferences and data hash do not change.gw-leak-checkgw-deleteThe 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 newcoder_statushelper reads an HTTP status and body without-f. The token stays in the 0600 header file.#348 follow-ups
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.internal/controller/credential_checks.goandinternal/credentialsecret/**.ControlPlaneGonerelease of providere2e-ns-keep.Also:
TestCoderAIGatewayKeyDeleteRetrieshas a "route not found" case. Coder'sRoute not found.404 on a key DELETE stallsNotSupportedwith a 10-minute requeue.Stub tests
hack/e2e-workspace-lifecycle_test.shcovers 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) andai-ns-no-release(P7).Validation
Local, on head 1bc84d5 (rebased on main 3aedefb):
git diff --exit-codedrift,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 -non both scripts.bash ./hack/e2e-workspace-lifecycle_test.shcannot 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
Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:high