Skip to content

test: service writes give the same outcome for sync and async brokers - #6005

Merged
norman-abramovitz merged 5 commits into
cloudfoundry:developfrom
nabramovitz:norm/test/async-service-writes
Oct 14, 2026
Merged

norman-abramovitz merged 5 commits into
cloudfoundry:developfrom
nabramovitz:norm/test/async-service-writes

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

#6001 was not caught because the frontend spec and the backend translator test both used hand-written job fixtures with the same wrong link key. This PR replaces hand-written service-write fixtures with Cloud Controller responses recorded on a live foundation, and checks that a synchronous and an asynchronous broker give the user the same outcome on both resolve paths. It is meant to merge before #6004, which then drops the #6001 expected-failure markers together with its fix.

Recorded CF responses

src/jetstream/plugins/cloudfoundry/testdata/cf-jobs/cf holds real CF API 3.226 job bodies (first poll and terminal) for service instance create/update/delete, app binding create/delete and service key create/delete, with a test broker (cloudfoundry/overview-broker) in synchronous and asynchronous mode, plus broker failures: async create, async update, sync create. Hostnames are replaced with example.com.

Backend: TestServiceWritesContract

Replays each recording through the real write handler against a fake CF, twice: with the job already terminal (fast path, 200/502), and still running when the window closes (202 handoff, then the tracker poll). Both paths must report the same result, and broker failures the same error. What the frontend receives is kept in testdata/cf-jobs/stratos; go test ./plugins/cloudfoundry -run TestServiceWritesContract -update rewrites it.

Frontend specs

@test-framework/cf gains serviceWriteContract() and answerServiceWrite(), which answer a pending write from those files on the fast or the polled path. The create-service-instance wizard (create, create + bind, update, broker failures), binding create, unbind, service key create and delete, and service instance delete each run for a sync and an async broker on both paths, with the same assertions.

E2E

e2e/tests/marketplace/async-service-writes.spec.ts runs the wizard against the test broker switched to synchronous and to asynchronous responses: success is reported only once CF has the instance, and the app chosen in the wizard gets bound. Configure the broker as services.testBroker in the secrets profile (see e2e/secrets.yaml.template); the spec skips without it and runs in chromium only, since the broker's mode is shared. Live run: 6 passed (8.5 min).

Known failures, marked

Marker Where Issue
it.fails ×4, test.fail ×2 bind after create #6001 (fixed by #6004; with its fix applied these report "expected to fail, but passed")
it.fails ×3 broker failure message differs by path: the polled path prefixes CF's title (CF-UnableToPerform. …) #6002

Finding for #6002

Every broker failure recorded (async create, async update, sync create) makes CF fail the job itself, so the polled path does report the failure; the "failure after the fast path reported as created" item in #6002 did not reproduce on CF API 3.226.

make check gate passes. Changelog fragment: changelog.d/0007-service-write-tests.md.

AI disclosure (RFC-0047): prepared with AI coding assistance; reviewed by the author.

Record Cloud Controller job responses from a live foundation, with a
test broker answering synchronously and asynchronously and failing
both ways, and replay them through the service instance, binding and
key write handlers. Each write runs on the fast path and through the
tracker handoff; both must report the same result, and broker
failures the same error. The responses the frontend receives are
kept in testdata/cf-jobs/stratos for its specs (-update rewrites
them).
Answer the create-service-instance wizard's writes from the recorded
backend responses instead of hand-written bodies, on the fast and the
polled path, for a synchronous and an asynchronous broker. Known
failures are marked: bind after create (cloudfoundry#6001) and broker failure
messages that differ between the two paths (cloudfoundry#6002).
Answer binding create and delete, service key create and delete, and
service instance delete from the recorded backend responses, for a
synchronous and an asynchronous broker on the fast and the polled
path, with the same assertions on each.
Run the create wizard against a test broker whose response mode can
be switched (cloudfoundry/overview-broker, services.testBroker in the
secrets profile), once synchronous and once asynchronous. The wizard
must report success only once CF has the instance, and must bind the
app chosen in the wizard; the bind case is a known failure (cloudfoundry#6001).
Runs in one browser because the broker mode is shared.

@norman-abramovitz norman-abramovitz 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

@norman-abramovitz
norman-abramovitz merged commit a10da5f into cloudfoundry:develop Oct 14, 2026
24 checks passed
@nabramovitz
nabramovitz deleted the norm/test/async-service-writes branch October 14, 2026 06:50
nabramovitz added a commit to nabramovitz/stratos that referenced this pull request Oct 14, 2026
With the plural job link read, the wizard binds the chosen app for a
synchronous and an asynchronous broker on the fast and the polled
path, so the cloudfoundry#6001 expected-failure markers from cloudfoundry#6005 come off, in
the unit spec and the e2e spec. The service write tests fragment no
longer lists bind after create as a known gap.
norman-abramovitz pushed a commit that referenced this pull request Oct 14, 2026
With the plural job link read, the wizard binds the chosen app for a
synchronous and an asynchronous broker on the fast and the polled
path, so the #6001 expected-failure markers from #6005 come off, in
the unit spec and the e2e spec. The service write tests fragment no
longer lists bind after create as a known gap.
norman-abramovitz pushed a commit that referenced this pull request Oct 15, 2026
The same broker failure read differently depending on how CF answered.
Inside the fast-path window the message was the broker's detail; after
a polled job it was CF's title in front of it ("CF-UnableToPerform.
..."), and only the polled path removed the HTML page CF quotes from a
broker's response.

A failed job's message is now the detail, markup stripped, or CF's
title when there is no detail; extractHttpErrorMessage reads the
fast-path body the same way, through the same stripMarkup. Callers add
their own lead-in. The three expected failures from #6005 now pass.

Refs #6002
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