test spring-cleaning

This makes a quick pass through our tests;

Discard output/err
----------------------------------------------

Many tests were testing for error-conditions, but didn't discard output.
This produced a lot of noise when running the tests, and made it hard
to discover if there were actual failures, or if the output was expected.
For example:

    === RUN   TestConfigCreateErrors
    Error: "create" requires exactly 2 arguments.
    See 'create --help'.

    Usage:  create [OPTIONS] CONFIG file|- [flags]

    Create a config from a file or STDIN
    Error: "create" requires exactly 2 arguments.
    See 'create --help'.

    Usage:  create [OPTIONS] CONFIG file|- [flags]

    Create a config from a file or STDIN
    Error: error creating config
    --- PASS: TestConfigCreateErrors (0.00s)

And after discarding output:

    === RUN   TestConfigCreateErrors
    --- PASS: TestConfigCreateErrors (0.00s)

Use sub-tests where possible
----------------------------------------------

Some tests were already set-up to use test-tables, and even had a usable
name (or in some cases "error" to check for). Change them to actual sub-
tests. Same test as above, but now with sub-tests and output discarded:

    === RUN   TestConfigCreateErrors
    === RUN   TestConfigCreateErrors/requires_exactly_2_arguments
    === RUN   TestConfigCreateErrors/requires_exactly_2_arguments#01
    === RUN   TestConfigCreateErrors/error_creating_config
    --- PASS: TestConfigCreateErrors (0.00s)
        --- PASS: TestConfigCreateErrors/requires_exactly_2_arguments (0.00s)
        --- PASS: TestConfigCreateErrors/requires_exactly_2_arguments#01 (0.00s)
        --- PASS: TestConfigCreateErrors/error_creating_config (0.00s)
    PASS

It's not perfect in all cases (in the above, there's duplicate "expected"
errors, but Go conveniently adds "#01" for the duplicate). There's probably
also various tests I missed that could still use the same changes applied;
we can improve these in follow-ups.

Set cmd.Args to prevent test-failures
----------------------------------------------

When running tests from my IDE, it compiles the tests before running,
then executes the compiled binary to run the tests. Cobra doesn't like
that, because in that situation `os.Args` is taken as argument for the
command that's executed. The command that's tested now sees the test-
flags as arguments (`-test.v -test.run ..`), which causes various tests
to fail ("Command XYZ does not accept arguments").

    # compile the tests:
    go test -c -o foo.test

    # execute the test:
    ./foo.test -test.v -test.run TestFoo
    === RUN   TestFoo
    Error: "foo" accepts no arguments.

The Cobra maintainers ran into the same situation, and for their own
use have added a special case to ignore `os.Args` in these cases;
https://github.com/spf13/cobra/blob/v1.8.1/command.go#L1078-L1083

    args := c.args

    // Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
    if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
        args = os.Args[1:]
    }

Unfortunately, that exception is too specific (only checks for `cobra.test`),
so doesn't automatically fix the issue for other test-binaries. They did
provide a `cmd.SetArgs()` utility for this purpose
https://github.com/spf13/cobra/blob/v1.8.1/command.go#L276-L280

    // SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
    // particularly useful when testing.
    func (c *Command) SetArgs(a []string) {
        c.args = a
    }

And the fix is to explicitly set the command's args to an empty slice to
prevent Cobra from falling back to using `os.Args[1:]` as arguments.

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

Some tests already take this issue into account, and I updated some tests
for this, but there's likely many other ones that can use the same treatment.

Perhaps the Cobra maintainers would accept a contribution to make their
condition less specific and to look for binaries ending with a `.test`
suffix (which is what compiled binaries usually are named as).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ab230240ad)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2024-07-04 01:29:04 +02:00
parent a2a0fb73ea
commit ca9636a1c3
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
87 changed files with 676 additions and 372 deletions

View File

@ -3,6 +3,7 @@ package builder
import ( import (
"context" "context"
"errors" "errors"
"io"
"testing" "testing"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
@ -19,5 +20,7 @@ func TestBuilderPromptTermination(t *testing.T) {
}, },
}) })
cmd := NewPruneCommand(cli) cmd := NewPruneCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli) test.TerminatePrompt(ctx, t, cmd, cli)
} }

View File

@ -42,6 +42,7 @@ func TestCheckpointCreateErrors(t *testing.T) {
cmd := newCreateCommand(cli) cmd := newCreateCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -42,6 +42,7 @@ func TestCheckpointListErrors(t *testing.T) {
cmd := newListCommand(cli) cmd := newListCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -41,6 +41,7 @@ func TestCheckpointRemoveErrors(t *testing.T) {
cmd := newRemoveCommand(cli) cmd := newRemoveCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -43,14 +43,18 @@ func TestConfigCreateErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newConfigCreateCommand( tc := tc
test.NewFakeCli(&fakeClient{ t.Run(tc.expectedError, func(t *testing.T) {
configCreateFunc: tc.configCreateFunc, cmd := newConfigCreateCommand(
}), test.NewFakeCli(&fakeClient{
) configCreateFunc: tc.configCreateFunc,
cmd.SetArgs(tc.args) }),
cmd.SetOut(io.Discard) )
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }

View File

@ -61,6 +61,7 @@ func TestConfigInspectErrors(t *testing.T) {
assert.Check(t, cmd.Flags().Set(key, value)) assert.Check(t, cmd.Flags().Set(key, value))
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -42,6 +42,7 @@ func TestConfigListErrors(t *testing.T) {
) )
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -37,6 +37,7 @@ func TestConfigRemoveErrors(t *testing.T) {
) )
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -74,6 +75,7 @@ func TestConfigRemoveContinueAfterError(t *testing.T) {
cmd := newConfigRemoveCommand(cli) cmd := newConfigRemoveCommand(cli)
cmd.SetArgs(names) cmd.SetArgs(names)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.Error(t, cmd.Execute(), "error removing config: foo") assert.Error(t, cmd.Execute(), "error removing config: foo")
assert.Check(t, is.DeepEqual(names, removedConfigs)) assert.Check(t, is.DeepEqual(names, removedConfigs))
} }

View File

@ -69,10 +69,14 @@ func TestNewAttachCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc})) tc := tc
cmd.SetOut(io.Discard) t.Run(tc.name, func(t *testing.T) {
cmd.SetArgs(tc.args) cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc}))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }

View File

@ -178,13 +178,14 @@ func TestSplitCpArg(t *testing.T) {
expectedContainer: "container", expectedContainer: "container",
}, },
} }
for _, testcase := range testcases { for _, tc := range testcases {
t.Run(testcase.doc, func(t *testing.T) { tc := tc
skip.If(t, testcase.os != "" && testcase.os != runtime.GOOS) t.Run(tc.doc, func(t *testing.T) {
skip.If(t, tc.os == "windows" && runtime.GOOS != "windows" || tc.os == "linux" && runtime.GOOS == "windows")
ctr, path := splitCpArg(testcase.path) ctr, path := splitCpArg(tc.path)
assert.Check(t, is.Equal(testcase.expectedContainer, ctr)) assert.Check(t, is.Equal(tc.expectedContainer, ctr))
assert.Check(t, is.Equal(testcase.expectedPath, path)) assert.Check(t, is.Equal(tc.expectedPath, path))
}) })
} }
} }

View File

@ -236,6 +236,7 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) {
fakeCLI.SetNotaryClient(tc.notaryFunc) fakeCLI.SetNotaryClient(tc.notaryFunc)
cmd := NewCreateCommand(fakeCLI) cmd := NewCreateCommand(fakeCLI)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
err := cmd.Execute() err := cmd.Execute()
assert.ErrorContains(t, err, tc.expectedError) assert.ErrorContains(t, err, tc.expectedError)

View File

@ -39,6 +39,7 @@ func TestContainerExportOutputToIrregularFile(t *testing.T) {
}) })
cmd := NewExportCommand(cli) cmd := NewExportCommand(cli)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"-o", "/dev/random", "container"}) cmd.SetArgs([]string{"-o", "/dev/random", "container"})
err := cmd.Execute() err := cmd.Execute()

View File

@ -163,6 +163,7 @@ func TestContainerListErrors(t *testing.T) {
assert.Check(t, cmd.Flags().Set(key, value)) assert.Check(t, cmd.Flags().Set(key, value))
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -2,6 +2,7 @@ package container
import ( import (
"context" "context"
"io"
"testing" "testing"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
@ -20,5 +21,7 @@ func TestContainerPrunePromptTermination(t *testing.T) {
}, },
}) })
cmd := NewPruneCommand(cli) cmd := NewPruneCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli) test.TerminatePrompt(ctx, t, cmd, cli)
} }

View File

@ -45,6 +45,7 @@ func TestRemoveForce(t *testing.T) {
}) })
cmd := NewRmCommand(cli) cmd := NewRmCommand(cli)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
err := cmd.Execute() err := cmd.Execute()

View File

