ReviewOS

also looking at this

stacks/ts-cloud

test(fleet): run site:move against two real machines

#180
Merged glennmichael123 wants to merge test/site-move-e2e into main
1 file +327 -0

Refs #167. Closes the gap I've been flagging since #176: none of site:move had ever run against a real box.

Every existing test drives injected effects. They prove the plan is right — ordering, resume behaviour, what refuses to run — and they assert the generated shell as strings. For an operation that archives a live site, carries its database and its private keys, and drains the box it came from, "the string looked right" is a different claim from "it ran".

What this does

Boots two systemd containers, builds a realistic site on the first — release tree, current symlink, shared state symlinked into that release, systemd units that really run and really bind a port — then executes the scripts the operation generates, in the order it generates them, against real systemd, real tar, real curl.

Same Docker harness shape as the existing sftp-box-e2e test, and skipped the same way when Docker is unavailable, so a machine without it reports a skip rather than a false pass.

What it establishes that a unit test could not

  • tar does not dereference. current and the shared-path links are still symlinks inside the archive and after restore, and writing through the release link reaches the shared file. This is the claim the whole design rests on: a flattened current becomes a second copy of the release, and a flattened shared path turns the database back into per-release state — silently, and only visible one deploy later.
  • The state parsers agree with real systemctl output. If they didn't, the plan would quietly decide a step was already done and skip it — the worst possible failure mode for a resumable operation.
  • Pausing background work leaves the site serving, and the target starts the app but not its scheduler or queue, so two boxes never run one scheduler against one dataset.
  • The health gate passes against a real listener and fails when nothing is bound.
  • Private keys land 0600 after the TLS carry.
  • The drain stops everything and leaves every byte in place, and the source comes back by restarting it with its data intact — the reversibility the operation promises, demonstrated rather than asserted.

It has teeth

I verified the harness can actually fail, rather than passing vacuously. Adding -h to the snapshot's tar — the exact mistake the design warns against — produces:

(fail) keeps current and the shared links as symlinks inside the archive
(fail) carries the shared state across byte-for-byte, still as symlinks
 13 pass  2 fail

Reverted, and green again.

Results

15 tests, all passing against real containers (~14–37s depending on image cache). Full suite 4137 pass, 0 fail. No source changes — site-move.ts is byte-identical to main.

What this does not cover

The on-box database carry (#178) is exercised only at the plan level here; proving pg_dumppsql end to end needs Postgres in the container and is worth a follow-up. The scp hops are stood in for by docker cp, since how bytes cross between boxes is the one part deliberately left to the caller.

So: the remote shell is now known to work. A first real move is still worth doing with the source kept until the target is verified — which the design already makes safe.

1 changed file on the files tab, with 0 review threads.