Skip to content

test(stack-kms-vendor): share the vendor test harness and live workflow - #1556

Closed
freshtonic wants to merge 2 commits into
james/kms-tests-vendor-key-namefrom
james/kms-vendor-test-harness
Closed

freshtonic wants to merge 2 commits into
james/kms-tests-vendor-key-namefrom
james/kms-vendor-test-harness

Conversation

@freshtonic

Copy link
Copy Markdown
Contributor

Summary

The four key vendor crates (AWS KMS, HashiCorp Vault, Google Cloud KMS, Azure Key Vault) each had their own copy of the same test harness: the fixture types, the fixture loader and a Replay transport that answers HTTP calls from recorded fixtures. The copies had started to differ. This PR moves the harness to one place. It also moves the job that the two opt-in live-test workflows had in common into one reusable workflow.

No library behaviour changes.

Changes

  • stack-kms-vendor: new replay module behind the existing test-support feature (which already holds the contract suite and FakeVendor). No new crate.
  • packages/stack-kms-{aws,vault,gcp,azure}/tests/common/mod.rs: keep only the vendor-specific parts (emulator, test keys, constants).
  • Two small test-harness changes: every Replay now records the waits the client asks for (only Azure did before), and AWS sends a null fixture body as no bytes, as the other three did. No AWS fixture has a null body.
  • .github/workflows/_test-kms-live.yml: new reusable workflow. integration-gcp-kms.yml and integration-azure-key-vault.yml call it, and each keeps its triggers, permissions, concurrency, job id, opt-in variable and fork-PR condition.
  • scripts/__tests__/crates-ci.test.mjs: it now follows a call to a reusable workflow in this repository, so it still finds the caller of each test:live:* task.
  • AGENTS.md: notes on the replay module and the new workflow.
  • Changeset: @cipherstash/auth patch, because code under stack-kms-vendor/src/ changed. The binding does not turn on test-support, so its binary does not change.

Verification

Run on the top branch of this stack (james/kms-vendor-dispatch), on macOS:

  • cargo fmt --all --check and cargo clippy --workspace --all-features --all-targets -- -D warnings: pass.
  • mise x --env test -- cargo nextest run --workspace --all-features: 1401 of 1402 pass. The one failure is stack-encrypt::ui derive_diagnostics (trybuild). It fails on every snapshot because of a local rustc wrapper that changes the paths in the compiler output. This stack does not touch stack-encrypt. CI is the check for it.
  • mise run wasm:guest:test: 80 of 80 pass.
  • All four Go guests rebuilt, then go vet ./... and go test -count=1 ./... in languages/golang: pass.
  • pnpm --filter @cipherstash/auth test: 92 pass. pnpm --filter stash test: 1667 pass.
  • Biome on the changed TypeScript and script files: no errors.
  • cargo check of the workspace and the guest (native and wasm32-wasip1) on each branch of the stack: pass.
  • pnpm run test:scripts: pass.
  • Not run: actionlint on the three workflow files. It is not installed on this machine.

Review notes

  • The check names change. A run of the live tests now shows as <caller job name> / live. These jobs do nothing until a repository variable is set, so they should not be required checks. Please confirm that branch protection does not name them.

Related

Refs #1541. Code-smell follow-up to the key vendor backend stack.

@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

@changeset-bot

changeset-bot Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3f1228c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 19 packages
Name Type
@cipherstash/auth Patch
stash Patch
@cipherstash/stack Patch
@cipherstash/wizard Patch
@cipherstash/ffi-integration-tests Patch
@cipherstash/basic-example Patch
@cipherstash/e2e Patch
@cipherstash/bench Patch
@cipherstash/stack-drizzle Patch
@cipherstash/stack-prisma Patch
@cipherstash/stack-supabase Patch
@cipherstash/test-kit Patch
@cipherstash/prisma-example Patch
@cipherstash/auth-darwin-arm64 Patch
@cipherstash/auth-darwin-x64 Patch
@cipherstash/auth-linux-arm64-gnu Patch
@cipherstash/auth-linux-x64-gnu Patch
@cipherstash/auth-linux-x64-musl Patch
@cipherstash/auth-win32-x64-msvc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@freshtonic
freshtonic added this pull request to stack #1523 November 6, 2026 11:25
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Mutation testing (cargo-mutants, --in-diff, stack-auth + stack-encrypt)