@ -127,23 +127,27 @@ func TestRunCommandWithContentTrustErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
fakeCLI := test.NewFakeCli(&fakeClient{ tc := tc
createContainerFunc: func(config *container.Config, t.Run(tc.name, func(t *testing.T) {
hostConfig *container.HostConfig, fakeCLI := test.NewFakeCli(&fakeClient{
networkingConfig *network.NetworkingConfig, createContainerFunc: func(config *container.Config,
platform *specs.Platform, hostConfig *container.HostConfig,
containerName string, networkingConfig *network.NetworkingConfig,
) (container.CreateResponse, error) { platform *specs.Platform,
return container.CreateResponse{}, errors.New("shouldn't try to pull image") containerName string,
}, ) (container.CreateResponse, error) {
}, test.EnableContentTrust) return container.CreateResponse{}, errors.New("shouldn't try to pull image")
fakeCLI.SetNotaryClient(tc.notaryFunc) },
cmd := NewRunCommand(fakeCLI) }, test.EnableContentTrust)
cmd.SetArgs(tc.args) fakeCLI.SetNotaryClient(tc.notaryFunc)
cmd.SetOut(io.Discard) cmd := NewRunCommand(fakeCLI)
err := cmd.Execute() cmd.SetArgs(tc.args)
assert.Assert(t, err != nil) cmd.SetOut(io.Discard)
assert.Assert(t, is.Contains(fakeCLI.ErrBuffer().String(), tc.expectedError)) cmd.SetErr(io.Discard)
err := cmd.Execute()
assert.Assert(t, err != nil)
assert.Assert(t, is.Contains(fakeCLI.ErrBuffer().String(), tc.expectedError))
})
} }
} }

View File

@ -127,6 +127,7 @@ func TestRunBuildFromGitHubSpecialCase(t *testing.T) {
// Clone a small repo that exists so git doesn't prompt for credentials // Clone a small repo that exists so git doesn't prompt for credentials
cmd.SetArgs([]string{"github.com/docker/for-win"}) cmd.SetArgs([]string{"github.com/docker/for-win"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
err := cmd.Execute() err := cmd.Execute()
assert.ErrorContains(t, err, "unable to prepare context") assert.ErrorContains(t, err, "unable to prepare context")
assert.ErrorContains(t, err, "docker-build-git") assert.ErrorContains(t, err, "docker-build-git")

View File

@ -35,10 +35,14 @@ func TestNewHistoryCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc})) tc := tc
cmd.SetOut(io.Discard) t.Run(tc.name, func(t *testing.T) {
cmd.SetArgs(tc.args) cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc}))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }

View File

@ -36,6 +36,7 @@ func TestNewImportCommandErrors(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc})) cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
@ -44,6 +45,7 @@ func TestNewImportCommandErrors(t *testing.T) {
func TestNewImportCommandInvalidFile(t *testing.T) { func TestNewImportCommandInvalidFile(t *testing.T) {
cmd := NewImportCommand(test.NewFakeCli(&fakeClient{})) cmd := NewImportCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"testdata/import-command-success.unexistent-file"}) cmd.SetArgs([]string{"testdata/import-command-success.unexistent-file"})
assert.ErrorContains(t, cmd.Execute(), "testdata/import-command-success.unexistent-file") assert.ErrorContains(t, cmd.Execute(), "testdata/import-command-success.unexistent-file")
} }
@ -96,9 +98,13 @@ func TestNewImportCommandSuccess(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc})) tc := tc
cmd.SetOut(io.Discard) t.Run(tc.name, func(t *testing.T) {
cmd.SetArgs(tc.args) cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc}))
assert.NilError(t, cmd.Execute()) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.NilError(t, cmd.Execute())
})
} }
} }

View File

@ -25,10 +25,14 @@ func TestNewInspectCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newInspectCommand(test.NewFakeCli(&fakeClient{})) tc := tc
cmd.SetOut(io.Discard) t.Run(tc.name, func(t *testing.T) {
cmd.SetArgs(tc.args) cmd := newInspectCommand(test.NewFakeCli(&fakeClient{}))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }

View File

@ -35,10 +35,14 @@ func TestNewImagesCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := NewImagesCommand(test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc})) tc := tc
cmd.SetOut(io.Discard) t.Run(tc.name, func(t *testing.T) {
cmd.SetArgs(tc.args) cmd := NewImagesCommand(test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc}))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -79,14 +83,18 @@ func TestNewImagesCommandSuccess(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc}) tc := tc
cli.SetConfigFile(&configfile.ConfigFile{ImagesFormat: tc.imageFormat}) t.Run(tc.name, func(t *testing.T) {
cmd := NewImagesCommand(cli) cli := test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc})
cmd.SetOut(io.Discard) cli.SetConfigFile(&configfile.ConfigFile{ImagesFormat: tc.imageFormat})
cmd.SetArgs(tc.args) cmd := NewImagesCommand(cli)
err := cmd.Execute() cmd.SetOut(io.Discard)
assert.NilError(t, err) cmd.SetErr(io.Discard)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("list-command-success.%s.golden", tc.name)) cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("list-command-success.%s.golden", tc.name))
})
} }
} }

View File

@ -40,12 +40,16 @@ func TestNewLoadCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc}) tc := tc
cli.In().SetIsTerminal(tc.isTerminalIn) t.Run(tc.name, func(t *testing.T) {
cmd := NewLoadCommand(cli) cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc})
cmd.SetOut(io.Discard) cli.In().SetIsTerminal(tc.isTerminalIn)
cmd.SetArgs(tc.args) cmd := NewLoadCommand(cli)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -53,6 +57,7 @@ func TestNewLoadCommandInvalidInput(t *testing.T) {
expectedError := "open *" expectedError := "open *"
cmd := NewLoadCommand(test.NewFakeCli(&fakeClient{})) cmd := NewLoadCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"--input", "*"}) cmd.SetArgs([]string{"--input", "*"})
err := cmd.Execute() err := cmd.Execute()
assert.ErrorContains(t, err, expectedError) assert.ErrorContains(t, err, expectedError)
@ -89,12 +94,15 @@ func TestNewLoadCommandSuccess(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc}) tc := tc
cmd := NewLoadCommand(cli) t.Run(tc.name, func(t *testing.T) {
cmd.SetOut(io.Discard) cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc})
cmd.SetArgs(tc.args) cmd := NewLoadCommand(cli)
err := cmd.Execute() cmd.SetOut(io.Discard)
assert.NilError(t, err) cmd.SetArgs(tc.args)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("load-command-success.%s.golden", tc.name)) err := cmd.Execute()
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("load-command-success.%s.golden", tc.name))
})
} }
} }

View File

@ -39,12 +39,16 @@ func TestNewPruneCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := NewPruneCommand(test.NewFakeCli(&fakeClient{ tc := tc
imagesPruneFunc: tc.imagesPruneFunc, t.Run(tc.name, func(t *testing.T) {
})) cmd := NewPruneCommand(test.NewFakeCli(&fakeClient{
cmd.SetOut(io.Discard) imagesPruneFunc: tc.imagesPruneFunc,
cmd.SetArgs(tc.args) }))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -94,6 +98,7 @@ func TestNewPruneCommandSuccess(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{imagesPruneFunc: tc.imagesPruneFunc}) cli := test.NewFakeCli(&fakeClient{imagesPruneFunc: tc.imagesPruneFunc})
// when prompted, answer "Y" to confirm the prune. // when prompted, answer "Y" to confirm the prune.
@ -119,5 +124,8 @@ func TestPrunePromptTermination(t *testing.T) {
}, },
}) })
cmd := NewPruneCommand(cli) cmd := NewPruneCommand(cli)
cmd.SetArgs([]string{})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli) test.TerminatePrompt(ctx, t, cmd, cli)
} }

View File

@ -38,11 +38,15 @@ func TestNewPullCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{}) tc := tc
cmd := NewPullCommand(cli) t.Run(tc.name, func(t *testing.T) {
cmd.SetOut(io.Discard) cli := test.NewFakeCli(&fakeClient{})
cmd.SetArgs(tc.args) cmd := NewPullCommand(cli)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -69,18 +73,22 @@ func TestNewPullCommandSuccess(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) { t.Run(tc.name, func(t *testing.T) {
assert.Check(t, is.Equal(tc.expectedTag, ref), tc.name) cli := test.NewFakeCli(&fakeClient{
return io.NopCloser(strings.NewReader("")), nil imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) {
}, assert.Check(t, is.Equal(tc.expectedTag, ref), tc.name)
return io.NopCloser(strings.NewReader("")), nil
},
})
cmd := NewPullCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("pull-command-success.%s.golden", tc.name))
}) })
cmd := NewPullCommand(cli)
cmd.SetOut(io.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("pull-command-success.%s.golden", tc.name))
} }
} }
@ -111,16 +119,20 @@ func TestNewPullCommandWithContentTrustErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) { t.Run(tc.name, func(t *testing.T) {
return io.NopCloser(strings.NewReader("")), errors.New("shouldn't try to pull image") cli := test.NewFakeCli(&fakeClient{
}, imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) {
}, test.EnableContentTrust) return io.NopCloser(strings.NewReader("")), errors.New("shouldn't try to pull image")
cli.SetNotaryClient(tc.notaryFunc) },
cmd := NewPullCommand(cli) }, test.EnableContentTrust)
cmd.SetOut(io.Discard) cli.SetNotaryClient(tc.notaryFunc)
cmd.SetArgs(tc.args) cmd := NewPullCommand(cli)
err := cmd.Execute() cmd.SetOut(io.Discard)
assert.ErrorContains(t, err, tc.expectedError) cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.ErrorContains(t, err, tc.expectedError)
})
} }
} }

