# tests/integration — cross-lane runtime gates Owned by PKG/QA. Real binaries against `tools/mockd` / `tools/testserver`, headless. Unit tests live in each lane; this tree is for behaviour that only shows up when the pieces run together (throughput, memory over time, reconnect). ## GUI M1 definition-of-done gates (R3) `gui/docs/pkg-qa-requests-m1.md` R3: three GUI DoD items are not unit tests and have nowhere to run. GUI owns the harness; PKG/QA owns the CI job. This is the wiring contract so the two halves meet without another round trip. ### What PKG/QA needs from GUI A driver invoked as `gui/tests/dod/run.sh [--json ]` (exact path TBD by GUI), headless-capable (Xvfb or offscreen `QT_QPA_PLATFORM`), with: | `` | Pass / fail condition | Budget | |---|---|---| | `scroll-60fps` | `mockd --tasks 10000`, scripted fling scroll; **fail** if p99 frame > 16.6 ms | per-PR | | `rss-flat` | `mockd --tasks 10000` + progress events, 10 min; **fail** if RSS growth > a fixed slack (GUI picks the number, states it) | nightly | | `unhappy-path` | `mockd --slow` / `--flaky ` / `--drop-connection `; **fail** on crash, on watchdog-detected hang, or if connection state never returns to `Connected` | per-PR | Contract: * exit `0` pass, non-zero fail; a hang is the harness's own watchdog to catch and turn into a non-zero exit, not something CI should have to `timeout(1)` around. * `--json` writes one machine-readable result file (measured p99, RSS series, recovery time) so the job can upload it as an artifact and a regression is a diff, not a re-run. * no network, no writes outside a tempdir, no leaked child processes on failure. ### CI job — pre-drafted, add once the harness path is fixed ```yaml gui-dod: # Per-PR GUI gates. The 10-minute rss-flat gate is in gui-dod-nightly, not here. runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Bootstrap toolchain run: sudo ./tools/bootstrap.sh - uses: actions/setup-node@v4 with: node-version: '22' # tools/mockd - name: Configure + build run: | cmake --preset dev cmake --build --preset dev --target velox-gui - name: Install mockd run: cd tools/mockd && npm ci - name: Xvfb + gates run: | sudo apt-get install -y --no-install-recommends xvfb xvfb-run -a gui/tests/dod/run.sh scroll-60fps --json scroll.json # TODO(GUI): path xvfb-run -a gui/tests/dod/run.sh unhappy-path --json unhappy.json - uses: actions/upload-artifact@v4 if: always() with: name: gui-dod-${{ github.run_id }} path: "*.json" gui-dod-nightly: if: github.event_name == 'schedule' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Bootstrap toolchain run: sudo ./tools/bootstrap.sh - uses: actions/setup-node@v4 with: node-version: '22' - name: Configure + build run: | cmake --preset dev cmake --build --preset dev --target velox-gui - run: cd tools/mockd && npm ci - name: RSS soak (10 min) run: | sudo apt-get install -y --no-install-recommends xvfb xvfb-run -a gui/tests/dod/run.sh rss-flat --json rss.json - uses: actions/upload-artifact@v4 if: always() with: name: gui-dod-rss-${{ github.run_id }} path: rss.json ``` `gui-dod-nightly` needs a `schedule:` trigger added to the top of `ci.yml` (there is none today), or its own workflow file. Decide that when the harness lands. ### Status Blocked on GUI's harness. Not urgent (GUI M1 DoD, not M0). When GUI files the follow-up with the real `run.sh` path and the `rss-flat` slack number, PKG/QA drops the `TODO(GUI)` markers, adds the `schedule:` trigger, and marks `gui-dod` required.