From ac502b5909e644d017c145402c62479568c98702 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 26 Sep 2024 18:53:10 +0200 Subject: [PATCH] cli/command/container: add unit tests for container stop Signed-off-by: Sebastiaan van Stijn --- cli/command/container/client_test.go | 8 +++ cli/command/container/stop_test.go | 86 ++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 cli/command/container/stop_test.go diff --git a/cli/command/container/client_test.go b/cli/command/container/client_test.go index 8b3b0cd97ea9..adc39f9bedb4 100644 --- a/cli/command/container/client_test.go +++ b/cli/command/container/client_test.go @@ -36,6 +36,7 @@ type fakeClient struct { containerExecResizeFunc func(id string, options container.ResizeOptions) error containerRemoveFunc func(ctx context.Context, containerID string, options container.RemoveOptions) error containerRestartFunc func(ctx context.Context, containerID string, options container.StopOptions) error + containerStopFunc func(ctx context.Context, containerID string, options container.StopOptions) error containerKillFunc func(ctx context.Context, containerID, signal string) error containerPruneFunc func(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) containerAttachFunc func(ctx context.Context, containerID string, options container.AttachOptions) (types.HijackedResponse, error) @@ -183,6 +184,13 @@ func (f *fakeClient) ContainerRestart(ctx context.Context, containerID string, o return nil } +func (f *fakeClient) ContainerStop(ctx context.Context, containerID string, options container.StopOptions) error { + if f.containerStopFunc != nil { + return f.containerStopFunc(ctx, containerID, options) + } + return nil +} + func (f *fakeClient) ContainerAttach(ctx context.Context, containerID string, options container.AttachOptions) (types.HijackedResponse, error) { if f.containerAttachFunc != nil { return f.containerAttachFunc(ctx, containerID, options) diff --git a/cli/command/container/stop_test.go b/cli/command/container/stop_test.go new file mode 100644 index 000000000000..44893d68abd9 --- /dev/null +++ b/cli/command/container/stop_test.go @@ -0,0 +1,86 @@ +package container + +import ( + "context" + "io" + "sort" + "sync" + "testing" + + "github.com/docker/cli/internal/test" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/errdefs" + "github.com/pkg/errors" + "gotest.tools/v3/assert" + is "gotest.tools/v3/assert/cmp" +) + +func TestStop(t *testing.T) { + for _, tc := range []struct { + name string + args []string + stopped []string + expectedOpts container.StopOptions + expectedErr string + }{ + { + name: "without options", + args: []string{"container-1", "container-2"}, + stopped: []string{"container-1", "container-2"}, + }, + { + name: "with unknown container", + args: []string{"container-1", "nosuchcontainer", "container-2"}, + expectedErr: "no such container", + stopped: []string{"container-1", "container-2"}, + }, + { + name: "with -t", + args: []string{"-t", "2", "container-1"}, + expectedOpts: container.StopOptions{Timeout: func(to int) *int { return &to }(2)}, + stopped: []string{"container-1"}, + }, + { + name: "with --time", + args: []string{"--time", "2", "container-1"}, + expectedOpts: container.StopOptions{Timeout: func(to int) *int { return &to }(2)}, + stopped: []string{"container-1"}, + }, + } { + tc := tc + t.Run(tc.name, func(t *testing.T) { + var stopped []string + mutex := new(sync.Mutex) + + cli := test.NewFakeCli(&fakeClient{ + containerStopFunc: func(ctx context.Context, containerID string, options container.StopOptions) error { + assert.Check(t, is.DeepEqual(options, tc.expectedOpts)) + if containerID == "nosuchcontainer" { + return errdefs.NotFound(errors.New("Error: no such container: " + containerID)) + } + + // containerStopFunc is called in parallel for each container + // so append must be synchronized. + mutex.Lock() + stopped = append(stopped, containerID) + mutex.Unlock() + return nil + }, + Version: "1.36", + }) + cmd := NewStopCommand(cli) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + cmd.SetArgs(tc.args) + + err := cmd.Execute() + if tc.expectedErr != "" { + assert.Check(t, is.ErrorContains(err, tc.expectedErr)) + } else { + assert.Check(t, is.Nil(err)) + } + sort.Strings(stopped) + assert.Check(t, is.DeepEqual(stopped, tc.stopped)) + }) + } +}