View File

@ -38,11 +38,15 @@ func TestNewPushCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc}) tc := tc
cmd := NewPushCommand(cli) t.Run(tc.name, func(t *testing.T) {
cmd.SetOut(io.Discard) cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc})
cmd.SetArgs(tc.args) cmd := NewPushCommand(cli)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -73,6 +77,7 @@ func TestNewPushCommandSuccess(t *testing.T) {
}) })
cmd := NewPushCommand(cli) cmd := NewPushCommand(cli)
cmd.SetOut(cli.OutBuffer()) cmd.SetOut(cli.OutBuffer())
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
assert.NilError(t, cmd.Execute()) assert.NilError(t, cmd.Execute())
if tc.output != "" { if tc.output != "" {

View File

@ -62,11 +62,13 @@ func TestNewRemoveCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
cmd := NewRemoveCommand(test.NewFakeCli(&fakeClient{ cmd := NewRemoveCommand(test.NewFakeCli(&fakeClient{
imageRemoveFunc: tc.imageRemoveFunc, imageRemoveFunc: tc.imageRemoveFunc,
})) }))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}) })
@ -119,10 +121,12 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{imageRemoveFunc: tc.imageRemoveFunc}) cli := test.NewFakeCli(&fakeClient{imageRemoveFunc: tc.imageRemoveFunc})
cmd := NewRemoveCommand(cli) cmd := NewRemoveCommand(cli)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
assert.NilError(t, cmd.Execute()) assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal(tc.expectedStderr, cli.ErrBuffer().String())) assert.Check(t, is.Equal(tc.expectedStderr, cli.ErrBuffer().String()))

View File

@ -52,12 +52,16 @@ func TestNewSaveCommandErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{imageSaveFunc: tc.imageSaveFunc}) tc := tc
cli.Out().SetIsTerminal(tc.isTerminal) t.Run(tc.name, func(t *testing.T) {
cmd := NewSaveCommand(cli) cli := test.NewFakeCli(&fakeClient{imageSaveFunc: tc.imageSaveFunc})
cmd.SetOut(io.Discard) cli.Out().SetIsTerminal(tc.isTerminal)
cmd.SetArgs(tc.args) cmd := NewSaveCommand(cli)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -77,7 +81,7 @@ func TestNewSaveCommandSuccess(t *testing.T) {
return io.NopCloser(strings.NewReader("")), nil return io.NopCloser(strings.NewReader("")), nil
}, },
deferredFunc: func() { deferredFunc: func() {
os.Remove("save_tmp_file") _ = os.Remove("save_tmp_file")
}, },
}, },
{ {
@ -92,16 +96,20 @@ func TestNewSaveCommandSuccess(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := NewSaveCommand(test.NewFakeCli(&fakeClient{ tc := tc
imageSaveFunc: func(images []string) (io.ReadCloser, error) { t.Run(strings.Join(tc.args, " "), func(t *testing.T) {
return io.NopCloser(strings.NewReader("")), nil cmd := NewSaveCommand(test.NewFakeCli(&fakeClient{
}, imageSaveFunc: func(images []string) (io.ReadCloser, error) {
})) return io.NopCloser(strings.NewReader("")), nil
cmd.SetOut(io.Discard) },
cmd.SetArgs(tc.args) }))
assert.NilError(t, cmd.Execute()) cmd.SetOut(io.Discard)
if tc.deferredFunc != nil { cmd.SetErr(io.Discard)
tc.deferredFunc() cmd.SetArgs(tc.args)
} assert.NilError(t, cmd.Execute())
if tc.deferredFunc != nil {
tc.deferredFunc()
}
})
} }
} }

View File

@ -20,6 +20,7 @@ func TestCliNewTagCommandErrors(t *testing.T) {
cmd := NewTagCommand(test.NewFakeCli(&fakeClient{})) cmd := NewTagCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetArgs(args) cmd.SetArgs(args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), expectedError) assert.ErrorContains(t, cmd.Execute(), expectedError)
} }
} }

View File

@ -35,6 +35,7 @@ func TestManifestAnnotateError(t *testing.T) {
cmd := newAnnotateCommand(cli) cmd := newAnnotateCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -52,6 +53,7 @@ func TestManifestAnnotate(t *testing.T) {
cmd := newAnnotateCommand(cli) cmd := newAnnotateCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/fake:0.0"}) cmd.SetArgs([]string{"example.com/list:v1", "example.com/fake:0.0"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
expectedError := "manifest for image example.com/fake:0.0 does not exist" expectedError := "manifest for image example.com/fake:0.0 does not exist"
assert.ErrorContains(t, cmd.Execute(), expectedError) assert.ErrorContains(t, cmd.Execute(), expectedError)
@ -71,6 +73,7 @@ func TestManifestAnnotate(t *testing.T) {
err = cmd.Flags().Set("verbose", "true") err = cmd.Flags().Set("verbose", "true")
assert.NilError(t, err) assert.NilError(t, err)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"}) cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.SetErr(io.Discard)
assert.NilError(t, cmd.Execute()) assert.NilError(t, cmd.Execute())
actual := cli.OutBuffer() actual := cli.OutBuffer()
expected := golden.Get(t, "inspect-annotate.golden") expected := golden.Get(t, "inspect-annotate.golden")

View File

@ -31,11 +31,15 @@ func TestManifestCreateErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(nil) tc := tc
cmd := newCreateListCommand(cli) t.Run(tc.expectedError, func(t *testing.T) {
cmd.SetArgs(tc.args) cli := test.NewFakeCli(nil)
cmd.SetOut(io.Discard) cmd := newCreateListCommand(cli)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -87,6 +91,7 @@ func TestManifestCreateRefuseAmend(t *testing.T) {
cmd := newCreateListCommand(cli) cmd := newCreateListCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"}) cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
err = cmd.Execute() err = cmd.Execute()
assert.Error(t, err, "refusing to amend an existing manifest list with no --amend flag") assert.Error(t, err, "refusing to amend an existing manifest list with no --amend flag")
} }
@ -109,6 +114,7 @@ func TestManifestCreateNoManifest(t *testing.T) {
cmd := newCreateListCommand(cli) cmd := newCreateListCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"}) cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
err := cmd.Execute() err := cmd.Execute()
assert.Error(t, err, "No such image: example.com/alpine:3.0") assert.Error(t, err, "No such image: example.com/alpine:3.0")
} }

View File

@ -70,6 +70,7 @@ func TestInspectCommandLocalManifestNotFound(t *testing.T) {
cmd := newInspectCommand(cli) cmd := newInspectCommand(cli)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"}) cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
err := cmd.Execute() err := cmd.Execute()
assert.Error(t, err, "No such manifest: example.com/alpine:3.0") assert.Error(t, err, "No such manifest: example.com/alpine:3.0")
@ -91,6 +92,7 @@ func TestInspectCommandNotFound(t *testing.T) {
cmd := newInspectCommand(cli) cmd := newInspectCommand(cli)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"example.com/alpine:3.0"}) cmd.SetArgs([]string{"example.com/alpine:3.0"})
err := cmd.Execute() err := cmd.Execute()
assert.Error(t, err, "No such manifest: example.com/alpine:3.0") assert.Error(t, err, "No such manifest: example.com/alpine:3.0")

View File

@ -44,6 +44,7 @@ func TestManifestPushErrors(t *testing.T) {
cmd := newPushListCommand(cli) cmd := newPushListCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -56,6 +56,7 @@ func TestRmManifestNotCreated(t *testing.T) {
cmd := newRmManifestListCommand(cli) cmd := newRmManifestListCommand(cli)
cmd.SetArgs([]string{"example.com/first:1", "example.com/second:2"}) cmd.SetArgs([]string{"example.com/first:1", "example.com/second:2"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
err = cmd.Execute() err = cmd.Execute()
assert.Error(t, err, "No such manifest: example.com/first:1") assert.Error(t, err, "No such manifest: example.com/first:1")

View File

@ -38,6 +38,7 @@ func TestNetworkConnectErrors(t *testing.T) {
) )
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -137,6 +137,7 @@ func TestNetworkCreateErrors(t *testing.T) {
assert.NilError(t, cmd.Flags().Set(key, value)) assert.NilError(t, cmd.Flags().Set(key, value))
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -36,6 +36,7 @@ func TestNetworkDisconnectErrors(t *testing.T) {
) )
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -36,6 +36,7 @@ func TestNetworkListErrors(t *testing.T) {
}), }),
) )
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -82,6 +83,7 @@ func TestNetworkList(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{networkListFunc: tc.networkListFunc}) cli := test.NewFakeCli(&fakeClient{networkListFunc: tc.networkListFunc})
cmd := newListCommand(cli) cmd := newListCommand(cli)

View File

@ -2,6 +2,7 @@ package network
import ( import (
"context" "context"
"io"
"testing" "testing"
"github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test"
@ -20,5 +21,8 @@ func TestNetworkPrunePromptTermination(t *testing.T) {
}, },
}) })
cmd := NewPruneCommand(cli) cmd := NewPruneCommand(cli)
cmd.SetArgs([]string{})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli) test.TerminatePrompt(ctx, t, cmd, cli)
} }

