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>
- 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>
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>
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>
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>
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>
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>
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>