Mirrors the existing nestsClient/tests/hang-interop/ layout — all T16 cross-stack interop test infrastructure (Rust sidecars + bun browser harness) now lives under nestsClient/tests/. Updates: - nestsClient/build.gradle.kts: browserInteropDir path. - PlaywrightDriver.kt + BrowserInteropTest.kt: kdoc comments. - All plan docs in nestsClient/plans/ that referenced the old path. Compiles clean post-move. No CI changes (those jobs are intentionally not wired per 2026-05-07-cross-stack-interop-ci-gating.md; when re-added they'll reference the new path).
5.9 KiB
Plan: wire CI gating for the cross-stack interop suite
Status: specced — pickup ready. Depends on:
2026-05-07-moq-relay-routing-investigation.mdclosed2026-05-07-tighten-cross-stack-assertions.mdclosed- 5/5 sweep stability verified
This is the FINAL step of the T16 closure. With stable hard-pass suites, CI gating becomes safe and meaningful.
What's needed
A) .github/workflows/build.yml — the hang-interop job
The job was originally part of this branch but removed per
maintainer ask in commit 6829ab727 ("ci(nests): drop hang-interop
job from build.yml") because the suite was flaky. Resurrect the
exact same shape:
hang-interop:
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
- uses: actions/setup-java@v5
with: { distribution: 'zulu', java-version: 21 }
- uses: gradle/actions/setup-gradle@v4
with:
cache-read-only: ${{ github.ref != 'refs/heads/main' }}
- uses: dtolnay/rust-toolchain@stable
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
nestsClient/tests/hang-interop/target
~/.cache/amethyst-nests-interop/hang-interop-cargo
key: ${{ runner.os }}-cargo-${{ hashFiles('nestsClient/tests/hang-interop/Cargo.lock', 'nestsClient/tests/hang-interop/REV') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Run cross-stack interop suite
run: ./gradlew :nestsClient:jvmTest -DnestsHangInterop=true
- uses: actions/upload-artifact@v7
if: failure()
with:
name: Hang Interop Test Reports
path: nestsClient/build/reports/tests/jvmTest/
The git show 6829ab727 -- .github/workflows/build.yml reverse
gives the exact diff to re-add. Linux-only is correct: the cargo
install of moq-relay 0.10.x has nontrivial native deps
(aws-lc-sys, ring) that take 5+ min cold; cached runs ~30 s.
macOS / Windows would double matrix cost without catching new
defects.
B) .github/workflows/build.yml — the browser-interop job
Same shape as A, plus bun + Playwright caching:
browser-interop:
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
# ...same checkout + JDK + Gradle + Rust + cargo cache as hang-interop...
- uses: oven-sh/setup-bun@v2
with: { bun-version: 1.3.11 }
- uses: actions/cache@v4
with:
path: |
nestsClient/tests/browser-interop/node_modules
nestsClient/tests/browser-interop/dist
key: ${{ runner.os }}-bun-${{ hashFiles('nestsClient/tests/browser-interop/package.json', 'nestsClient/tests/browser-interop/bun.lock') }}
- uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('nestsClient/tests/browser-interop/package.json') }}
- name: Run browser cross-stack interop suite
run: |
./gradlew :nestsClient:jvmTest \
--tests "com.vitorpamplona.nestsclient.interop.native.BrowserInteropTest" \
-DnestsHangInterop=true \
-DnestsBrowserInterop=true
- uses: actions/upload-artifact@v7
if: failure()
with:
name: Browser Interop Test Reports
path: |
nestsClient/build/reports/tests/jvmTest/
nestsClient/tests/browser-interop/test-results/
nestsClient/tests/browser-interop/playwright-report/
Same git show b94737de7 -- .github/workflows/build.yml reverse
gives the exact diff (feat/nests-browser-interop's removal
commit).
C) Cross-link with :cli interop tests
The existing nests-interop opt-in pattern already lives in
cli/tests/nests/nests-interop.sh. Confirm both new jobs run
in parallel with that without resource contention. They use
different ports (NativeMoqRelayHarness reserves ServerSocket(0))
so they're independent at the network level.
Stability bar
Before flipping the CI switch, run:
for i in 1 2 3 4 5 6 7 8 9 10; do
echo "=== run $i ==="
./gradlew :nestsClient:jvmTest \
--tests HangInteropTest \
--tests BrowserInteropTest \
-DnestsHangInterop=true \
-DnestsBrowserInterop=true \
--rerun-tasks 2>&1 | grep -E "FAILED]|BUILD"
done
10/10 BUILD SUCCESSFUL. If even one fails, do NOT wire CI; loop back to the routing investigation.
CI runtime budget
- Hang-interop job: ~3-4 min on warm cache (one suite run, 60 s long-broadcast scenario dominates), ~8 min cold (cargo install moq-relay).
- Browser-interop job: ~5-7 min warm (Chromium boot × N scenarios), ~10 min cold (Playwright install).
- Both run in parallel after
lint.
Total CI overhead: ~5-10 min on the critical path beyond the existing build matrix. Acceptable.
Documentation updates
After CI is green:
nestsClient/plans/2026-05-06-cross-stack-interop-test-results.md— replace the "CI integration: Not wired" section with "wired, tracking flake-rate at 0/N runs".nestsClient/plans/2026-05-06-cross-stack-interop-test-gap-matrix.md— replace#6 CI integration: ⏸ deferredwith✅ live.- Pick a maintainer to monitor the first 2 weeks of CI runs and bisect any new flake immediately (don't let it accumulate as "known flake" again).
Acceptance criteria
- Both jobs added to
build.ymland merge to main. - 10/10 sweep before merge.
- First 2 weeks post-merge: ≥ 95% green rate. If lower, the routing investigation isn't really done — pull the jobs again until it is.
Optional follow-ups
- Add I-12 GOAWAY scenario IF an IETF moq-transport target lands.
Currently N/A in moq-lite-03 per
cross-stack-interop-test-results.md's I12 section. If an IETF target ever ships, this is the cross-stack regression test. - Surface
framesPerGroupas a per-deployment config if the framesPerGroup-rerun outcome shows the two rigs can't converge (see2026-05-07-framespergroup-production-rerun.md).