View File

@ -114,5 +114,7 @@ func TestNetworkRemovePromptTermination(t *testing.T) {
}) })
cmd := newRemoveCommand(cli) cmd := newRemoveCommand(cli)
cmd.SetArgs([]string{"existing-network"}) cmd.SetArgs([]string{"existing-network"})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli) test.TerminatePrompt(ctx, t, cmd, cli)
} }

View File

@ -44,6 +44,7 @@ func TestNodeDemoteErrors(t *testing.T) {
})) }))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -74,6 +74,7 @@ func TestNodeInspectErrors(t *testing.T) {
assert.Check(t, cmd.Flags().Set(key, value)) assert.Check(t, cmd.Flags().Set(key, value))
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -105,13 +106,16 @@ func TestNodeInspectPretty(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
nodeInspectFunc: tc.nodeInspectFunc, t.Run(tc.name, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
nodeInspectFunc: tc.nodeInspectFunc,
})
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"nodeID"})
assert.Check(t, cmd.Flags().Set("pretty", "true"))
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-inspect-pretty.%s.golden", tc.name))
}) })
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"nodeID"})
assert.Check(t, cmd.Flags().Set("pretty", "true"))
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-inspect-pretty.%s.golden", tc.name))
} }
} }

View File

@ -48,6 +48,7 @@ func TestNodeListErrorOnAPIFailure(t *testing.T) {
}) })
cmd := newListCommand(cli) cmd := newListCommand(cli)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.Error(t, cmd.Execute(), tc.expectedError) assert.Error(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -44,6 +44,7 @@ func TestNodePromoteErrors(t *testing.T) {
})) }))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -61,6 +61,7 @@ func TestNodePsErrors(t *testing.T) {
assert.Check(t, cmd.Flags().Set(key, value)) assert.Check(t, cmd.Flags().Set(key, value))
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.Error(t, cmd.Execute(), tc.expectedError) assert.Error(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -133,19 +134,22 @@ func TestNodePs(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
infoFunc: tc.infoFunc, t.Run(tc.name, func(t *testing.T) {
nodeInspectFunc: tc.nodeInspectFunc, cli := test.NewFakeCli(&fakeClient{
taskInspectFunc: tc.taskInspectFunc, infoFunc: tc.infoFunc,
taskListFunc: tc.taskListFunc, nodeInspectFunc: tc.nodeInspectFunc,
serviceInspectFunc: tc.serviceInspectFunc, taskInspectFunc: tc.taskInspectFunc,
taskListFunc: tc.taskListFunc,
serviceInspectFunc: tc.serviceInspectFunc,
})
cmd := newPsCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-ps.%s.golden", tc.name))
}) })
cmd := newPsCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-ps.%s.golden", tc.name))
} }
} }

View File

@ -33,6 +33,7 @@ func TestNodeRemoveErrors(t *testing.T) {
})) }))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -64,6 +64,7 @@ func TestNodeUpdateErrors(t *testing.T) {
assert.Check(t, cmd.Flags().Set(key, value)) assert.Check(t, cmd.Flags().Set(key, value))
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -41,6 +41,7 @@ func TestCreateErrors(t *testing.T) {
cmd := newCreateCommand(cli) cmd := newCreateCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -53,6 +54,7 @@ func TestCreateErrorOnFileAsContextDir(t *testing.T) {
cmd := newCreateCommand(cli) cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpFile.Path()}) cmd.SetArgs([]string{"plugin-foo", tmpFile.Path()})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "context must be a directory") assert.ErrorContains(t, cmd.Execute(), "context must be a directory")
} }
@ -64,6 +66,7 @@ func TestCreateErrorOnContextDirWithoutConfig(t *testing.T) {
cmd := newCreateCommand(cli) cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()}) cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
expectedErr := "config.json: no such file or directory" expectedErr := "config.json: no such file or directory"
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
@ -82,6 +85,7 @@ func TestCreateErrorOnInvalidConfig(t *testing.T) {
cmd := newCreateCommand(cli) cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()}) cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "invalid") assert.ErrorContains(t, cmd.Execute(), "invalid")
} }
@ -98,6 +102,7 @@ func TestCreateErrorFromDaemon(t *testing.T) {
})) }))
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()}) cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "error creating plugin") assert.ErrorContains(t, cmd.Execute(), "error creating plugin")
} }

View File

@ -41,6 +41,7 @@ func TestPluginDisableErrors(t *testing.T) {
})) }))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -51,6 +51,7 @@ func TestPluginEnableErrors(t *testing.T) {
cmd.Flags().Set(key, value) cmd.Flags().Set(key, value)
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -66,6 +66,7 @@ func TestInspectErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc}) cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc})
cmd := newInspectCommand(cli) cmd := newInspectCommand(cli)
@ -74,6 +75,7 @@ func TestInspectErrors(t *testing.T) {
cmd.Flags().Set(key, value) cmd.Flags().Set(key, value)
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}) })
} }
@ -136,6 +138,7 @@ func TestInspect(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc}) cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc})
cmd := newInspectCommand(cli) cmd := newInspectCommand(cli)

View File

@ -54,11 +54,15 @@ func TestInstallErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc}) tc := tc
cmd := newInstallCommand(cli) t.Run(tc.description, func(t *testing.T) {
cmd.SetArgs(tc.args) cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc})
cmd.SetOut(io.Discard) cmd := newInstallCommand(cli)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -90,16 +94,20 @@ func TestInstallContentTrustErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
pluginInstallFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) { t.Run(tc.description, func(t *testing.T) {
return nil, errors.New("should not try to install plugin") cli := test.NewFakeCli(&fakeClient{
}, pluginInstallFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) {
}, test.EnableContentTrust) return nil, errors.New("should not try to install plugin")
cli.SetNotaryClient(tc.notaryFunc) },
cmd := newInstallCommand(cli) }, test.EnableContentTrust)
cmd.SetArgs(tc.args) cli.SetNotaryClient(tc.notaryFunc)
cmd.SetOut(io.Discard) cmd := newInstallCommand(cli)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -130,10 +138,13 @@ func TestInstall(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc}) tc := tc
cmd := newInstallCommand(cli) t.Run(tc.description, func(t *testing.T) {
cmd.SetArgs(tc.args) cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc})
assert.NilError(t, cmd.Execute()) cmd := newInstallCommand(cli)
assert.Check(t, strings.Contains(cli.OutBuffer().String(), tc.expectedOutput)) cmd.SetArgs(tc.args)
assert.NilError(t, cmd.Execute())
assert.Check(t, strings.Contains(cli.OutBuffer().String(), tc.expectedOutput))
})
} }
} }

View File

@ -46,14 +46,18 @@ func TestListErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc}) tc := tc
cmd := newListCommand(cli) t.Run(tc.description, func(t *testing.T) {
cmd.SetArgs(tc.args) cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc})
for key, value := range tc.flags { cmd := newListCommand(cli)
cmd.Flags().Set(key, value) cmd.SetArgs(tc.args)
} for key, value := range tc.flags {
cmd.SetOut(io.Discard) cmd.Flags().Set(key, value)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) }
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -162,13 +166,16 @@ func TestList(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc}) tc := tc
cmd := newListCommand(cli) t.Run(tc.description, func(t *testing.T) {
cmd.SetArgs(tc.args) cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc})
for key, value := range tc.flags { cmd := newListCommand(cli)
cmd.Flags().Set(key, value) cmd.SetArgs(tc.args)
} for key, value := range tc.flags {
assert.NilError(t, cmd.Execute()) cmd.Flags().Set(key, value)
golden.Assert(t, cli.OutBuffer().String(), tc.golden) }
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), tc.golden)
})
} }
} }

View File

@ -37,6 +37,7 @@ func TestRemoveErrors(t *testing.T) {
cmd := newRemoveCommand(cli) cmd := newRemoveCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -32,6 +32,8 @@ func TestUpgradePromptTermination(t *testing.T) {
// need to set a remote address that does not match the plugin // need to set a remote address that does not match the plugin
// reference sent by the `pluginInspectFunc` // reference sent by the `pluginInspectFunc`
cmd.SetArgs([]string{"foo/bar", "localhost:5000/foo/bar:v1.0.0"}) cmd.SetArgs([]string{"foo/bar", "localhost:5000/foo/bar:v1.0.0"})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli) test.TerminatePrompt(ctx, t, cmd, cli)
golden.Assert(t, cli.OutBuffer().String(), "plugin-upgrade-terminate.golden") golden.Assert(t, cli.OutBuffer().String(), "plugin-upgrade-terminate.golden")
} }

