|
| 1 | +# snapshot-e2e |
| 2 | + |
| 3 | +End-to-end black-box tests for the shared-filesystem snapshot store |
| 4 | +(`dryrun snapshot push --to-path` / `pull --from-path`), including |
| 5 | +cross-version compatibility against the **v0.6.1** baseline. |
| 6 | + |
| 7 | +The Rust unit tests in `crates/dry_run_core/src/history/filesystem_store.rs` |
| 8 | +cover internal correctness. This suite covers the things only a real |
| 9 | +multi-process / multi-binary / real-Postgres setup can: cross-version |
| 10 | +compat, concurrent writers, filesystem corruption, multi-database flows. |
| 11 | + |
| 12 | +## Running |
| 13 | + |
| 14 | +```sh |
| 15 | +./harness.sh # all scenarios, full Docker (HEAD + v0.6.1) |
| 16 | +./harness.sh 's04*.sh' # filter scenarios by glob |
| 17 | +./harness.sh -- bash # drop into the runner container |
| 18 | +./harness.sh down # stop the stack |
| 19 | +./harness.sh rebuild # rebuild after CLI code changes |
| 20 | + |
| 21 | +./run-native.sh # HEAD only, host cargo build, single pg-a |
| 22 | +./run-native.sh 's01*.sh' # filter |
| 23 | +``` |
| 24 | + |
| 25 | +`harness.sh` keeps the runner container alive between invocations |
| 26 | +(`up -d` + `exec`), so warm runs land in **~1.5–2 s**. `run-native.sh` |
| 27 | +skips Docker for the dryrun binary entirely — best for iterating while |
| 28 | +authoring new scenarios. |
| 29 | + |
| 30 | +Scenarios that need the v0.6.1 binary tag themselves |
| 31 | +`# NATIVE: skip`; `run-native.sh` honors that. |
| 32 | + |
| 33 | +## Layout |
| 34 | + |
| 35 | +``` |
| 36 | +snapshot-e2e/ |
| 37 | +├── docker-compose.yml # pg-a, pg-b, pg-c (tmpfs), persistent runner |
| 38 | +├── Dockerfile.dryrun # multi-stage: dryrun-old (v0.6.1) + dryrun-new (HEAD) |
| 39 | +├── harness.sh # full-Docker entrypoint |
| 40 | +├── run-native.sh # native fast-feedback entrypoint |
| 41 | +├── run.sh # invoked inside the runner; aggregates scenarios |
| 42 | +├── lib.sh # shared helpers: scenario / reset_* / ws_run / assert_* |
| 43 | +├── fixtures/schemas/*.sql # seed SQL |
| 44 | +├── scenarios/sNN_*.sh # one bash script per scenario |
| 45 | +├── shared/ # bind-mounted "team filesystem" (gitignored) |
| 46 | +└── workstations/{devA,devB}/ # per-workstation HOMEs (gitignored) |
| 47 | +``` |
| 48 | + |
| 49 | +## Adding a scenario |
| 50 | + |
| 51 | +Each scenario is ~30 lines of bash. Copy an existing one in `scenarios/` |
| 52 | +and tweak. Helpers from `lib.sh`: |
| 53 | + |
| 54 | +| Helper | What it does | |
| 55 | +| ------------------------------- | ------------------------------------------------------------------------ | |
| 56 | +| `scenario "TITLE"` | Names the scenario; `ok` / `fail` print TAP-ish output. | |
| 57 | +| `reset_shared` | Wipes the shared dir. | |
| 58 | +| `reset_workstation devA` | Clears `workstations/devA/` and writes a fresh `dryrun.toml`. | |
| 59 | +| `reset_db / seed_db <url> <sql>`| Drops `public` and re-seeds. | |
| 60 | +| `ws_run devA <argv...>` | Runs a command with `cd` + `HOME` set to the workstation dir. | |
| 61 | +| `assert_eq`, `assert_contains`, `assert_no_tmp_files`, `assert_jq`, … | Cheap assertions; failures print but don't `exit`. | |
| 62 | + |
| 63 | +Naming: `sNN_<id>_<short-description>.sh` where `<id>` matches a row in |
| 64 | +the design doc (`internal-docs/snapshot-share-tests.md`). Scenarios that |
| 65 | +require the v0.6.1 binary should put `# NATIVE: skip` near the top. |
| 66 | + |
| 67 | +## Tearing down |
| 68 | + |
| 69 | +```sh |
| 70 | +./harness.sh down # stop containers |
| 71 | +docker compose down -v # also drop networks (rare) |
| 72 | +``` |
| 73 | + |
| 74 | +The `shared/` and `workstations/` bind-mount roots persist between runs; |
| 75 | +`reset_*` clears their contents at scenario start. |
0 commit comments