ReviewOS

also looking at this

stacks/ts-cloud

test(fleet): prove the database and hostname halves of a transfer on real machines

#184
Merged glennmichael123 wants to merge test/move-database-and-rename-e2e into main
4 files +363 -3

Refs #167. Closes the last two untested paths in the server-transfer feature — and one of them turned up a real fragility.

The database (7 cases)

This is the part of a move with the least margin for error: the tree and the units can be re-shipped by a deploy, the rows cannot. It's also what a unit test can say least about, because the claim that matters isn't "the right string was built" but "pg_dump wrote something psql could read back into a database that setup had just created".

So Postgres is stood up on two boxes and the actual builders the move composes are driven end to end — buildDatabaseSetupScript, buildBackupScript, buildBackupRestoreScript — with the rows read back out of the target.

One detail worth calling out: the seed runs as the app role, because that's who runs migrations in practice. My first version seeded as the superuser, and the ownership assertion failed — correctly, because in that setup the app couldn't read its own data on the source either. Fixing the seed turned that case into a real check: pg_dump records ownership, and a restore that lost it would leave the app facing a database full of tables it can't read, which is indistinguishable from an empty database until someone reads the logs.

Local trust auth isn't a concession to the test — it's what the pantry Postgres the drivers provision configures, and it's why pgAdminCommand omits -h for a co-located engine.

The hostname (6 cases) — and a fix

Three of the four records server:rename updates are data, properly unit-tested. The fourth is shell, and it's the one with somewhere to go wrong: hostnamectl isn't always present, /etc/hosts may or may not already carry a 127.0.1.1 line, and getting either wrong leaves a box whose own name doesn't resolve — which surfaces later as sudo hanging, not as a failed rename.

Running it found that sed -i cannot rewrite /etc/hosts when the file is a bind mount — every container — and would equally fail on a hard-linked file, because sed -i renames a temp file over the target:

sed: cannot rename /etc/sedFQn5eY: Device or resource busy

Rewritten to write the content back in place, which keeps the inode and works in both cases. That's a real fix the harness found, not a concession to it. Both paths are covered: hostnamectl present, and the /etc/hostname fallback.

The container gets CAP_SYS_ADMIN because setting a hostname needs it and containers drop it by default — a real box's root has it, so without it the test would be asserting a restriction the target environment doesn't have.

Results

Full suite 4282 pass, 0 fail. Lint and typecheck clean.

If you see integration tests skipping or a mid-run failure, that's the local Docker daemon dropping (it did so several times during this work), not the tests — they're skipped by design when Docker is unavailable.

Where that leaves the feature

Every path a server transfer touches is now exercised against real machines: tree and symlinks, systemd units, background work, the health gate, TLS material, the drained-source guard, the on-box database, and the hostname.

4 changed files on the files tab, with 0 review threads.