View File

@ -49,6 +49,7 @@ func TestSecretCreateErrors(t *testing.T) {
) )
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -61,6 +61,7 @@ func TestSecretInspectErrors(t *testing.T) {
assert.Check(t, cmd.Flags().Set(key, value)) assert.Check(t, cmd.Flags().Set(key, value))
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -92,13 +93,16 @@ func TestSecretInspectWithoutFormat(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
secretInspectFunc: tc.secretInspectFunc, t.Run(tc.name, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
secretInspectFunc: tc.secretInspectFunc,
})
cmd := newSecretInspectCommand(cli)
cmd.SetArgs(tc.args)
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-without-format.%s.golden", tc.name))
}) })
cmd := newSecretInspectCommand(cli)
cmd.SetArgs(tc.args)
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-without-format.%s.golden", tc.name))
} }
} }
@ -128,14 +132,17 @@ func TestSecretInspectWithFormat(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
secretInspectFunc: tc.secretInspectFunc, t.Run(tc.name, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
secretInspectFunc: tc.secretInspectFunc,
})
cmd := newSecretInspectCommand(cli)
cmd.SetArgs(tc.args)
assert.Check(t, cmd.Flags().Set("format", tc.format))
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-with-format.%s.golden", tc.name))
}) })
cmd := newSecretInspectCommand(cli)
cmd.SetArgs(tc.args)
assert.Check(t, cmd.Flags().Set("format", tc.format))
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-with-format.%s.golden", tc.name))
} }
} }

View File

@ -42,6 +42,7 @@ func TestSecretListErrors(t *testing.T) {
) )
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }

View File

@ -38,6 +38,7 @@ func TestSecretRemoveErrors(t *testing.T) {
) )
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -74,6 +75,7 @@ func TestSecretRemoveContinueAfterError(t *testing.T) {
cmd := newSecretRemoveCommand(cli) cmd := newSecretRemoveCommand(cli)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs(names) cmd.SetArgs(names)
assert.Error(t, cmd.Execute(), "error removing secret: foo") assert.Error(t, cmd.Execute(), "error removing secret: foo")
assert.Check(t, is.DeepEqual(names, removedSecrets)) assert.Check(t, is.DeepEqual(names, removedSecrets))

View File

@ -91,14 +91,18 @@ func TestRollbackWithErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newRollbackCommand( tc := tc
test.NewFakeCli(&fakeClient{ t.Run(tc.name, func(t *testing.T) {
serviceInspectWithRawFunc: tc.serviceInspectWithRawFunc, cmd := newRollbackCommand(
serviceUpdateFunc: tc.serviceUpdateFunc, test.NewFakeCli(&fakeClient{
})) serviceInspectWithRawFunc: tc.serviceInspectWithRawFunc,
cmd.SetArgs(tc.args) serviceUpdateFunc: tc.serviceUpdateFunc,
cmd.Flags().Set("quiet", "true") }))
cmd.SetOut(io.Discard) cmd.SetArgs(tc.args)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.Flags().Set("quiet", "true")
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }

View File

@ -13,6 +13,7 @@ import (
func TestConfigWithEmptyComposeFile(t *testing.T) { func TestConfigWithEmptyComposeFile(t *testing.T) {
cmd := newConfigCommand(test.NewFakeCli(&fakeClient{})) cmd := newConfigCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), `Specify a Compose file`) assert.ErrorContains(t, cmd.Execute(), `Specify a Compose file`)
} }

View File

@ -12,6 +12,7 @@ func TestDeployWithEmptyName(t *testing.T) {
cmd := newDeployCommand(test.NewFakeCli(&fakeClient{})) cmd := newDeployCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetArgs([]string{"' '"}) cmd.SetArgs([]string{"' '"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`) assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`)
} }

View File

@ -25,18 +25,21 @@ func TestListErrors(t *testing.T) {
expectedError: "accepts no argument", expectedError: "accepts no argument",
}, },
{ {
args: []string{},
flags: map[string]string{ flags: map[string]string{
"format": "{{invalid format}}", "format": "{{invalid format}}",
}, },
expectedError: "template parsing error", expectedError: "template parsing error",
}, },
{ {
args: []string{},
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
return []swarm.Service{}, errors.Errorf("error getting services") return []swarm.Service{}, errors.Errorf("error getting services")
}, },
expectedError: "error getting services", expectedError: "error getting services",
}, },
{ {
args: []string{},
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
return []swarm.Service{*builders.Service()}, nil return []swarm.Service{*builders.Service()}, nil
}, },
@ -45,15 +48,19 @@ func TestListErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newListCommand(test.NewFakeCli(&fakeClient{ tc := tc
serviceListFunc: tc.serviceListFunc, t.Run(tc.expectedError, func(t *testing.T) {
})) cmd := newListCommand(test.NewFakeCli(&fakeClient{
cmd.SetArgs(tc.args) serviceListFunc: tc.serviceListFunc,
cmd.SetOut(io.Discard) }))
for key, value := range tc.flags { cmd.SetArgs(tc.args)
assert.Check(t, cmd.Flags().Set(key, value)) cmd.SetOut(io.Discard)
} cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -97,6 +104,7 @@ func TestStackList(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
var services []swarm.Service var services []swarm.Service
for _, name := range tc.serviceNames { for _, name := range tc.serviceNames {

View File

@ -40,12 +40,16 @@ func TestStackPsErrors(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newPsCommand(test.NewFakeCli(&fakeClient{ tc := tc
taskListFunc: tc.taskListFunc, t.Run(tc.expectedError, func(t *testing.T) {
})) cmd := newPsCommand(test.NewFakeCli(&fakeClient{
cmd.SetArgs(tc.args) taskListFunc: tc.taskListFunc,
cmd.SetOut(io.Discard) }))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -156,6 +160,7 @@ func TestStackPs(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
tc := tc
t.Run(tc.doc, func(t *testing.T) { t.Run(tc.doc, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{ cli := test.NewFakeCli(&fakeClient{
taskListFunc: tc.taskListFunc, taskListFunc: tc.taskListFunc,
@ -169,6 +174,7 @@ func TestStackPs(t *testing.T) {
assert.Check(t, cmd.Flags().Set(key, value)) assert.Check(t, cmd.Flags().Set(key, value))
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
if tc.expectedErr != "" { if tc.expectedErr != "" {
assert.Error(t, cmd.Execute(), tc.expectedErr) assert.Error(t, cmd.Execute(), tc.expectedErr)

View File

@ -45,6 +45,7 @@ func TestRemoveWithEmptyName(t *testing.T) {
cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{})) cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetArgs([]string{"good", "' '", "alsogood"}) cmd.SetArgs([]string{"good", "' '", "alsogood"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`) assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`)
} }
@ -157,6 +158,7 @@ func TestRemoveContinueAfterError(t *testing.T) {
} }
cmd := newRemoveCommand(test.NewFakeCli(cli)) cmd := newRemoveCommand(test.NewFakeCli(cli))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.SetArgs([]string{"foo", "bar"}) cmd.SetArgs([]string{"foo", "bar"})
assert.Error(t, cmd.Execute(), "Failed to remove some resources from stack: foo") assert.Error(t, cmd.Execute(), "Failed to remove some resources from stack: foo")

View File

@ -80,6 +80,7 @@ func TestStackServicesErrors(t *testing.T) {
assert.Check(t, cmd.Flags().Set(key, value)) assert.Check(t, cmd.Flags().Set(key, value))
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}) })
} }
@ -89,6 +90,7 @@ func TestRunServicesWithEmptyName(t *testing.T) {
cmd := newServicesCommand(test.NewFakeCli(&fakeClient{})) cmd := newServicesCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetArgs([]string{"' '"}) cmd.SetArgs([]string{"' '"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`) assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`)
} }

View File

@ -145,6 +145,7 @@ func TestDisplayTrustRootInvalidFlags(t *testing.T) {
})) }))
assert.Check(t, cmd.Flags().Parse(testCase.args)) assert.Check(t, cmd.Flags().Parse(testCase.args))
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), testCase.errorMsg) assert.ErrorContains(t, cmd.Execute(), testCase.errorMsg)
} }
} }

View File

@ -63,18 +63,22 @@ func TestSwarmInitErrorOnAPIFailure(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newInitCommand( tc := tc
test.NewFakeCli(&fakeClient{ t.Run(tc.name, func(t *testing.T) {
swarmInitFunc: tc.swarmInitFunc, cmd := newInitCommand(
swarmInspectFunc: tc.swarmInspectFunc, test.NewFakeCli(&fakeClient{
swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, swarmInitFunc: tc.swarmInitFunc,
nodeInspectFunc: tc.nodeInspectFunc, swarmInspectFunc: tc.swarmInspectFunc,
})) swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc,
for key, value := range tc.flags { nodeInspectFunc: tc.nodeInspectFunc,
cmd.Flags().Set(key, value) }))
} for key, value := range tc.flags {
cmd.SetOut(io.Discard) cmd.Flags().Set(key, value)
assert.Error(t, cmd.Execute(), tc.expectedError) }
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.Error(t, cmd.Execute(), tc.expectedError)
})
} }
} }