No mutants were generated for the changed lines.

@freshtonic
freshtonic force-pushed the james/kms-vendor-test-harness branch from d4ca39e to 3f1228c Compare November 9, 2026 04:16
@freshtonic
freshtonic force-pushed the james/kms-tests-vendor-key-name branch from 5a564a3 to 0e3e986 Compare November 9, 2026 04:16
@freshtonic
freshtonic removed this pull request from stack #1523 November 9, 2026 04:17
@freshtonic
freshtonic added this pull request to stack #1579 November 9, 2026 04:17
The fixture types, the fixture loader, body_json and the Replay transport
were in each of the four vendor crates' tests/common/mod.rs. The copies
were almost the same, but they had started to differ: only the Azure
Replay kept its waits, and only the AWS copy sent a null body as "null".

Move the harness to stack_kms_vendor::replay, behind the test-support
feature. That feature already holds the contract suite and FakeVendor,
which every vendor crate uses as a dev-dependency, so this needs no new
crate and no new dependency edge. The module also holds the Recording
transport that the Vault crate uses to write fixtures.

Each tests/common/mod.rs now keeps only its vendor parts: the emulator,
the test keys and the constants. The fixture files do not change.

The feature now pulls in serde for the fixture types. The
@cipherstash/auth binding does not turn on test-support, so its binary
does not change. The changeset records the src/ change, as the repo rule
requires.
integration-gcp-kms.yml and integration-azure-key-vault.yml had the same
job: a secret pre-flight, checkout, mise, the Rust cache and
mise run test:live:<crate>. Only the secrets were different.

Move that job to the reusable workflow _test-kms-live.yml. Each caller
keeps its triggers, its permissions, its concurrency group, and the job
id "live" with its name, its opt-in on the repository variable and its
fork-PR condition. So both stay inert until STACK_KMS_GCP_LIVE_KEY or
STACK_KMS_AZURE_LIVE_KEY is set, and the scans in
workflow-dispatch-job-conditions.test.mjs see the same jobs. The secret
names and the pre-flight messages do not change. The Google key still
goes to a file only the runner user can read, and the Azure secrets
still reach only the test step. Both path filters now include the shared
file.

The reusable workflow runs mise run test:live:${{ inputs.crate }}.
crates-ci.test.mjs read only the run lines of a workflow's own steps, so
it saw no caller for the two live tasks. It now reads the steps of a
reusable workflow in this repository through each job that calls it,
with the caller's inputs put in. A task counts for the caller, so
removing a caller still orphans its task.
@freshtonic
freshtonic force-pushed the james/kms-tests-vendor-key-name branch from 0e3e986 to abf6a63 Compare November 10, 2026 02:37
@freshtonic
freshtonic force-pushed the james/kms-vendor-test-harness branch from 3f1228c to 2d44caa Compare November 10, 2026 02:37
@freshtonic
freshtonic removed this pull request from stack #1579 November 12, 2026 03:45
@freshtonic

Copy link
Copy Markdown
Contributor Author

Folded into #1526 (the shared fixture harness, replay) and #1530 (the shared live workflow, _test-kms-live.yml, which #1531 also calls).

The plan is docs/plans/2026-11-12-key-vendor-backends-scope-reduction.md, and the decision log (docs/plans/2026-11-05-key-vendor-backends-decisions.md, "Scope reduction") records what changed. The old branch tip is kept locally as refs/backup/2026-11-12/<branch>.

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