Skip to content

Commit

Permalink
command: add tests for container diff and rename
Browse files Browse the repository at this point in the history
This commit adds tests for the commands
docker diff and docker rename. Also,
it creates the mock methods of the
docker client ContainerDiff and
ContainerRename so they can
be used in the tests.

For docker diff, it covers the
cases that:
 - the command runs successfully
 - the client returns an error
 - the container id is empty

For docker rename, it covers
the cases that:
 - the command runs successfully
 - the container old name is empty
 - the container new name is empty
 - the client returns an error

Co-authored-by: Laura Brehm <[email protected]>
Signed-off-by: Stavros Panakakis <[email protected]>
  • Loading branch information
Stavrospanakakis and laurazard committed Sep 23, 2024
1 parent baa7a9f commit 46b360b
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 0 deletions.
18 changes: 18 additions & 0 deletions cli/command/container/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type fakeClient struct {
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)
containerDiffFunc func(ctx context.Context, containerID string) ([]container.FilesystemChange, error)
containerRenameFunc func(ctx context.Context, oldName, newName string) error
Version string
}

Expand Down Expand Up @@ -181,3 +183,19 @@ func (f *fakeClient) ContainerAttach(ctx context.Context, containerID string, op
}
return types.HijackedResponse{}, nil
}

func (f *fakeClient) ContainerDiff(ctx context.Context, containerID string) ([]container.FilesystemChange, error) {
if f.containerDiffFunc != nil {
return f.containerDiffFunc(ctx, containerID)
}

return []container.FilesystemChange{}, nil
}

func (f *fakeClient) ContainerRename(ctx context.Context, oldName, newName string) error {
if f.containerRenameFunc != nil {
return f.containerRenameFunc(ctx, oldName, newName)
}

return nil
}
93 changes: 93 additions & 0 deletions cli/command/container/diff_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package container

import (
"context"
"io"
"strings"
"testing"

"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/container"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)

func TestRunDiff(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerDiffFunc: func(
ctx context.Context,
containerID string,
) ([]container.FilesystemChange, error) {
return []container.FilesystemChange{
{
Kind: container.ChangeModify,
Path: "/path/to/file0",
},
{
Kind: container.ChangeAdd,
Path: "/path/to/file1",
},
{
Kind: container.ChangeDelete,
Path: "/path/to/file2",
},
}, nil
},
})

cmd := NewDiffCommand(cli)
cmd.SetOut(io.Discard)

cmd.SetArgs([]string{"container-id"})

err := cmd.Execute()
assert.NilError(t, err)

diff := strings.SplitN(cli.OutBuffer().String(), "\n", 3)
assert.Assert(t, is.Len(diff, 3))

file0 := strings.TrimSpace(diff[0])
file1 := strings.TrimSpace(diff[1])
file2 := strings.TrimSpace(diff[2])

assert.Check(t, is.Equal(file0, "C /path/to/file0"))
assert.Check(t, is.Equal(file1, "A /path/to/file1"))
assert.Check(t, is.Equal(file2, "D /path/to/file2"))
}

func TestRunDiffClientError(t *testing.T) {
clientError := errors.New("client error")

cli := test.NewFakeCli(&fakeClient{
containerDiffFunc: func(
ctx context.Context,
containerID string,
) ([]container.FilesystemChange, error) {
return nil, clientError
},
})

cmd := NewDiffCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)

cmd.SetArgs([]string{"container-id"})

err := cmd.Execute()
assert.ErrorIs(t, err, clientError)
}

func TestRunDiffEmptyContainerError(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})

cmd := NewDiffCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)

containerID := ""
cmd.SetArgs([]string{containerID})

err := cmd.Execute()
assert.Error(t, err, "Container name cannot be empty")
}
77 changes: 77 additions & 0 deletions cli/command/container/rename_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package container

import (
"context"
"io"
"testing"

"github.com/docker/cli/internal/test"
"github.com/pkg/errors"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)

func TestRunRename(t *testing.T) {
testcases := []struct {
doc, oldName, newName, expectedErr string
}{
{
doc: "success",
oldName: "oldName",
newName: "newName",
expectedErr: "",
},
{
doc: "empty old name",
oldName: "",
newName: "newName",
expectedErr: "Error: Neither old nor new names may be empty",
},
{
doc: "empty new name",
oldName: "oldName",
newName: "",
expectedErr: "Error: Neither old nor new names may be empty",
},
}

for _, tc := range testcases {
t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerRenameFunc: func(ctx context.Context, oldName, newName string) error {
return nil
},
})

cmd := NewRenameCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{tc.oldName, tc.newName})

err := cmd.Execute()

if tc.expectedErr != "" {
assert.ErrorContains(t, err, tc.expectedErr)
} else {
assert.NilError(t, err)
}
})
}
}

func TestRunRenameClientError(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerRenameFunc: func(ctx context.Context, oldName, newName string) error {
return errors.New("client error")
},
})

cmd := NewRenameCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"oldName", "newName"})

err := cmd.Execute()

assert.Check(t, is.Error(err, "Error: failed to rename container named oldName"))
}

0 comments on commit 46b360b

Please sign in to comment.