View File

@ -48,14 +48,18 @@ func TestSwarmJoinErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newJoinCommand( tc := tc
test.NewFakeCli(&fakeClient{ t.Run(tc.name, func(t *testing.T) {
swarmJoinFunc: tc.swarmJoinFunc, cmd := newJoinCommand(
infoFunc: tc.infoFunc, test.NewFakeCli(&fakeClient{
})) swarmJoinFunc: tc.swarmJoinFunc,
cmd.SetArgs(tc.args) infoFunc: tc.infoFunc,
cmd.SetOut(io.Discard) }))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -89,12 +93,15 @@ func TestSwarmJoin(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
infoFunc: tc.infoFunc, t.Run(tc.name, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
infoFunc: tc.infoFunc,
})
cmd := newJoinCommand(cli)
cmd.SetArgs([]string{"remote"})
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal(strings.TrimSpace(cli.OutBuffer().String()), tc.expected))
}) })
cmd := newJoinCommand(cli)
cmd.SetArgs([]string{"remote"})
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal(strings.TrimSpace(cli.OutBuffer().String()), tc.expected))
} }
} }

View File

@ -87,19 +87,23 @@ func TestSwarmJoinTokenErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
swarmInspectFunc: tc.swarmInspectFunc, t.Run(tc.name, func(t *testing.T) {
swarmUpdateFunc: tc.swarmUpdateFunc, cli := test.NewFakeCli(&fakeClient{
infoFunc: tc.infoFunc, swarmInspectFunc: tc.swarmInspectFunc,
nodeInspectFunc: tc.nodeInspectFunc, swarmUpdateFunc: tc.swarmUpdateFunc,
infoFunc: tc.infoFunc,
nodeInspectFunc: tc.nodeInspectFunc,
})
cmd := newJoinTokenCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}) })
cmd := newJoinTokenCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
cmd.SetOut(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -194,17 +198,20 @@ func TestSwarmJoinToken(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
swarmInspectFunc: tc.swarmInspectFunc, t.Run(tc.name, func(t *testing.T) {
infoFunc: tc.infoFunc, cli := test.NewFakeCli(&fakeClient{
nodeInspectFunc: tc.nodeInspectFunc, swarmInspectFunc: tc.swarmInspectFunc,
infoFunc: tc.infoFunc,
nodeInspectFunc: tc.nodeInspectFunc,
})
cmd := newJoinTokenCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("jointoken-%s.golden", tc.name))
}) })
cmd := newJoinTokenCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("jointoken-%s.golden", tc.name))
} }
} }

View File

@ -32,13 +32,17 @@ func TestSwarmLeaveErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newLeaveCommand( tc := tc
test.NewFakeCli(&fakeClient{ t.Run(tc.name, func(t *testing.T) {
swarmLeaveFunc: tc.swarmLeaveFunc, cmd := newLeaveCommand(
})) test.NewFakeCli(&fakeClient{
cmd.SetArgs(tc.args) swarmLeaveFunc: tc.swarmLeaveFunc,
cmd.SetOut(io.Discard) }))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }

View File

@ -80,18 +80,22 @@ func TestSwarmUnlockKeyErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newUnlockKeyCommand( tc := tc
test.NewFakeCli(&fakeClient{ t.Run(tc.name, func(t *testing.T) {
swarmInspectFunc: tc.swarmInspectFunc, cmd := newUnlockKeyCommand(
swarmUpdateFunc: tc.swarmUpdateFunc, test.NewFakeCli(&fakeClient{
swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, swarmInspectFunc: tc.swarmInspectFunc,
})) swarmUpdateFunc: tc.swarmUpdateFunc,
cmd.SetArgs(tc.args) swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc,
for key, value := range tc.flags { }))
assert.Check(t, cmd.Flags().Set(key, value)) cmd.SetArgs(tc.args)
} for key, value := range tc.flags {
cmd.SetOut(io.Discard) assert.Check(t, cmd.Flags().Set(key, value))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) }
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -154,17 +158,20 @@ func TestSwarmUnlockKey(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
swarmInspectFunc: tc.swarmInspectFunc, t.Run(tc.name, func(t *testing.T) {
swarmUpdateFunc: tc.swarmUpdateFunc, cli := test.NewFakeCli(&fakeClient{
swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, swarmInspectFunc: tc.swarmInspectFunc,
swarmUpdateFunc: tc.swarmUpdateFunc,
swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc,
})
cmd := newUnlockKeyCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("unlockkeys-%s.golden", tc.name))
}) })
cmd := newUnlockKeyCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("unlockkeys-%s.golden", tc.name))
} }
} }

View File

@ -64,14 +64,18 @@ func TestSwarmUnlockErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newUnlockCommand( tc := tc
test.NewFakeCli(&fakeClient{ t.Run(tc.name, func(t *testing.T) {
infoFunc: tc.infoFunc, cmd := newUnlockCommand(
swarmUnlockFunc: tc.swarmUnlockFunc, test.NewFakeCli(&fakeClient{
})) infoFunc: tc.infoFunc,
cmd.SetArgs(tc.args) swarmUnlockFunc: tc.swarmUnlockFunc,
cmd.SetOut(io.Discard) }))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }

View File

@ -65,18 +65,22 @@ func TestSwarmUpdateErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newUpdateCommand( tc := tc
test.NewFakeCli(&fakeClient{ t.Run(tc.name, func(t *testing.T) {
swarmInspectFunc: tc.swarmInspectFunc, cmd := newUpdateCommand(
swarmUpdateFunc: tc.swarmUpdateFunc, test.NewFakeCli(&fakeClient{
swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, swarmInspectFunc: tc.swarmInspectFunc,
})) swarmUpdateFunc: tc.swarmUpdateFunc,
cmd.SetArgs(tc.args) swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc,
for key, value := range tc.flags { }))
assert.Check(t, cmd.Flags().Set(key, value)) cmd.SetArgs(tc.args)
} for key, value := range tc.flags {
cmd.SetOut(io.Discard) assert.Check(t, cmd.Flags().Set(key, value))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) }
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
} }
@ -165,18 +169,25 @@ func TestSwarmUpdate(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{ tc := tc
swarmInspectFunc: tc.swarmInspectFunc, t.Run(tc.name, func(t *testing.T) {
swarmUpdateFunc: tc.swarmUpdateFunc, cli := test.NewFakeCli(&fakeClient{
swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, swarmInspectFunc: tc.swarmInspectFunc,
swarmUpdateFunc: tc.swarmUpdateFunc,
swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc,
})
cmd := newUpdateCommand(cli)
if tc.args == nil {
cmd.SetArgs([]string{})
} else {
cmd.SetArgs(tc.args)
}
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
cmd.SetOut(cli.OutBuffer())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("update-%s.golden", tc.name))
}) })
cmd := newUpdateCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
assert.Check(t, cmd.Flags().Set(key, value))
}
cmd.SetOut(cli.OutBuffer())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("update-%s.golden", tc.name))
} }
} }

View File

@ -2,6 +2,7 @@ package system
import ( import (
"context" "context"
"io"
"testing" "testing"
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
@ -18,6 +19,8 @@ func TestPrunePromptPre131DoesNotIncludeBuildCache(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{version: "1.30"}) cli := test.NewFakeCli(&fakeClient{version: "1.30"})
cmd := newPruneCommand(cli) cmd := newPruneCommand(cli)
cmd.SetArgs([]string{}) cmd.SetArgs([]string{})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "system prune has been cancelled") assert.ErrorContains(t, cmd.Execute(), "system prune has been cancelled")
expected := `WARNING! This will remove: expected := `WARNING! This will remove:
- all stopped containers - all stopped containers
@ -35,6 +38,8 @@ func TestPrunePromptFilters(t *testing.T) {
}) })
cmd := newPruneCommand(cli) cmd := newPruneCommand(cli)
cmd.SetArgs([]string{"--filter", "until=24h", "--filter", "label=hello-world", "--filter", "label!=foo=bar", "--filter", "label=bar=baz"}) cmd.SetArgs([]string{"--filter", "until=24h", "--filter", "label=hello-world", "--filter", "label!=foo=bar", "--filter", "label=bar=baz"})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "system prune has been cancelled") assert.ErrorContains(t, cmd.Execute(), "system prune has been cancelled")
expected := `WARNING! This will remove: expected := `WARNING! This will remove:
@ -69,5 +74,8 @@ func TestSystemPrunePromptTermination(t *testing.T) {
}) })
cmd := newPruneCommand(cli) cmd := newPruneCommand(cli)
cmd.SetArgs([]string{})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli) test.TerminatePrompt(ctx, t, cmd, cli)
} }

View File

