Repository navigation
feat: passthroughtest, a seam to run the consumed-module passthrough in a test - #42
Merged
Merged
Conversation
…in a test A consuming solution could not exercise its page's calls to a consumed module in a test: the passthrough handler is internal, and Serve resolves the gateway and api.consumes from the composition and registers with the host. A `codefly test` suite therefore could not drive a streamed method at all. Server.PassthroughHandler(PassthroughEnvironment) builds the passthrough exactly as Serve does: the same boot check (validatePassthrough) and the same mounting code, now one function (mountPassthrough) that serve and the seam both call, against a gateway URL and api.consumes projection the caller supplies. Nothing else of the solution is served and nothing registers. Package passthroughtest builds on it: a fake host gateway that mints the viewer's Work Context and forwards /v1/<as>/* to the test's own module server (streams flushed as they arrive, cancellation propagated), hooks to route a module and to refuse mints, a record of every mint and of every forwarded call with the mint it presented, and a client that calls as a viewer with the identity headers the gateway stamps. Its own tests drive a unary call, a stream of several messages, per-method authority, the response field mask on both, and cancellation reaching the module when the page disconnects, and a refused mint refusing only its method. The formatting gate now covers the whole tree, not only ./*.go. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Why
A consuming solution cannot test its page's calls to a consumed module. The passthrough handler is internal, and
Serveresolves the gateway andapi.consumesfrom the composition and registers with the host. So acodefly testsuite in a consuming solution cannot run the passthrough against its ownConsumesdeclaration and a fake host, and in particular cannot exercise a server-streaming method.What
Root package: one shared constructor, one new exported entry point
mountPassthrough(mux)is now the only place the passthrough is wired, atPassthroughPathPrefix.servecalls it (the inline block moved there unchanged), and so does the seam.(*Server).PassthroughHandler(PassthroughEnvironment) (http.Handler, error)sets the gateway URL andapi.consumesprojection from its argument instead of the environment. It then runs the same boot checkServeruns (validatePassthrough) and mounts the handler throughmountPassthrough. Nothing else of the solution is served, and nothing registers.PassthroughEnvironment{GatewayURL string; Consumes []manifest.ConsumedAPI}.These are additions only. No existing exported signature changes.
New package
passthroughtestNewHost(t) *HostStartTaskmint and reverse-proxies/v1/<as>/*to routed modules. Streams are flushed as they arrive, and a cancelled request is cancelled upstream.(*Host).Module(as, upstreamURL) *Hostapi.consumesprojection.(*Host).RefuseMints(func(Mint) *Refusal) *Host(*Host).Mints() []Mint,(*Host).Calls() []CallMintwhose capability it presented. This is how a test asserts the authority minted for each method.(*Host).URL()Start(t, host, consumes...) *Solution/Handler(host, consumes...) (http.Handler, error)httptest, or the bare handler together with the boot refusalServewould give.(*Solution).Client(),ClientAs(Viewer),BaseURL(as),.URLx-org-id/x-session-idheaders the gateway stamps, and the base URL a generated client takes.Viewer,DefaultViewer,Mint,Call,RefusalDocs and gate
passthroughtest" section.gofmt -l .instead of./*.go). AGENTS.md asks for this in the same PR that adds a subdirectory package.Tests
passthroughtest/passthroughtest_test.gouses the seam as a consumer would, as an external test package with a dynamically registered placeholder module API (acme.widgets.v1):widgets:readand Watch mints its ownwidgets:watch, asserted from the host's record of which mint each forwarded call presented;permission_denied, with the reason), and the other method is still served;Serverefuses it.Mutation checks, run locally and then reverted:
Results:
go mod verify,go build ./...,go vet ./...andtest -z "$(gofmt -l .)"pass.go test ./... -count=1andgo test -race ./... -count=1 -timeout=5mpass for both packages.go mod tidyis a no-op. The repo configures no linter. A localgolangci-lint runreports 0 issues inpassthroughtest. On the root package it reports 7, none on lines this PR touches.Classification
Fix. The seam lives in the repository that owns the passthrough and serves the real handler through the one constructor
Serveuses. It does not reimplement the passthrough. The one change to runtime code is extracting the existing mount block intomountPassthrough, with no change in behaviour.Not verified
codefly testsuite, only from this repo's owngo test.StartTaskConnect JSON shape, the Work Context header, and path-preserving/v1/<as>/*forwarding. It is not checked against a real host or gateway, so a drift there would not show up in a green seam test.🤖 Generated with Claude Code