Skip to content

🤖 tests: cover watch option decoding over HTTP for workspaces and templates - #119

Merged
ThomasK33 merged 1 commit into
mainfrom
test/watch-option-http-matrix
Sep 23, 2026
Merged

ThomasK33 merged 1 commit into
mainfrom
test/watch-option-http-matrix

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Summary

Adds an HTTP-level test that sends real watch requests through the generic API server path (option decoding, WatchList defaulting, validation, then storage) for both coderworkspaces and codertemplates. It freezes the eight-case matrix of supported and rejected watch options. Test-only; no product or docs change.

Background

#112 asked for coverage of watch options through the generic request path, not only direct storage calls, for both resources. The existing tests in internal/aggregated/storage/watch_test.go call Watch directly, so they skip Kubernetes' defaulting. That defaulting turns a watch with no resourceVersion (or 0) into an initial-events request that this server rejects. The workspace behaviour was observed on a deployed server during #109; templates were never exercised over HTTP. The supported request form is already documented in docs/how-to/deploy-aggregated-apiserver.md (from #115), and this test confirms it.

Implementation

  • startIntegrationAggregatedAPIServer extracts the existing in-process server setup from integration_test.go, with the same cleanup order. The existing bootstrap/list test uses it unchanged.
  • The mock Coder backend gains the template-version and file routes that a template GET needs.
  • TestIntegrationWatchOptionsThroughGenericAPIServer gets a fresh resource version with an HTTP GET, then checks each case for exactly one status, plus the decoded Status reason, message and (for 422) the single field cause:
Case (watch=true plus) Workspaces and templates
nothing 400 BadRequest: sendInitialEvents=true is not supported
resourceVersion=0 400 BadRequest: same
resourceVersion=<token from GET> 200, stream opens (headers checked, then closed)
sendInitialEvents=false 422 Invalid: requires resourceVersionMatch=NotOlderThan
sendInitialEvents=false&resourceVersionMatch=NotOlderThan 400 BadRequest: resourceVersionMatch "NotOlderThan" is not supported
sendInitialEvents=true&resourceVersionMatch=NotOlderThan 400 BadRequest: sendInitialEvents=true is not supported
resourceVersionMatch=NotOlderThan 422 Invalid: forbidden unless sendInitialEvents is provided
resourceVersion=<token>&resourceVersionMatch=NotOlderThan 422 Invalid: same

The test asserts that the WatchList feature gate is enabled in the normal server configuration (the default since Kubernetes 1.34). It does not force the gate, so a future default change fails loudly instead of silently shifting expectations.

Validation

  • All 16 cases pass, as named subtests.
  • Mutation check: removing the storage's sendInitialEvents=true rejection makes the three affected cases fail for both resources. Removing both storage checks makes the unexpected 200s fail fast rather than hang.
  • Live run of the test on this head. It is an in-process HTTP test with a mock Coder backend, not a deployed cluster:

Live run of the watch option matrix test, in-process with a mock Coder backend

pr112-watch-matrix-live.webm

Risks

Test-only. The 200 case checks for a chunked response, which assumes the harness's HTTP/1.1 client; that would need adjusting if the client moved to HTTP/2.

Part of #112.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: xhigh • Cost: $1413.83

Existing watch tests call storage.Watch directly and skip the generic
handler's option decoding, WatchList defaulting, and ListOptions
validation. Add an in-process HTTP test that sends real watch requests to
both coderworkspaces and codertemplates and freezes one expected result
per case:

- no resourceVersion, and resourceVersion=0: 400 BadRequest
  (defaulting injects sendInitialEvents=true, which storage rejects)
- resourceVersion from a GET of the object: 200 watch stream
- sendInitialEvents=false only: 422 Invalid (upstream validation)
- sendInitialEvents=false with resourceVersionMatch=NotOlderThan:
  400 BadRequest (storage rejects resourceVersionMatch)
- sendInitialEvents=true with resourceVersionMatch=NotOlderThan:
  400 BadRequest (storage rejects sendInitialEvents=true)
- resourceVersionMatch=NotOlderThan only, with or without a
  resourceVersion: 422 Invalid (upstream validation)

The test asserts that the WatchList feature gate is enabled under the
production server configuration, so a dependency bump that changes the
default fails loudly. The server bootstrap moves into a shared harness
helper with t.Cleanup, and the mock Coder server now serves the template
version and source zip that template GET needs.

Part of #112

_Generated with [`xum`](https://github.com/coder/xum) • Model: `anthropic:claude-opus-5-5` • Thinking: `xhigh`_

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

chatgpt-codex-connector Bot commented Sep 23, 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-09-23T11:26:16.044881Z 0828d37 PR opened
🔒 Security Review Completed 2026-09-23T11:32:00.538383Z 0828d37 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: 0828d379ca

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 Sep 23, 2026
Merged via the queue into main with commit 116e2ec Sep 23, 2026
10 checks passed
@ThomasK33
ThomasK33 deleted the test/watch-option-http-matrix branch September 23, 2026 11:42
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.

1 participant