diff --git a/pkg/compose/wait.go b/pkg/compose/wait.go index 622803e9b..32c34ce4d 100644 --- a/pkg/compose/wait.go +++ b/pkg/compose/wait.go @@ -18,6 +18,7 @@ package compose import ( "context" + "errors" "fmt" "github.com/moby/moby/client" @@ -27,6 +28,12 @@ import ( ) func (s *composeService) Wait(ctx context.Context, projectName string, options api.WaitOptions) (int64, error) { + if s.dryRun { + // dry-run never starts a real container, so there is nothing for + // wait to observe: refuse upfront instead of racing the fake API + // client into a misleading "no containers" error. + return 0, errors.New("wait is not supported in dry-run mode") + } containers, err := s.getContainers(ctx, projectName, oneOffInclude, false, options.Services...) if err != nil { return 0, err diff --git a/pkg/compose/wait_test.go b/pkg/compose/wait_test.go index f86b3c7a7..493663117 100644 --- a/pkg/compose/wait_test.go +++ b/pkg/compose/wait_test.go @@ -82,6 +82,18 @@ func TestWait_NoContainersAtAll(t *testing.T) { assert.Equal(t, *allCalls, 1) } +// TestWait_DryRunNotSupported: dry-run refuses immediately, without +// listing containers. +func TestWait_DryRunNotSupported(t *testing.T) { + tested, _, runningCalls, allCalls := waitTestService(t, nil, nil) + tested.(*composeService).dryRun = true + + _, err := tested.Wait(t.Context(), "proj", api.WaitOptions{}) + assert.ErrorContains(t, err, "not supported in dry-run mode") + assert.Equal(t, *runningCalls, 0) + assert.Equal(t, *allCalls, 0) +} + // TestWait_RunningContainersSkipFallback: with a running container to // observe, the fallback listing never runs — a stale exited one-off cannot // short-circuit the wait.