@ -3,6 +3,7 @@ package system
import ( import (
"context" "context"
"errors" "errors"
"io"
"strings" "strings"
"testing" "testing"
@ -20,7 +21,9 @@ func TestVersionWithoutServer(t *testing.T) {
}, },
}) })
cmd := NewVersionCommand(cli) cmd := NewVersionCommand(cli)
cmd.SetArgs([]string{})
cmd.SetOut(cli.Err()) cmd.SetOut(cli.Err())
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "no server") assert.ErrorContains(t, cmd.Execute(), "no server")
out := cli.OutBuffer().String() out := cli.OutBuffer().String()
// TODO: use an assertion like e2e/image/build_test.go:assertBuildOutput() // TODO: use an assertion like e2e/image/build_test.go:assertBuildOutput()

View File

@ -67,6 +67,7 @@ func TestTrustInspectPrettyCommandErrors(t *testing.T) {
test.NewFakeCli(&fakeClient{})) test.NewFakeCli(&fakeClient{}))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
cmd.Flags().Set("pretty", "true") cmd.Flags().Set("pretty", "true")
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
@ -79,6 +80,7 @@ func TestTrustInspectPrettyCommandOfflineErrors(t *testing.T) {
cmd.Flags().Set("pretty", "true") cmd.Flags().Set("pretty", "true")
cmd.SetArgs([]string{"nonexistent-reg-name.io/image"}) cmd.SetArgs([]string{"nonexistent-reg-name.io/image"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access nonexistent-reg-name.io/image") assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access nonexistent-reg-name.io/image")
cli = test.NewFakeCli(&fakeClient{}) cli = test.NewFakeCli(&fakeClient{})
@ -87,6 +89,7 @@ func TestTrustInspectPrettyCommandOfflineErrors(t *testing.T) {
cmd.Flags().Set("pretty", "true") cmd.Flags().Set("pretty", "true")
cmd.SetArgs([]string{"nonexistent-reg-name.io/image:tag"}) cmd.SetArgs([]string{"nonexistent-reg-name.io/image:tag"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access nonexistent-reg-name.io/image") assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access nonexistent-reg-name.io/image")
} }
@ -97,6 +100,7 @@ func TestTrustInspectPrettyCommandUninitializedErrors(t *testing.T) {
cmd.Flags().Set("pretty", "true") cmd.Flags().Set("pretty", "true")
cmd.SetArgs([]string{"reg/unsigned-img"}) cmd.SetArgs([]string{"reg/unsigned-img"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access reg/unsigned-img") assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access reg/unsigned-img")
cli = test.NewFakeCli(&fakeClient{}) cli = test.NewFakeCli(&fakeClient{})
@ -105,6 +109,7 @@ func TestTrustInspectPrettyCommandUninitializedErrors(t *testing.T) {
cmd.Flags().Set("pretty", "true") cmd.Flags().Set("pretty", "true")
cmd.SetArgs([]string{"reg/unsigned-img:tag"}) cmd.SetArgs([]string{"reg/unsigned-img:tag"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access reg/unsigned-img:tag") assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access reg/unsigned-img:tag")
} }
@ -115,6 +120,7 @@ func TestTrustInspectPrettyCommandEmptyNotaryRepoErrors(t *testing.T) {
cmd.Flags().Set("pretty", "true") cmd.Flags().Set("pretty", "true")
cmd.SetArgs([]string{"reg/img:unsigned-tag"}) cmd.SetArgs([]string{"reg/img:unsigned-tag"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.NilError(t, cmd.Execute()) assert.NilError(t, cmd.Execute())
assert.Check(t, is.Contains(cli.OutBuffer().String(), "No signatures for reg/img:unsigned-tag")) assert.Check(t, is.Contains(cli.OutBuffer().String(), "No signatures for reg/img:unsigned-tag"))
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Administrative keys for reg/img")) assert.Check(t, is.Contains(cli.OutBuffer().String(), "Administrative keys for reg/img"))
@ -125,6 +131,7 @@ func TestTrustInspectPrettyCommandEmptyNotaryRepoErrors(t *testing.T) {
cmd.Flags().Set("pretty", "true") cmd.Flags().Set("pretty", "true")
cmd.SetArgs([]string{"reg/img"}) cmd.SetArgs([]string{"reg/img"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.NilError(t, cmd.Execute()) assert.NilError(t, cmd.Execute())
assert.Check(t, is.Contains(cli.OutBuffer().String(), "No signatures for reg/img")) assert.Check(t, is.Contains(cli.OutBuffer().String(), "No signatures for reg/img"))
assert.Check(t, is.Contains(cli.OutBuffer().String(), "Administrative keys for reg/img")) assert.Check(t, is.Contains(cli.OutBuffer().String(), "Administrative keys for reg/img"))

View File

@ -39,6 +39,7 @@ func TestTrustInspectCommandErrors(t *testing.T) {
cmd.Flags().Set("pretty", "true") cmd.Flags().Set("pretty", "true")
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -86,6 +87,7 @@ func TestTrustInspectCommandRepositoryErrors(t *testing.T) {
cmd := newInspectCommand(cli) cmd := newInspectCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.err) assert.ErrorContains(t, cmd.Execute(), tc.err)
if tc.golden != "" { if tc.golden != "" {
golden.Assert(t, cli.OutBuffer().String(), tc.golden) golden.Assert(t, cli.OutBuffer().String(), tc.golden)

View File

@ -42,6 +42,7 @@ func TestTrustKeyGenerateErrors(t *testing.T) {
cmd := newKeyGenerateCommand(cli) cmd := newKeyGenerateCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -50,8 +51,8 @@ func TestGenerateKeySuccess(t *testing.T) {
pubKeyCWD := t.TempDir() pubKeyCWD := t.TempDir()
privKeyStorageDir := t.TempDir() privKeyStorageDir := t.TempDir()
passwd := "password" const testPass = "password"
cannedPasswordRetriever := passphrase.ConstantRetriever(passwd) cannedPasswordRetriever := passphrase.ConstantRetriever(testPass)
// generate a single key // generate a single key
keyName := "alice" keyName := "alice"
privKeyFileStore, err := trustmanager.NewKeyFileStore(privKeyStorageDir, cannedPasswordRetriever) privKeyFileStore, err := trustmanager.NewKeyFileStore(privKeyStorageDir, cannedPasswordRetriever)
@ -87,7 +88,7 @@ func TestGenerateKeySuccess(t *testing.T) {
// assert encrypted header // assert encrypted header
assert.Check(t, is.Equal("ENCRYPTED PRIVATE KEY", privKeyPEM.Type)) assert.Check(t, is.Equal("ENCRYPTED PRIVATE KEY", privKeyPEM.Type))
// check that the passphrase matches // check that the passphrase matches
_, err = tufutils.ParsePKCS8ToTufKey(privKeyPEM.Bytes, []byte(passwd)) _, err = tufutils.ParsePKCS8ToTufKey(privKeyPEM.Bytes, []byte(testPass))
assert.NilError(t, err) assert.NilError(t, err)
// check that the public key exists at the correct path if we use the helper: // check that the public key exists at the correct path if we use the helper:

View File

@ -63,6 +63,7 @@ func TestTrustKeyLoadErrors(t *testing.T) {
cmd := newKeyLoadCommand(cli) cmd := newKeyLoadCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.Check(t, is.Contains(cli.OutBuffer().String(), tc.expectedOutput)) assert.Check(t, is.Contains(cli.OutBuffer().String(), tc.expectedOutput))
} }

View File

@ -52,6 +52,7 @@ func TestTrustRevokeCommandErrors(t *testing.T) {
test.NewFakeCli(&fakeClient{})) test.NewFakeCli(&fakeClient{}))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -139,6 +140,7 @@ func TestTrustRevokeCommand(t *testing.T) {
cmd := newRevokeCommand(cli) cmd := newRevokeCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
if tc.expectedErr != "" { if tc.expectedErr != "" {
assert.ErrorContains(t, cmd.Execute(), tc.expectedErr) assert.ErrorContains(t, cmd.Execute(), tc.expectedErr)
} else { } else {
@ -164,6 +166,8 @@ func TestRevokeTrustPromptTermination(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{}) cli := test.NewFakeCli(&fakeClient{})
cmd := newRevokeCommand(cli) cmd := newRevokeCommand(cli)
cmd.SetArgs([]string{"example/trust-demo"}) cmd.SetArgs([]string{"example/trust-demo"})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli) test.TerminatePrompt(ctx, t, cmd, cli)
golden.Assert(t, cli.OutBuffer().String(), "trust-revoke-prompt-termination.golden") golden.Assert(t, cli.OutBuffer().String(), "trust-revoke-prompt-termination.golden")
} }

View File

@ -67,6 +67,7 @@ func TestTrustSignCommandErrors(t *testing.T) {
test.NewFakeCli(&fakeClient{})) test.NewFakeCli(&fakeClient{}))
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -77,6 +78,7 @@ func TestTrustSignCommandOfflineErrors(t *testing.T) {
cmd := newSignCommand(cli) cmd := newSignCommand(cli)
cmd.SetArgs([]string{"reg-name.io/image:tag"}) cmd.SetArgs([]string{"reg-name.io/image:tag"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "client is offline") assert.ErrorContains(t, cmd.Execute(), "client is offline")
} }
@ -260,6 +262,7 @@ func TestSignCommandChangeListIsCleanedOnError(t *testing.T) {
cmd := newSignCommand(cli) cmd := newSignCommand(cli)
cmd.SetArgs([]string{"ubuntu:latest"}) cmd.SetArgs([]string{"ubuntu:latest"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
err := cmd.Execute() err := cmd.Execute()
assert.Assert(t, err != nil) assert.Assert(t, err != nil)
@ -277,5 +280,6 @@ func TestSignCommandLocalFlag(t *testing.T) {
cmd := newSignCommand(cli) cmd := newSignCommand(cli)
cmd.SetArgs([]string{"--local", "reg-name.io/image:red"}) cmd.SetArgs([]string{"--local", "reg-name.io/image:red"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "error contacting notary server: dial tcp: lookup reg-name.io") assert.ErrorContains(t, cmd.Execute(), "error contacting notary server: dial tcp: lookup reg-name.io")
} }

View File

@ -60,6 +60,7 @@ func TestTrustSignerAddErrors(t *testing.T) {
cmd := newSignerAddCommand(cli) cmd := newSignerAddCommand(cli)
cmd.SetArgs(tc.args) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
} }
} }
@ -78,6 +79,7 @@ func TestSignerAddCommandNoTargetsKey(t *testing.T) {
cmd.SetArgs([]string{"--key", tmpfile.Name(), "alice", "alpine", "linuxkit/alpine"}) cmd.SetArgs([]string{"--key", tmpfile.Name(), "alice", "alpine", "linuxkit/alpine"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.Error(t, cmd.Execute(), fmt.Sprintf("could not parse public key from file: %s: no valid public key found", tmpfile.Name())) assert.Error(t, cmd.Execute(), fmt.Sprintf("could not parse public key from file: %s: no valid public key found", tmpfile.Name()))
} }
@ -90,6 +92,7 @@ func TestSignerAddCommandBadKeyPath(t *testing.T) {
cmd.SetArgs([]string{"--key", "/path/to/key.pem", "alice", "alpine"}) cmd.SetArgs([]string{"--key", "/path/to/key.pem", "alice", "alpine"})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
expectedError := "unable to read public key from file: open /path/to/key.pem: no such file or directory" expectedError := "unable to read public key from file: open /path/to/key.pem: no such file or directory"
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
expectedError = "unable to read public key from file: open /path/to/key.pem: The system cannot find the path specified." expectedError = "unable to read public key from file: open /path/to/key.pem: The system cannot find the path specified."
@ -111,6 +114,7 @@ func TestSignerAddCommandInvalidRepoName(t *testing.T) {
cmd.SetArgs([]string{"--key", pubKeyFilepath, "alice", imageName}) cmd.SetArgs([]string{"--key", pubKeyFilepath, "alice", imageName})
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.Error(t, cmd.Execute(), "failed to add signer to: 870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd") assert.Error(t, cmd.Execute(), "failed to add signer to: 870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd")
expectedErr := fmt.Sprintf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings\n\n", imageName) expectedErr := fmt.Sprintf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings\n\n", imageName)

View File

@ -30,41 +30,54 @@ func TestTrustSignerRemoveErrors(t *testing.T) {
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {
cmd := newSignerRemoveCommand( tc := tc
test.NewFakeCli(&fakeClient{})) t.Run(tc.name, func(t *testing.T) {
cmd.SetArgs(tc.args) cmd := newSignerRemoveCommand(
cmd.SetOut(io.Discard) test.NewFakeCli(&fakeClient{}))
assert.ErrorContains(t, cmd.Execute(), tc.expectedError) cmd.SetArgs(tc.args)
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
} }
testCasesWithOutput := []struct { testCasesWithOutput := []struct {
name string name string
args []string args []string
expectedError string expectedError string
expectedErrOut string
}{ }{
{ {
name: "not-an-image", name: "not-an-image",
args: []string{"user", "notanimage"}, args: []string{"user", "notanimage"},
expectedError: "error retrieving signers for notanimage", expectedError: "error removing signer from: notanimage",
expectedErrOut: "error retrieving signers for notanimage",
}, },
{ {
name: "sha-reference", name: "sha-reference",
args: []string{"user", "870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"}, args: []string{"user", "870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"},
expectedError: "invalid repository name", expectedError: "error removing signer from: 870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd",
expectedErrOut: "invalid repository name",
}, },
{ {
name: "invalid-img-reference", name: "invalid-img-reference",
args: []string{"user", "ALPINE"}, args: []string{"user", "ALPINE"},
expectedError: "invalid reference format", expectedError: "error removing signer from: ALPINE",
expectedErrOut: "invalid reference format",
}, },
} }
for _, tc := range testCasesWithOutput { for _, tc := range testCasesWithOutput {
cli := test.NewFakeCli(&fakeClient{}) tc := tc
cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository) t.Run(tc.name, func(t *testing.T) {
cmd := newSignerRemoveCommand(cli) cli := test.NewFakeCli(&fakeClient{})
cmd.SetArgs(tc.args) cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository)
cmd.SetOut(io.Discard) cmd := newSignerRemoveCommand(cli)
cmd.Execute() cmd.SetArgs(tc.args)
assert.Check(t, is.Contains(cli.ErrBuffer().String(), tc.expectedError)) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
err := cmd.Execute()
assert.Check(t, is.Error(err, tc.expectedError))
assert.Check(t, is.Contains(cli.ErrBuffer().String(), tc.expectedErrOut))
})
} }
} }

View File

@ -166,15 +166,20 @@ func TestVolumePrunePromptNo(t *testing.T) {
skip.If(t, runtime.GOOS == "windows", "TODO: fix test on windows") skip.If(t, runtime.GOOS == "windows", "TODO: fix test on windows")
for _, input := range []string{"n", "N", "no", "anything", "really"} { for _, input := range []string{"n", "N", "no", "anything", "really"} {
cli := test.NewFakeCli(&fakeClient{ input := input
volumePruneFunc: simplePruneFunc, t.Run(input, func(t *testing.T) {
}) cli := test.NewFakeCli(&fakeClient{
volumePruneFunc: simplePruneFunc,
})
cli.SetIn(streams.NewIn(io.NopCloser(strings.NewReader(input)))) cli.SetIn(streams.NewIn(io.NopCloser(strings.NewReader(input))))
cmd := NewPruneCommand(cli) cmd := NewPruneCommand(cli)
cmd.SetArgs([]string{}) cmd.SetArgs([]string{})
assert.ErrorContains(t, cmd.Execute(), "volume prune has been cancelled") cmd.SetOut(io.Discard)
golden.Assert(t, cli.OutBuffer().String(), "volume-prune-no.golden") cmd.SetErr(io.Discard)
assert.ErrorContains(t, cmd.Execute(), "volume prune has been cancelled")
golden.Assert(t, cli.OutBuffer().String(), "volume-prune-no.golden")
})
} }
} }
@ -199,6 +204,8 @@ func TestVolumePrunePromptTerminate(t *testing.T) {
cmd := NewPruneCommand(cli) cmd := NewPruneCommand(cli)
cmd.SetArgs([]string{}) cmd.SetArgs([]string{})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
test.TerminatePrompt(ctx, t, cmd, cli) test.TerminatePrompt(ctx, t, cmd, cli)
golden.Assert(t, cli.OutBuffer().String(), "volume-prune-terminate.golden") golden.Assert(t, cli.OutBuffer().String(), "volume-prune-terminate.golden")
} }

View File

@ -303,6 +303,7 @@ func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig,
for registryHostname := range configFile.CredentialHelpers { for registryHostname := range configFile.CredentialHelpers {
newAuth, err := configFile.GetAuthConfig(registryHostname) newAuth, err := configFile.GetAuthConfig(registryHostname)
if err != nil { if err != nil {
// TODO(thaJeztah): use context-logger, so that this output can be suppressed (in tests).
logrus.WithError(err).Warnf("Failed to get credentials for registry: %s", registryHostname) logrus.WithError(err).Warnf("Failed to get credentials for registry: %s", registryHostname)
continue continue
} }

View File

@ -144,5 +144,6 @@ func newDummyCommand(validationFunc cobra.PositionalArgs) *cobra.Command {
}, },
} }
cmd.SetOut(io.Discard) cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)
return cmd return cmd
} }

View File

@ -149,6 +149,7 @@ func ConvertPortToPortConfig(
for _, binding := range portBindings[port] { for _, binding := range portBindings[port] {
if p := net.ParseIP(binding.HostIP); p != nil && !p.IsUnspecified() { if p := net.ParseIP(binding.HostIP); p != nil && !p.IsUnspecified() {
// TODO(thaJeztah): use context-logger, so that this output can be suppressed (in tests).
logrus.Warnf("ignoring IP-address (%s:%s) service will listen on '0.0.0.0'", net.JoinHostPort(binding.HostIP, binding.HostPort), port) logrus.Warnf("ignoring IP-address (%s:%s) service will listen on '0.0.0.0'", net.JoinHostPort(binding.HostIP, binding.HostPort), port)
} }