Commit graph

8 commits

Author SHA1 Message Date
Nicolas De Loof
fe17e31be0 test(e2e): lifecycle scenarios — cascade, profiles, healthcheck, recreate
Vocabulary grows with Recreated (the mirror of NotRecreated),
ServiceHealthy (healthcheck status observed from inspect) and a Within
action modifier bounding blocking commands like up --wait, replacing
the hand-rolled goroutine+timer of the legacy TestStartInterval.

- cascade: abort-on-container-exit/failure scenarios inline the model;
  exit-code propagation (111) is locked with ExitCode. The one-off
  variant stays legacy — it drives a long-running up in the background.
- profiles: the four scenarios observe which services materialize
  instead of grepping ps output; the dotenv variant declares its .env
  inline, making the activation mechanism visible.
- TestRecreateWithNoDeps now asserts both sides: the service is
  replaced (Recreated) and the healthy dependency is left alone.
- Fixtures start_interval/, profiles/compose.yaml+test-profile.env and
  recreate-no-deps.yaml are removed; cascade/ stays for the legacy
  one-off test.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-08-18 16:49:56 +02:00
Nicolas De Loof
6bc1b36516 test(e2e): expose, container_name, ipc and wait scenarios
- TestExposeRange keeps its regression link (#13378), the invariant
  being simply that up accepts a port range in expose.
- TestUpContainerNameConflict interpolates a project-scoped
  container_name instead of the fixture's global 'test', so parallel
  runs cannot collide on it.
- TestIPC demonstrates the CLI() escape hatch: the external container
  the 'container:' mode points at is created eagerly before the steps,
  so its id is available to the declarative checks. (Runs only in CI:
  ipc container: mode is rejected by Docker Desktop and dind daemons —
  'restricted host mount' — for the legacy test as well.)
- wait scenarios observe which services exited instead of trusting the
  command's silence; TestWaitOnInfinity stays legacy, the DSL has no
  notion of a still-running command. The wait fixture stays for it;
  ipc-test and container_name fixtures are removed.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-08-18 16:49:56 +02:00
Nicolas De Loof
a33cc37ad9 test(e2e): TestRemoveOrphans states its real intent — COMPOSE_REMOVE_ORPHANS from .env
The legacy test read as 'up removes leftover one-offs', but plain up
only warns about them: the removal it asserted came from the fixture's
.env declaring COMPOSE_REMOVE_ORPHANS=true (added by 'restore
setEnvWithDotEnv', d3d378b92) — an invariant the fixture kept invisible.
The scenario declares both files inline as a txtar archive, so the
mechanism under test is in plain sight, and observes the one-off's
removal from container state rather than ps output.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-08-18 16:49:56 +02:00
Nicolas De Loof
a725a8ae04 test(e2e): one-off vocabulary — service checks skip run containers
Snapshots now record whether a container is a one-off (run) container,
plus its start time. Service-facing checks (ServiceState, NotRecreated,
label checks) observe only long-lived containers; three checks join the
vocabulary for the one-off side: OneOffState, OneOffsUntouched (same
containers, same state, same start time — catches an unwanted restart,
which message matching never could) and OneOffsRemoved (errors if there
was nothing to remove, rather than pass vacuously).

TestStartStopWithOneOffs becomes the demonstrator: stop/start/restart
act on services and leave the one-off untouched, down --remove-orphans
takes it away.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-08-18 16:49:56 +02:00
Nicolas De Loof
695a2a759a test(e2e): start/stop scenarios observe container state, not CLI chatter
Migrate the state-friendly start/stop tests to the Scenario DSL:

- TestStartStop: stop halts containers in place, start brings the same
  ones back (NotRecreated); the ls checks match the project name exactly
  in the JSON output, immune to the prefix collisions the other
  start-stop project names would cause under parallel runs.
- TestStartStopWithDependencies: dependency start/stop propagation read
  from container state instead of 'Container X Started' messages.
- TestUpNoDeps replaces the 'Up no-deps links' subtest as its own
  scenario: up --no-deps must not create the linked dependency.
- TestStartSingleServiceAndDependency: create/start walk the dependency
  chain and nothing else — now asserting the unrelated services have no
  container at all, stronger than the legacy message matching.

The one-off and multi-file tests stay legacy: the vocabulary has no
one-off awareness yet and a scenario holds a single compose file.
The links and start-stop-deps fixtures become unused and are removed.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-08-18 16:49:56 +02:00
Nicolas De Loof
5baeadf929 test(e2e): no-deps scenarios — the donor container's absence is the observable
Migrate the volumes_from and network_mode:service donor tests to the
Scenario DSL, inlining the compose model and dropping the no-deps
fixtures. Each scenario removes the donor container behind compose's
back and expects up --no-deps to be rejected with the 'container
missing' error — the CLI's reported decision being the observable.

ServiceNotCreated joins the check vocabulary: it asserts a service has
no container at all, here proving the donor really is gone before the
failing step.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-08-18 16:49:56 +02:00
Nicolas De Loof
12288a7fff test(e2e): pause scenarios — paused is a container state, ExitCode locks error paths
Migrate the four pause tests to the Scenario DSL: the invariant is the
container state (paused/running), not an HTTP timeout, so the scenarios
observe state and drop the port-mapping helpers and the pause fixture.

ExitCode joins the check vocabulary for error-path steps, paired with
MayFail. TestPauseServiceDoesNotExist now locks the current behavior —
pause of an unknown service is rejected with 'no such service' — which
resolves the TODO the legacy test carried: it asserted exit 0 while
wishing for an error, and the CLI has since started validating selected
services.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-08-18 16:49:56 +02:00
Nicolas De Loof
b2e3deb18e test(e2e): testdata/<TestName>/ anchors each scenario's project files
Each scenario resolves its project files from testdata/<TestName>/ by
convention: standalone compose files in their native format, directly
runnable with docker compose -f, copied to a temporary directory so the
committed files are never mutated. Subtests map to nested directories.

Ownership is strictly one test per directory: a check fails the suite on
any testdata directory no test owns, which is what keeps this from
degrading into a catch-all fixtures directory — no sharing, no
leftovers after a rename.

The inline Compose() declaration is removed; the demonstrator scenarios
move their models to testdata, including the multi-file build context
of TestUpBuildUnchangedContext (compose.yaml + Dockerfile + marker).

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2026-08-18 16:49:56 +02:00