From ab230240ad44fdffa03558a3dbb47971f6336911 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 4 Jul 2024 01:29:04 +0200 Subject: [PATCH] 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 --- cli/command/builder/prune_test.go | 3 ++ cli/command/checkpoint/create_test.go | 1 + cli/command/checkpoint/list_test.go | 1 + cli/command/checkpoint/remove_test.go | 1 + cli/command/config/create_test.go | 20 ++++--- cli/command/config/inspect_test.go | 1 + cli/command/config/ls_test.go | 1 + cli/command/config/remove_test.go | 2 + cli/command/container/attach_test.go | 12 +++-- cli/command/container/cp_test.go | 15 +++--- cli/command/container/create_test.go | 1 + cli/command/container/export_test.go | 1 + cli/command/container/list_test.go | 1 + cli/command/container/prune_test.go | 3 ++ cli/command/container/rm_test.go | 1 + cli/command/container/run_test.go | 38 ++++++++------ cli/command/image/build_test.go | 1 + cli/command/image/history_test.go | 12 +++-- cli/command/image/import_test.go | 14 +++-- cli/command/image/inspect_test.go | 12 +++-- cli/command/image/list_test.go | 32 +++++++----- cli/command/image/load_test.go | 34 +++++++----- cli/command/image/prune_test.go | 20 ++++--- cli/command/image/pull_test.go | 66 ++++++++++++++---------- cli/command/image/push_test.go | 15 ++++-- cli/command/image/remove_test.go | 4 ++ cli/command/image/save_test.go | 44 +++++++++------- cli/command/image/tag_test.go | 1 + cli/command/manifest/annotate_test.go | 3 ++ cli/command/manifest/create_test.go | 16 ++++-- cli/command/manifest/inspect_test.go | 2 + cli/command/manifest/push_test.go | 1 + cli/command/manifest/rm_test.go | 1 + cli/command/network/connect_test.go | 1 + cli/command/network/create_test.go | 1 + cli/command/network/disconnect_test.go | 1 + cli/command/network/list_test.go | 2 + cli/command/network/prune_test.go | 4 ++ cli/command/network/remove_test.go | 2 + cli/command/node/demote_test.go | 1 + cli/command/node/inspect_test.go | 18 ++++--- cli/command/node/list_test.go | 1 + cli/command/node/promote_test.go | 1 + cli/command/node/ps_test.go | 30 ++++++----- cli/command/node/remove_test.go | 1 + cli/command/node/update_test.go | 1 + cli/command/plugin/create_test.go | 5 ++ cli/command/plugin/disable_test.go | 1 + cli/command/plugin/enable_test.go | 1 + cli/command/plugin/inspect_test.go | 3 ++ cli/command/plugin/install_test.go | 51 +++++++++++------- cli/command/plugin/list_test.go | 39 ++++++++------ cli/command/plugin/remove_test.go | 1 + cli/command/plugin/upgrade_test.go | 2 + cli/command/secret/create_test.go | 1 + cli/command/secret/inspect_test.go | 33 +++++++----- cli/command/secret/ls_test.go | 1 + cli/command/secret/remove_test.go | 2 + cli/command/service/rollback_test.go | 22 ++++---- cli/command/stack/config_test.go | 1 + cli/command/stack/deploy_test.go | 1 + cli/command/stack/list_test.go | 26 ++++++---- cli/command/stack/ps_test.go | 18 ++++--- cli/command/stack/remove_test.go | 2 + cli/command/stack/services_test.go | 2 + cli/command/swarm/ca_test.go | 1 + cli/command/swarm/init_test.go | 28 +++++----- cli/command/swarm/join_test.go | 35 ++++++++----- cli/command/swarm/join_token_test.go | 53 ++++++++++--------- cli/command/swarm/leave_test.go | 18 ++++--- cli/command/swarm/unlock_key_test.go | 53 ++++++++++--------- cli/command/swarm/unlock_test.go | 20 ++++--- cli/command/swarm/update_test.go | 59 ++++++++++++--------- cli/command/system/prune_test.go | 8 +++ cli/command/system/version_test.go | 3 ++ cli/command/trust/inspect_pretty_test.go | 7 +++ cli/command/trust/inspect_test.go | 2 + cli/command/trust/key_generate_test.go | 7 +-- cli/command/trust/key_load_test.go | 1 + cli/command/trust/revoke_test.go | 4 ++ cli/command/trust/sign_test.go | 4 ++ cli/command/trust/signer_add_test.go | 4 ++ cli/command/trust/signer_remove_test.go | 61 +++++++++++++--------- cli/command/volume/prune_test.go | 23 ++++++--- cli/config/configfile/file.go | 1 + cli/required_test.go | 1 + opts/port.go | 1 + 87 files changed, 677 insertions(+), 373 deletions(-) diff --git a/cli/command/builder/prune_test.go b/cli/command/builder/prune_test.go index e59e7ad7881e..7fb18900da50 100644 --- a/cli/command/builder/prune_test.go +++ b/cli/command/builder/prune_test.go @@ -3,6 +3,7 @@ package builder import ( "context" "errors" + "io" "testing" "github.com/docker/cli/internal/test" @@ -19,5 +20,7 @@ func TestBuilderPromptTermination(t *testing.T) { }, }) cmd := NewPruneCommand(cli) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) test.TerminatePrompt(ctx, t, cmd, cli) } diff --git a/cli/command/checkpoint/create_test.go b/cli/command/checkpoint/create_test.go index ebee2c1abf4e..3ad7922df64a 100644 --- a/cli/command/checkpoint/create_test.go +++ b/cli/command/checkpoint/create_test.go @@ -42,6 +42,7 @@ func TestCheckpointCreateErrors(t *testing.T) { cmd := newCreateCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/checkpoint/list_test.go b/cli/command/checkpoint/list_test.go index 648d65a7bdc9..7ac4a768de15 100644 --- a/cli/command/checkpoint/list_test.go +++ b/cli/command/checkpoint/list_test.go @@ -42,6 +42,7 @@ func TestCheckpointListErrors(t *testing.T) { cmd := newListCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/checkpoint/remove_test.go b/cli/command/checkpoint/remove_test.go index 9ec1976ae1a0..01bda3c04d2a 100644 --- a/cli/command/checkpoint/remove_test.go +++ b/cli/command/checkpoint/remove_test.go @@ -41,6 +41,7 @@ func TestCheckpointRemoveErrors(t *testing.T) { cmd := newRemoveCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/config/create_test.go b/cli/command/config/create_test.go index a1c5e618990d..db9f8eac8298 100644 --- a/cli/command/config/create_test.go +++ b/cli/command/config/create_test.go @@ -43,14 +43,18 @@ func TestConfigCreateErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := newConfigCreateCommand( - test.NewFakeCli(&fakeClient{ - configCreateFunc: tc.configCreateFunc, - }), - ) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.expectedError, func(t *testing.T) { + cmd := newConfigCreateCommand( + test.NewFakeCli(&fakeClient{ + configCreateFunc: tc.configCreateFunc, + }), + ) + cmd.SetArgs(tc.args) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + }) } } diff --git a/cli/command/config/inspect_test.go b/cli/command/config/inspect_test.go index a35a74d776d7..fc22516fbba3 100644 --- a/cli/command/config/inspect_test.go +++ b/cli/command/config/inspect_test.go @@ -61,6 +61,7 @@ func TestConfigInspectErrors(t *testing.T) { assert.Check(t, cmd.Flags().Set(key, value)) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/config/ls_test.go b/cli/command/config/ls_test.go index 27e76c1a95bb..15658ee3308b 100644 --- a/cli/command/config/ls_test.go +++ b/cli/command/config/ls_test.go @@ -42,6 +42,7 @@ func TestConfigListErrors(t *testing.T) { ) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/config/remove_test.go b/cli/command/config/remove_test.go index bbdd0c4317e9..1466391ee5db 100644 --- a/cli/command/config/remove_test.go +++ b/cli/command/config/remove_test.go @@ -37,6 +37,7 @@ func TestConfigRemoveErrors(t *testing.T) { ) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -74,6 +75,7 @@ func TestConfigRemoveContinueAfterError(t *testing.T) { cmd := newConfigRemoveCommand(cli) cmd.SetArgs(names) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.Error(t, cmd.Execute(), "error removing config: foo") assert.Check(t, is.DeepEqual(names, removedConfigs)) } diff --git a/cli/command/container/attach_test.go b/cli/command/container/attach_test.go index 11f4ced45f5e..69332fc6bc2d 100644 --- a/cli/command/container/attach_test.go +++ b/cli/command/container/attach_test.go @@ -74,10 +74,14 @@ func TestNewAttachCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc})) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc})) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + cmd.SetArgs(tc.args) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + }) } } diff --git a/cli/command/container/cp_test.go b/cli/command/container/cp_test.go index 245aef3a5a50..6bec0275bdea 100644 --- a/cli/command/container/cp_test.go +++ b/cli/command/container/cp_test.go @@ -178,13 +178,14 @@ func TestSplitCpArg(t *testing.T) { expectedContainer: "container", }, } - for _, testcase := range testcases { - t.Run(testcase.doc, func(t *testing.T) { - skip.If(t, testcase.os != "" && testcase.os != runtime.GOOS) - - ctr, path := splitCpArg(testcase.path) - assert.Check(t, is.Equal(testcase.expectedContainer, ctr)) - assert.Check(t, is.Equal(testcase.expectedPath, path)) + for _, tc := range testcases { + tc := tc + 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(tc.path) + assert.Check(t, is.Equal(tc.expectedContainer, ctr)) + assert.Check(t, is.Equal(tc.expectedPath, path)) }) } } diff --git a/cli/command/container/create_test.go b/cli/command/container/create_test.go index f77c699db344..43509a9b007e 100644 --- a/cli/command/container/create_test.go +++ b/cli/command/container/create_test.go @@ -236,6 +236,7 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) { fakeCLI.SetNotaryClient(tc.notaryFunc) cmd := NewCreateCommand(fakeCLI) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs(tc.args) err := cmd.Execute() assert.ErrorContains(t, err, tc.expectedError) diff --git a/cli/command/container/export_test.go b/cli/command/container/export_test.go index 891317fff3df..ae21a8799533 100644 --- a/cli/command/container/export_test.go +++ b/cli/command/container/export_test.go @@ -39,6 +39,7 @@ func TestContainerExportOutputToIrregularFile(t *testing.T) { }) cmd := NewExportCommand(cli) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs([]string{"-o", "/dev/random", "container"}) err := cmd.Execute() diff --git a/cli/command/container/list_test.go b/cli/command/container/list_test.go index 6c80541870ef..6bc63b57a691 100644 --- a/cli/command/container/list_test.go +++ b/cli/command/container/list_test.go @@ -163,6 +163,7 @@ func TestContainerListErrors(t *testing.T) { assert.Check(t, cmd.Flags().Set(key, value)) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/container/prune_test.go b/cli/command/container/prune_test.go index ec006f9a39bd..bf2e793d07de 100644 --- a/cli/command/container/prune_test.go +++ b/cli/command/container/prune_test.go @@ -2,6 +2,7 @@ package container import ( "context" + "io" "testing" "github.com/docker/cli/internal/test" @@ -20,5 +21,7 @@ func TestContainerPrunePromptTermination(t *testing.T) { }, }) cmd := NewPruneCommand(cli) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) test.TerminatePrompt(ctx, t, cmd, cli) } diff --git a/cli/command/container/rm_test.go b/cli/command/container/rm_test.go index 704effbb59ce..493a2a68ba10 100644 --- a/cli/command/container/rm_test.go +++ b/cli/command/container/rm_test.go @@ -45,6 +45,7 @@ func TestRemoveForce(t *testing.T) { }) cmd := NewRmCommand(cli) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs(tc.args) err := cmd.Execute() diff --git a/cli/command/container/run_test.go b/cli/command/container/run_test.go index d02956da1de3..7c39b17ca67b 100644 --- a/cli/command/container/run_test.go +++ b/cli/command/container/run_test.go @@ -127,23 +127,27 @@ func TestRunCommandWithContentTrustErrors(t *testing.T) { }, } for _, tc := range testCases { - fakeCLI := test.NewFakeCli(&fakeClient{ - createContainerFunc: func(config *container.Config, - hostConfig *container.HostConfig, - networkingConfig *network.NetworkingConfig, - platform *specs.Platform, - containerName string, - ) (container.CreateResponse, error) { - return container.CreateResponse{}, errors.New("shouldn't try to pull image") - }, - }, test.EnableContentTrust) - fakeCLI.SetNotaryClient(tc.notaryFunc) - cmd := NewRunCommand(fakeCLI) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - err := cmd.Execute() - assert.Assert(t, err != nil) - assert.Assert(t, is.Contains(fakeCLI.ErrBuffer().String(), tc.expectedError)) + tc := tc + t.Run(tc.name, func(t *testing.T) { + fakeCLI := test.NewFakeCli(&fakeClient{ + createContainerFunc: func(config *container.Config, + hostConfig *container.HostConfig, + networkingConfig *network.NetworkingConfig, + platform *specs.Platform, + containerName string, + ) (container.CreateResponse, error) { + return container.CreateResponse{}, errors.New("shouldn't try to pull image") + }, + }, test.EnableContentTrust) + fakeCLI.SetNotaryClient(tc.notaryFunc) + cmd := NewRunCommand(fakeCLI) + cmd.SetArgs(tc.args) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + err := cmd.Execute() + assert.Assert(t, err != nil) + assert.Assert(t, is.Contains(fakeCLI.ErrBuffer().String(), tc.expectedError)) + }) } } diff --git a/cli/command/image/build_test.go b/cli/command/image/build_test.go index 1548261b3d46..b13ba3b0c1db 100644 --- a/cli/command/image/build_test.go +++ b/cli/command/image/build_test.go @@ -127,6 +127,7 @@ func TestRunBuildFromGitHubSpecialCase(t *testing.T) { // Clone a small repo that exists so git doesn't prompt for credentials cmd.SetArgs([]string{"github.com/docker/for-win"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) err := cmd.Execute() assert.ErrorContains(t, err, "unable to prepare context") assert.ErrorContains(t, err, "docker-build-git") diff --git a/cli/command/image/history_test.go b/cli/command/image/history_test.go index 4f3f54677b30..86eeaba3ba2e 100644 --- a/cli/command/image/history_test.go +++ b/cli/command/image/history_test.go @@ -35,10 +35,14 @@ func TestNewHistoryCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc})) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc})) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + cmd.SetArgs(tc.args) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + }) } } diff --git a/cli/command/image/import_test.go b/cli/command/image/import_test.go index 7db6eea4f0dd..59a6ced04d40 100644 --- a/cli/command/image/import_test.go +++ b/cli/command/image/import_test.go @@ -36,6 +36,7 @@ func TestNewImportCommandErrors(t *testing.T) { for _, tc := range testCases { cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc})) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs(tc.args) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } @@ -44,6 +45,7 @@ func TestNewImportCommandErrors(t *testing.T) { func TestNewImportCommandInvalidFile(t *testing.T) { cmd := NewImportCommand(test.NewFakeCli(&fakeClient{})) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs([]string{"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 { - cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc})) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.NilError(t, cmd.Execute()) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc})) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + cmd.SetArgs(tc.args) + assert.NilError(t, cmd.Execute()) + }) } } diff --git a/cli/command/image/inspect_test.go b/cli/command/image/inspect_test.go index 1a6425f8c99b..c7c2f3f2495b 100644 --- a/cli/command/image/inspect_test.go +++ b/cli/command/image/inspect_test.go @@ -25,10 +25,14 @@ func TestNewInspectCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := newInspectCommand(test.NewFakeCli(&fakeClient{})) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := newInspectCommand(test.NewFakeCli(&fakeClient{})) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + cmd.SetArgs(tc.args) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + }) } } diff --git a/cli/command/image/list_test.go b/cli/command/image/list_test.go index 2b5259b1f53d..4917c539398f 100644 --- a/cli/command/image/list_test.go +++ b/cli/command/image/list_test.go @@ -35,10 +35,14 @@ func TestNewImagesCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := NewImagesCommand(test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc})) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := NewImagesCommand(test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc})) + 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 { - cli := test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc}) - cli.SetConfigFile(&configfile.ConfigFile{ImagesFormat: tc.imageFormat}) - cmd := NewImagesCommand(cli) - cmd.SetOut(io.Discard) - 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)) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc}) + cli.SetConfigFile(&configfile.ConfigFile{ImagesFormat: tc.imageFormat}) + cmd := NewImagesCommand(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("list-command-success.%s.golden", tc.name)) + }) } } diff --git a/cli/command/image/load_test.go b/cli/command/image/load_test.go index 8f1b46016b68..9c36ce32353b 100644 --- a/cli/command/image/load_test.go +++ b/cli/command/image/load_test.go @@ -40,12 +40,16 @@ func TestNewLoadCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc}) - cli.In().SetIsTerminal(tc.isTerminalIn) - cmd := NewLoadCommand(cli) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc}) + cli.In().SetIsTerminal(tc.isTerminalIn) + cmd := NewLoadCommand(cli) + 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 *" cmd := NewLoadCommand(test.NewFakeCli(&fakeClient{})) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs([]string{"--input", "*"}) err := cmd.Execute() assert.ErrorContains(t, err, expectedError) @@ -89,12 +94,15 @@ func TestNewLoadCommandSuccess(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc}) - cmd := NewLoadCommand(cli) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - err := cmd.Execute() - assert.NilError(t, err) - golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("load-command-success.%s.golden", tc.name)) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc}) + cmd := NewLoadCommand(cli) + cmd.SetOut(io.Discard) + cmd.SetArgs(tc.args) + err := cmd.Execute() + assert.NilError(t, err) + golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("load-command-success.%s.golden", tc.name)) + }) } } diff --git a/cli/command/image/prune_test.go b/cli/command/image/prune_test.go index e1df3cafe02c..1d6b2de983ad 100644 --- a/cli/command/image/prune_test.go +++ b/cli/command/image/prune_test.go @@ -39,12 +39,16 @@ func TestNewPruneCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := NewPruneCommand(test.NewFakeCli(&fakeClient{ - imagesPruneFunc: tc.imagesPruneFunc, - })) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := NewPruneCommand(test.NewFakeCli(&fakeClient{ + imagesPruneFunc: tc.imagesPruneFunc, + })) + 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 { + tc := tc t.Run(tc.name, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{imagesPruneFunc: tc.imagesPruneFunc}) // when prompted, answer "Y" to confirm the prune. @@ -119,5 +124,8 @@ func TestPrunePromptTermination(t *testing.T) { }, }) cmd := NewPruneCommand(cli) + cmd.SetArgs([]string{}) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) test.TerminatePrompt(ctx, t, cmd, cli) } diff --git a/cli/command/image/pull_test.go b/cli/command/image/pull_test.go index 3aa6e5524409..43bc772ea75b 100644 --- a/cli/command/image/pull_test.go +++ b/cli/command/image/pull_test.go @@ -38,11 +38,15 @@ func TestNewPullCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{}) - cmd := NewPullCommand(cli) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{}) + cmd := NewPullCommand(cli) + 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 { - cli := test.NewFakeCli(&fakeClient{ - 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 - }, + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + 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 { - cli := test.NewFakeCli(&fakeClient{ - imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) { - return io.NopCloser(strings.NewReader("")), errors.New("shouldn't try to pull image") - }, - }, test.EnableContentTrust) - cli.SetNotaryClient(tc.notaryFunc) - cmd := NewPullCommand(cli) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - err := cmd.Execute() - assert.ErrorContains(t, err, tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + imagePullFunc: func(ref string, options image.PullOptions) (io.ReadCloser, error) { + return io.NopCloser(strings.NewReader("")), errors.New("shouldn't try to pull image") + }, + }, test.EnableContentTrust) + cli.SetNotaryClient(tc.notaryFunc) + cmd := NewPullCommand(cli) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + cmd.SetArgs(tc.args) + err := cmd.Execute() + assert.ErrorContains(t, err, tc.expectedError) + }) } } diff --git a/cli/command/image/push_test.go b/cli/command/image/push_test.go index 6ba7235775ce..a659c6c510cc 100644 --- a/cli/command/image/push_test.go +++ b/cli/command/image/push_test.go @@ -38,11 +38,15 @@ func TestNewPushCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc}) - cmd := NewPushCommand(cli) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc}) + cmd := NewPushCommand(cli) + 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.SetOut(cli.OutBuffer()) + cmd.SetErr(io.Discard) cmd.SetArgs(tc.args) assert.NilError(t, cmd.Execute()) if tc.output != "" { diff --git a/cli/command/image/remove_test.go b/cli/command/image/remove_test.go index b1035da92445..d4340b381914 100644 --- a/cli/command/image/remove_test.go +++ b/cli/command/image/remove_test.go @@ -62,11 +62,13 @@ func TestNewRemoveCommandErrors(t *testing.T) { }, } for _, tc := range testCases { + tc := tc t.Run(tc.name, func(t *testing.T) { cmd := NewRemoveCommand(test.NewFakeCli(&fakeClient{ imageRemoveFunc: tc.imageRemoveFunc, })) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs(tc.args) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) }) @@ -119,10 +121,12 @@ func TestNewRemoveCommandSuccess(t *testing.T) { }, } for _, tc := range testCases { + tc := tc t.Run(tc.name, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{imageRemoveFunc: tc.imageRemoveFunc}) cmd := NewRemoveCommand(cli) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs(tc.args) assert.NilError(t, cmd.Execute()) assert.Check(t, is.Equal(tc.expectedStderr, cli.ErrBuffer().String())) diff --git a/cli/command/image/save_test.go b/cli/command/image/save_test.go index 22434c736fd3..c6cff4cc3c22 100644 --- a/cli/command/image/save_test.go +++ b/cli/command/image/save_test.go @@ -52,12 +52,16 @@ func TestNewSaveCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{imageSaveFunc: tc.imageSaveFunc}) - cli.Out().SetIsTerminal(tc.isTerminal) - cmd := NewSaveCommand(cli) - cmd.SetOut(io.Discard) - cmd.SetArgs(tc.args) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{imageSaveFunc: tc.imageSaveFunc}) + cli.Out().SetIsTerminal(tc.isTerminal) + cmd := NewSaveCommand(cli) + 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 }, 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 { - 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()) - if tc.deferredFunc != nil { - tc.deferredFunc() - } + tc := tc + t.Run(strings.Join(tc.args, " "), func(t *testing.T) { + cmd := NewSaveCommand(test.NewFakeCli(&fakeClient{ + imageSaveFunc: func(images []string) (io.ReadCloser, error) { + return io.NopCloser(strings.NewReader("")), nil + }, + })) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + cmd.SetArgs(tc.args) + assert.NilError(t, cmd.Execute()) + if tc.deferredFunc != nil { + tc.deferredFunc() + } + }) } } diff --git a/cli/command/image/tag_test.go b/cli/command/image/tag_test.go index 87e7aeb1e585..77bf81c2db6f 100644 --- a/cli/command/image/tag_test.go +++ b/cli/command/image/tag_test.go @@ -20,6 +20,7 @@ func TestCliNewTagCommandErrors(t *testing.T) { cmd := NewTagCommand(test.NewFakeCli(&fakeClient{})) cmd.SetArgs(args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), expectedError) } } diff --git a/cli/command/manifest/annotate_test.go b/cli/command/manifest/annotate_test.go index 5e95d1c7f1f6..089b29c71600 100644 --- a/cli/command/manifest/annotate_test.go +++ b/cli/command/manifest/annotate_test.go @@ -35,6 +35,7 @@ func TestManifestAnnotateError(t *testing.T) { cmd := newAnnotateCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -52,6 +53,7 @@ func TestManifestAnnotate(t *testing.T) { cmd := newAnnotateCommand(cli) cmd.SetArgs([]string{"example.com/list:v1", "example.com/fake:0.0"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) expectedError := "manifest for image example.com/fake:0.0 does not exist" assert.ErrorContains(t, cmd.Execute(), expectedError) @@ -71,6 +73,7 @@ func TestManifestAnnotate(t *testing.T) { err = cmd.Flags().Set("verbose", "true") assert.NilError(t, err) cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"}) + cmd.SetErr(io.Discard) assert.NilError(t, cmd.Execute()) actual := cli.OutBuffer() expected := golden.Get(t, "inspect-annotate.golden") diff --git a/cli/command/manifest/create_test.go b/cli/command/manifest/create_test.go index 71fe6c63e9cd..0b1296e805a4 100644 --- a/cli/command/manifest/create_test.go +++ b/cli/command/manifest/create_test.go @@ -31,11 +31,15 @@ func TestManifestCreateErrors(t *testing.T) { } for _, tc := range testCases { - cli := test.NewFakeCli(nil) - cmd := newCreateListCommand(cli) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.expectedError, func(t *testing.T) { + cli := test.NewFakeCli(nil) + cmd := newCreateListCommand(cli) + 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.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) err = cmd.Execute() 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.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) err := cmd.Execute() assert.Error(t, err, "No such image: example.com/alpine:3.0") } diff --git a/cli/command/manifest/inspect_test.go b/cli/command/manifest/inspect_test.go index af4e17af3c97..0009b4177066 100644 --- a/cli/command/manifest/inspect_test.go +++ b/cli/command/manifest/inspect_test.go @@ -70,6 +70,7 @@ func TestInspectCommandLocalManifestNotFound(t *testing.T) { cmd := newInspectCommand(cli) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"}) err := cmd.Execute() 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.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs([]string{"example.com/alpine:3.0"}) err := cmd.Execute() assert.Error(t, err, "No such manifest: example.com/alpine:3.0") diff --git a/cli/command/manifest/push_test.go b/cli/command/manifest/push_test.go index 2276cf7e43f5..2a11fceda2cf 100644 --- a/cli/command/manifest/push_test.go +++ b/cli/command/manifest/push_test.go @@ -44,6 +44,7 @@ func TestManifestPushErrors(t *testing.T) { cmd := newPushListCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/manifest/rm_test.go b/cli/command/manifest/rm_test.go index b360c0d8bbfa..8d285c28c82a 100644 --- a/cli/command/manifest/rm_test.go +++ b/cli/command/manifest/rm_test.go @@ -56,6 +56,7 @@ func TestRmManifestNotCreated(t *testing.T) { cmd := newRmManifestListCommand(cli) cmd.SetArgs([]string{"example.com/first:1", "example.com/second:2"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) err = cmd.Execute() assert.Error(t, err, "No such manifest: example.com/first:1") diff --git a/cli/command/network/connect_test.go b/cli/command/network/connect_test.go index 89c9b8e607b2..cfdff2880605 100644 --- a/cli/command/network/connect_test.go +++ b/cli/command/network/connect_test.go @@ -38,6 +38,7 @@ func TestNetworkConnectErrors(t *testing.T) { ) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/network/create_test.go b/cli/command/network/create_test.go index 30707c2792e8..8eab2ff0bd81 100644 --- a/cli/command/network/create_test.go +++ b/cli/command/network/create_test.go @@ -137,6 +137,7 @@ func TestNetworkCreateErrors(t *testing.T) { assert.NilError(t, cmd.Flags().Set(key, value)) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/network/disconnect_test.go b/cli/command/network/disconnect_test.go index e60ecd6ac089..bcbb491d096a 100644 --- a/cli/command/network/disconnect_test.go +++ b/cli/command/network/disconnect_test.go @@ -36,6 +36,7 @@ func TestNetworkDisconnectErrors(t *testing.T) { ) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/network/list_test.go b/cli/command/network/list_test.go index 7b1ae329bc20..e92c0d09fa3e 100644 --- a/cli/command/network/list_test.go +++ b/cli/command/network/list_test.go @@ -36,6 +36,7 @@ func TestNetworkListErrors(t *testing.T) { }), ) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -82,6 +83,7 @@ func TestNetworkList(t *testing.T) { } for _, tc := range testCases { + tc := tc t.Run(tc.doc, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{networkListFunc: tc.networkListFunc}) cmd := newListCommand(cli) diff --git a/cli/command/network/prune_test.go b/cli/command/network/prune_test.go index b59dfff81419..16010d3c7420 100644 --- a/cli/command/network/prune_test.go +++ b/cli/command/network/prune_test.go @@ -2,6 +2,7 @@ package network import ( "context" + "io" "testing" "github.com/docker/cli/internal/test" @@ -20,5 +21,8 @@ func TestNetworkPrunePromptTermination(t *testing.T) { }, }) cmd := NewPruneCommand(cli) + cmd.SetArgs([]string{}) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) test.TerminatePrompt(ctx, t, cmd, cli) } diff --git a/cli/command/network/remove_test.go b/cli/command/network/remove_test.go index 283f9544bd6c..05ec10b1ed56 100644 --- a/cli/command/network/remove_test.go +++ b/cli/command/network/remove_test.go @@ -114,5 +114,7 @@ func TestNetworkRemovePromptTermination(t *testing.T) { }) cmd := newRemoveCommand(cli) cmd.SetArgs([]string{"existing-network"}) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) test.TerminatePrompt(ctx, t, cmd, cli) } diff --git a/cli/command/node/demote_test.go b/cli/command/node/demote_test.go index 64a11c098593..ad7590533d9c 100644 --- a/cli/command/node/demote_test.go +++ b/cli/command/node/demote_test.go @@ -44,6 +44,7 @@ func TestNodeDemoteErrors(t *testing.T) { })) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/node/inspect_test.go b/cli/command/node/inspect_test.go index 579330ad0828..9cb742fbb931 100644 --- a/cli/command/node/inspect_test.go +++ b/cli/command/node/inspect_test.go @@ -74,6 +74,7 @@ func TestNodeInspectErrors(t *testing.T) { assert.Check(t, cmd.Flags().Set(key, value)) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -105,13 +106,16 @@ func TestNodeInspectPretty(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{ - nodeInspectFunc: tc.nodeInspectFunc, + tc := tc + 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)) } } diff --git a/cli/command/node/list_test.go b/cli/command/node/list_test.go index 715e43cc8357..0ccf8a2d4e2a 100644 --- a/cli/command/node/list_test.go +++ b/cli/command/node/list_test.go @@ -48,6 +48,7 @@ func TestNodeListErrorOnAPIFailure(t *testing.T) { }) cmd := newListCommand(cli) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/node/promote_test.go b/cli/command/node/promote_test.go index 42b3a7d755ed..bf4dce53959a 100644 --- a/cli/command/node/promote_test.go +++ b/cli/command/node/promote_test.go @@ -44,6 +44,7 @@ func TestNodePromoteErrors(t *testing.T) { })) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/node/ps_test.go b/cli/command/node/ps_test.go index 98318903b527..84b1612170b0 100644 --- a/cli/command/node/ps_test.go +++ b/cli/command/node/ps_test.go @@ -61,6 +61,7 @@ func TestNodePsErrors(t *testing.T) { assert.Check(t, cmd.Flags().Set(key, value)) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.Error(t, cmd.Execute(), tc.expectedError) } } @@ -133,19 +134,22 @@ func TestNodePs(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{ - infoFunc: tc.infoFunc, - nodeInspectFunc: tc.nodeInspectFunc, - taskInspectFunc: tc.taskInspectFunc, - taskListFunc: tc.taskListFunc, - serviceInspectFunc: tc.serviceInspectFunc, + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + infoFunc: tc.infoFunc, + nodeInspectFunc: tc.nodeInspectFunc, + 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)) } } diff --git a/cli/command/node/remove_test.go b/cli/command/node/remove_test.go index db7bbcc7de49..44b6342826f8 100644 --- a/cli/command/node/remove_test.go +++ b/cli/command/node/remove_test.go @@ -33,6 +33,7 @@ func TestNodeRemoveErrors(t *testing.T) { })) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/node/update_test.go b/cli/command/node/update_test.go index 0421e4757022..09881d7ec200 100644 --- a/cli/command/node/update_test.go +++ b/cli/command/node/update_test.go @@ -64,6 +64,7 @@ func TestNodeUpdateErrors(t *testing.T) { assert.Check(t, cmd.Flags().Set(key, value)) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/plugin/create_test.go b/cli/command/plugin/create_test.go index e05eb6085538..0472f6eae153 100644 --- a/cli/command/plugin/create_test.go +++ b/cli/command/plugin/create_test.go @@ -41,6 +41,7 @@ func TestCreateErrors(t *testing.T) { cmd := newCreateCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -53,6 +54,7 @@ func TestCreateErrorOnFileAsContextDir(t *testing.T) { cmd := newCreateCommand(cli) cmd.SetArgs([]string{"plugin-foo", tmpFile.Path()}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), "context must be a directory") } @@ -64,6 +66,7 @@ func TestCreateErrorOnContextDirWithoutConfig(t *testing.T) { cmd := newCreateCommand(cli) cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) expectedErr := "config.json: no such file or directory" if runtime.GOOS == "windows" { @@ -82,6 +85,7 @@ func TestCreateErrorOnInvalidConfig(t *testing.T) { cmd := newCreateCommand(cli) cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), "invalid") } @@ -98,6 +102,7 @@ func TestCreateErrorFromDaemon(t *testing.T) { })) cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), "error creating plugin") } diff --git a/cli/command/plugin/disable_test.go b/cli/command/plugin/disable_test.go index cd78943c942d..40bfab72ea24 100644 --- a/cli/command/plugin/disable_test.go +++ b/cli/command/plugin/disable_test.go @@ -41,6 +41,7 @@ func TestPluginDisableErrors(t *testing.T) { })) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/plugin/enable_test.go b/cli/command/plugin/enable_test.go index 0f220547562a..20fa25f74098 100644 --- a/cli/command/plugin/enable_test.go +++ b/cli/command/plugin/enable_test.go @@ -51,6 +51,7 @@ func TestPluginEnableErrors(t *testing.T) { cmd.Flags().Set(key, value) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/plugin/inspect_test.go b/cli/command/plugin/inspect_test.go index f5c2ad585760..2dcb8958891e 100644 --- a/cli/command/plugin/inspect_test.go +++ b/cli/command/plugin/inspect_test.go @@ -66,6 +66,7 @@ func TestInspectErrors(t *testing.T) { } for _, tc := range testCases { + tc := tc t.Run(tc.description, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc}) cmd := newInspectCommand(cli) @@ -74,6 +75,7 @@ func TestInspectErrors(t *testing.T) { cmd.Flags().Set(key, value) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) }) } @@ -136,6 +138,7 @@ func TestInspect(t *testing.T) { } for _, tc := range testCases { + tc := tc t.Run(tc.description, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{pluginInspectFunc: tc.inspectFunc}) cmd := newInspectCommand(cli) diff --git a/cli/command/plugin/install_test.go b/cli/command/plugin/install_test.go index 03cad5f110e9..4eb55c1a9199 100644 --- a/cli/command/plugin/install_test.go +++ b/cli/command/plugin/install_test.go @@ -54,11 +54,15 @@ func TestInstallErrors(t *testing.T) { } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc}) - cmd := newInstallCommand(cli) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.description, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc}) + cmd := newInstallCommand(cli) + 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 { - cli := test.NewFakeCli(&fakeClient{ - pluginInstallFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) { - return nil, errors.New("should not try to install plugin") - }, - }, test.EnableContentTrust) - cli.SetNotaryClient(tc.notaryFunc) - cmd := newInstallCommand(cli) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.description, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + pluginInstallFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) { + return nil, errors.New("should not try to install plugin") + }, + }, test.EnableContentTrust) + cli.SetNotaryClient(tc.notaryFunc) + cmd := newInstallCommand(cli) + 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 { - cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc}) - cmd := newInstallCommand(cli) - cmd.SetArgs(tc.args) - assert.NilError(t, cmd.Execute()) - assert.Check(t, strings.Contains(cli.OutBuffer().String(), tc.expectedOutput)) + tc := tc + t.Run(tc.description, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{pluginInstallFunc: tc.installFunc}) + cmd := newInstallCommand(cli) + cmd.SetArgs(tc.args) + assert.NilError(t, cmd.Execute()) + assert.Check(t, strings.Contains(cli.OutBuffer().String(), tc.expectedOutput)) + }) } } diff --git a/cli/command/plugin/list_test.go b/cli/command/plugin/list_test.go index a5e4e71d31a0..07138856fab9 100644 --- a/cli/command/plugin/list_test.go +++ b/cli/command/plugin/list_test.go @@ -46,14 +46,18 @@ func TestListErrors(t *testing.T) { } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc}) - cmd := newListCommand(cli) - cmd.SetArgs(tc.args) - for key, value := range tc.flags { - cmd.Flags().Set(key, value) - } - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.description, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc}) + cmd := newListCommand(cli) + cmd.SetArgs(tc.args) + for key, value := range tc.flags { + cmd.Flags().Set(key, value) + } + 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 { - cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc}) - cmd := newListCommand(cli) - cmd.SetArgs(tc.args) - for key, value := range tc.flags { - cmd.Flags().Set(key, value) - } - assert.NilError(t, cmd.Execute()) - golden.Assert(t, cli.OutBuffer().String(), tc.golden) + tc := tc + t.Run(tc.description, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{pluginListFunc: tc.listFunc}) + cmd := newListCommand(cli) + cmd.SetArgs(tc.args) + for key, value := range tc.flags { + cmd.Flags().Set(key, value) + } + assert.NilError(t, cmd.Execute()) + golden.Assert(t, cli.OutBuffer().String(), tc.golden) + }) } } diff --git a/cli/command/plugin/remove_test.go b/cli/command/plugin/remove_test.go index cf701cfa3b72..de40a28ade52 100644 --- a/cli/command/plugin/remove_test.go +++ b/cli/command/plugin/remove_test.go @@ -37,6 +37,7 @@ func TestRemoveErrors(t *testing.T) { cmd := newRemoveCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/plugin/upgrade_test.go b/cli/command/plugin/upgrade_test.go index f4795efa6635..006998b16ff5 100644 --- a/cli/command/plugin/upgrade_test.go +++ b/cli/command/plugin/upgrade_test.go @@ -32,6 +32,8 @@ func TestUpgradePromptTermination(t *testing.T) { // need to set a remote address that does not match the plugin // reference sent by the `pluginInspectFunc` 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) golden.Assert(t, cli.OutBuffer().String(), "plugin-upgrade-terminate.golden") } diff --git a/cli/command/secret/create_test.go b/cli/command/secret/create_test.go index 6af3aa97f4ab..41c7b853da08 100644 --- a/cli/command/secret/create_test.go +++ b/cli/command/secret/create_test.go @@ -49,6 +49,7 @@ func TestSecretCreateErrors(t *testing.T) { ) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/secret/inspect_test.go b/cli/command/secret/inspect_test.go index 47a28cb8d010..ca509c12494e 100644 --- a/cli/command/secret/inspect_test.go +++ b/cli/command/secret/inspect_test.go @@ -61,6 +61,7 @@ func TestSecretInspectErrors(t *testing.T) { assert.Check(t, cmd.Flags().Set(key, value)) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -92,13 +93,16 @@ func TestSecretInspectWithoutFormat(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{ - secretInspectFunc: tc.secretInspectFunc, + tc := tc + 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 { - cli := test.NewFakeCli(&fakeClient{ - secretInspectFunc: tc.secretInspectFunc, + tc := tc + 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)) } } diff --git a/cli/command/secret/ls_test.go b/cli/command/secret/ls_test.go index 0579612b96a9..161e32f2ce64 100644 --- a/cli/command/secret/ls_test.go +++ b/cli/command/secret/ls_test.go @@ -42,6 +42,7 @@ func TestSecretListErrors(t *testing.T) { ) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } diff --git a/cli/command/secret/remove_test.go b/cli/command/secret/remove_test.go index 8600a98fd314..6b0dfcc2cdff 100644 --- a/cli/command/secret/remove_test.go +++ b/cli/command/secret/remove_test.go @@ -38,6 +38,7 @@ func TestSecretRemoveErrors(t *testing.T) { ) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -74,6 +75,7 @@ func TestSecretRemoveContinueAfterError(t *testing.T) { cmd := newSecretRemoveCommand(cli) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs(names) assert.Error(t, cmd.Execute(), "error removing secret: foo") assert.Check(t, is.DeepEqual(names, removedSecrets)) diff --git a/cli/command/service/rollback_test.go b/cli/command/service/rollback_test.go index 9c5b97bc7674..742d9f99c404 100644 --- a/cli/command/service/rollback_test.go +++ b/cli/command/service/rollback_test.go @@ -91,14 +91,18 @@ func TestRollbackWithErrors(t *testing.T) { } for _, tc := range testCases { - cmd := newRollbackCommand( - test.NewFakeCli(&fakeClient{ - serviceInspectWithRawFunc: tc.serviceInspectWithRawFunc, - serviceUpdateFunc: tc.serviceUpdateFunc, - })) - cmd.SetArgs(tc.args) - cmd.Flags().Set("quiet", "true") - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := newRollbackCommand( + test.NewFakeCli(&fakeClient{ + serviceInspectWithRawFunc: tc.serviceInspectWithRawFunc, + serviceUpdateFunc: tc.serviceUpdateFunc, + })) + cmd.SetArgs(tc.args) + cmd.Flags().Set("quiet", "true") + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + }) } } diff --git a/cli/command/stack/config_test.go b/cli/command/stack/config_test.go index 4a3f88e46afc..ed3dcc9a44c6 100644 --- a/cli/command/stack/config_test.go +++ b/cli/command/stack/config_test.go @@ -13,6 +13,7 @@ import ( func TestConfigWithEmptyComposeFile(t *testing.T) { cmd := newConfigCommand(test.NewFakeCli(&fakeClient{})) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), `Specify a Compose file`) } diff --git a/cli/command/stack/deploy_test.go b/cli/command/stack/deploy_test.go index 86215bdc32e1..df731256bde5 100644 --- a/cli/command/stack/deploy_test.go +++ b/cli/command/stack/deploy_test.go @@ -12,6 +12,7 @@ func TestDeployWithEmptyName(t *testing.T) { cmd := newDeployCommand(test.NewFakeCli(&fakeClient{})) cmd.SetArgs([]string{"' '"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`) } diff --git a/cli/command/stack/list_test.go b/cli/command/stack/list_test.go index f4c2d41b3c01..be76aa7e3da0 100644 --- a/cli/command/stack/list_test.go +++ b/cli/command/stack/list_test.go @@ -25,18 +25,21 @@ func TestListErrors(t *testing.T) { expectedError: "accepts no argument", }, { + args: []string{}, flags: map[string]string{ "format": "{{invalid format}}", }, expectedError: "template parsing error", }, { + args: []string{}, serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { return []swarm.Service{}, errors.Errorf("error getting services") }, expectedError: "error getting services", }, { + args: []string{}, serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { return []swarm.Service{*builders.Service()}, nil }, @@ -45,15 +48,19 @@ func TestListErrors(t *testing.T) { } for _, tc := range testCases { - cmd := newListCommand(test.NewFakeCli(&fakeClient{ - serviceListFunc: tc.serviceListFunc, - })) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - for key, value := range tc.flags { - assert.Check(t, cmd.Flags().Set(key, value)) - } - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.expectedError, func(t *testing.T) { + cmd := newListCommand(test.NewFakeCli(&fakeClient{ + serviceListFunc: tc.serviceListFunc, + })) + cmd.SetArgs(tc.args) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + 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 { + tc := tc t.Run(tc.doc, func(t *testing.T) { var services []swarm.Service for _, name := range tc.serviceNames { diff --git a/cli/command/stack/ps_test.go b/cli/command/stack/ps_test.go index a6b87393608a..e14002e210a6 100644 --- a/cli/command/stack/ps_test.go +++ b/cli/command/stack/ps_test.go @@ -40,12 +40,16 @@ func TestStackPsErrors(t *testing.T) { } for _, tc := range testCases { - cmd := newPsCommand(test.NewFakeCli(&fakeClient{ - taskListFunc: tc.taskListFunc, - })) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.expectedError, func(t *testing.T) { + cmd := newPsCommand(test.NewFakeCli(&fakeClient{ + taskListFunc: tc.taskListFunc, + })) + 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 { + tc := tc t.Run(tc.doc, func(t *testing.T) { cli := test.NewFakeCli(&fakeClient{ taskListFunc: tc.taskListFunc, @@ -169,6 +174,7 @@ func TestStackPs(t *testing.T) { assert.Check(t, cmd.Flags().Set(key, value)) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) if tc.expectedErr != "" { assert.Error(t, cmd.Execute(), tc.expectedErr) diff --git a/cli/command/stack/remove_test.go b/cli/command/stack/remove_test.go index 0c4bd2a8e34a..ed5c9e4f8b26 100644 --- a/cli/command/stack/remove_test.go +++ b/cli/command/stack/remove_test.go @@ -45,6 +45,7 @@ func TestRemoveWithEmptyName(t *testing.T) { cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{})) cmd.SetArgs([]string{"good", "' '", "alsogood"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`) } @@ -157,6 +158,7 @@ func TestRemoveContinueAfterError(t *testing.T) { } cmd := newRemoveCommand(test.NewFakeCli(cli)) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.SetArgs([]string{"foo", "bar"}) assert.Error(t, cmd.Execute(), "Failed to remove some resources from stack: foo") diff --git a/cli/command/stack/services_test.go b/cli/command/stack/services_test.go index 2ec6431558a0..8d24a4e49ea0 100644 --- a/cli/command/stack/services_test.go +++ b/cli/command/stack/services_test.go @@ -80,6 +80,7 @@ func TestStackServicesErrors(t *testing.T) { assert.Check(t, cmd.Flags().Set(key, value)) } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) }) } @@ -89,6 +90,7 @@ func TestRunServicesWithEmptyName(t *testing.T) { cmd := newServicesCommand(test.NewFakeCli(&fakeClient{})) cmd.SetArgs([]string{"' '"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), `invalid stack name: "' '"`) } diff --git a/cli/command/swarm/ca_test.go b/cli/command/swarm/ca_test.go index 29d2cd359ad4..3096079e1757 100644 --- a/cli/command/swarm/ca_test.go +++ b/cli/command/swarm/ca_test.go @@ -145,6 +145,7 @@ func TestDisplayTrustRootInvalidFlags(t *testing.T) { })) assert.Check(t, cmd.Flags().Parse(testCase.args)) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), testCase.errorMsg) } } diff --git a/cli/command/swarm/init_test.go b/cli/command/swarm/init_test.go index e2153040e998..fbed83bde8eb 100644 --- a/cli/command/swarm/init_test.go +++ b/cli/command/swarm/init_test.go @@ -63,18 +63,22 @@ func TestSwarmInitErrorOnAPIFailure(t *testing.T) { }, } for _, tc := range testCases { - cmd := newInitCommand( - test.NewFakeCli(&fakeClient{ - swarmInitFunc: tc.swarmInitFunc, - swarmInspectFunc: tc.swarmInspectFunc, - swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, - nodeInspectFunc: tc.nodeInspectFunc, - })) - for key, value := range tc.flags { - cmd.Flags().Set(key, value) - } - cmd.SetOut(io.Discard) - assert.Error(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := newInitCommand( + test.NewFakeCli(&fakeClient{ + swarmInitFunc: tc.swarmInitFunc, + swarmInspectFunc: tc.swarmInspectFunc, + swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, + nodeInspectFunc: tc.nodeInspectFunc, + })) + for key, value := range tc.flags { + cmd.Flags().Set(key, value) + } + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + assert.Error(t, cmd.Execute(), tc.expectedError) + }) } } diff --git a/cli/command/swarm/join_test.go b/cli/command/swarm/join_test.go index 5ed5e0a29f8f..9a60e9e25e28 100644 --- a/cli/command/swarm/join_test.go +++ b/cli/command/swarm/join_test.go @@ -48,14 +48,18 @@ func TestSwarmJoinErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := newJoinCommand( - test.NewFakeCli(&fakeClient{ - swarmJoinFunc: tc.swarmJoinFunc, - infoFunc: tc.infoFunc, - })) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := newJoinCommand( + test.NewFakeCli(&fakeClient{ + swarmJoinFunc: tc.swarmJoinFunc, + infoFunc: tc.infoFunc, + })) + 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 { - cli := test.NewFakeCli(&fakeClient{ - infoFunc: tc.infoFunc, + tc := tc + 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)) } } diff --git a/cli/command/swarm/join_token_test.go b/cli/command/swarm/join_token_test.go index 3d1bf18de643..21b89e66529b 100644 --- a/cli/command/swarm/join_token_test.go +++ b/cli/command/swarm/join_token_test.go @@ -87,19 +87,23 @@ func TestSwarmJoinTokenErrors(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{ - swarmInspectFunc: tc.swarmInspectFunc, - swarmUpdateFunc: tc.swarmUpdateFunc, - infoFunc: tc.infoFunc, - nodeInspectFunc: tc.nodeInspectFunc, + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + swarmInspectFunc: tc.swarmInspectFunc, + 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 { - cli := test.NewFakeCli(&fakeClient{ - swarmInspectFunc: tc.swarmInspectFunc, - infoFunc: tc.infoFunc, - nodeInspectFunc: tc.nodeInspectFunc, + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + 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)) } } diff --git a/cli/command/swarm/leave_test.go b/cli/command/swarm/leave_test.go index e1005828d067..58192e5ab470 100644 --- a/cli/command/swarm/leave_test.go +++ b/cli/command/swarm/leave_test.go @@ -32,13 +32,17 @@ func TestSwarmLeaveErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := newLeaveCommand( - test.NewFakeCli(&fakeClient{ - swarmLeaveFunc: tc.swarmLeaveFunc, - })) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := newLeaveCommand( + test.NewFakeCli(&fakeClient{ + swarmLeaveFunc: tc.swarmLeaveFunc, + })) + cmd.SetArgs(tc.args) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + }) } } diff --git a/cli/command/swarm/unlock_key_test.go b/cli/command/swarm/unlock_key_test.go index cfe49feb3e47..15d7f2e84022 100644 --- a/cli/command/swarm/unlock_key_test.go +++ b/cli/command/swarm/unlock_key_test.go @@ -80,18 +80,22 @@ func TestSwarmUnlockKeyErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := newUnlockKeyCommand( - test.NewFakeCli(&fakeClient{ - swarmInspectFunc: tc.swarmInspectFunc, - swarmUpdateFunc: tc.swarmUpdateFunc, - swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, - })) - 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) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := newUnlockKeyCommand( + test.NewFakeCli(&fakeClient{ + swarmInspectFunc: tc.swarmInspectFunc, + swarmUpdateFunc: tc.swarmUpdateFunc, + swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, + })) + 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) + }) } } @@ -154,17 +158,20 @@ func TestSwarmUnlockKey(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{ - swarmInspectFunc: tc.swarmInspectFunc, - swarmUpdateFunc: tc.swarmUpdateFunc, - swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + 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)) } } diff --git a/cli/command/swarm/unlock_test.go b/cli/command/swarm/unlock_test.go index c5d533ea9e84..04a996acb518 100644 --- a/cli/command/swarm/unlock_test.go +++ b/cli/command/swarm/unlock_test.go @@ -64,14 +64,18 @@ func TestSwarmUnlockErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := newUnlockCommand( - test.NewFakeCli(&fakeClient{ - infoFunc: tc.infoFunc, - swarmUnlockFunc: tc.swarmUnlockFunc, - })) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := newUnlockCommand( + test.NewFakeCli(&fakeClient{ + infoFunc: tc.infoFunc, + swarmUnlockFunc: tc.swarmUnlockFunc, + })) + cmd.SetArgs(tc.args) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + }) } } diff --git a/cli/command/swarm/update_test.go b/cli/command/swarm/update_test.go index 29432cd55b6e..debab12d2165 100644 --- a/cli/command/swarm/update_test.go +++ b/cli/command/swarm/update_test.go @@ -65,18 +65,22 @@ func TestSwarmUpdateErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := newUpdateCommand( - test.NewFakeCli(&fakeClient{ - swarmInspectFunc: tc.swarmInspectFunc, - swarmUpdateFunc: tc.swarmUpdateFunc, - swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, - })) - 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) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := newUpdateCommand( + test.NewFakeCli(&fakeClient{ + swarmInspectFunc: tc.swarmInspectFunc, + swarmUpdateFunc: tc.swarmUpdateFunc, + swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, + })) + 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) + }) } } @@ -165,18 +169,25 @@ func TestSwarmUpdate(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{ - swarmInspectFunc: tc.swarmInspectFunc, - swarmUpdateFunc: tc.swarmUpdateFunc, - swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + 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)) } } diff --git a/cli/command/system/prune_test.go b/cli/command/system/prune_test.go index 8dadc4c8633d..fa7294467f21 100644 --- a/cli/command/system/prune_test.go +++ b/cli/command/system/prune_test.go @@ -2,6 +2,7 @@ package system import ( "context" + "io" "testing" "github.com/docker/cli/cli/config/configfile" @@ -18,6 +19,8 @@ func TestPrunePromptPre131DoesNotIncludeBuildCache(t *testing.T) { cli := test.NewFakeCli(&fakeClient{version: "1.30"}) cmd := newPruneCommand(cli) cmd.SetArgs([]string{}) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), "system prune has been cancelled") expected := `WARNING! This will remove: - all stopped containers @@ -35,6 +38,8 @@ func TestPrunePromptFilters(t *testing.T) { }) cmd := newPruneCommand(cli) 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") expected := `WARNING! This will remove: @@ -69,5 +74,8 @@ func TestSystemPrunePromptTermination(t *testing.T) { }) cmd := newPruneCommand(cli) + cmd.SetArgs([]string{}) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) test.TerminatePrompt(ctx, t, cmd, cli) } diff --git a/cli/command/system/version_test.go b/cli/command/system/version_test.go index c0cf6425975f..6f8b243de4b4 100644 --- a/cli/command/system/version_test.go +++ b/cli/command/system/version_test.go @@ -3,6 +3,7 @@ package system import ( "context" "errors" + "io" "strings" "testing" @@ -20,7 +21,9 @@ func TestVersionWithoutServer(t *testing.T) { }, }) cmd := NewVersionCommand(cli) + cmd.SetArgs([]string{}) cmd.SetOut(cli.Err()) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), "no server") out := cli.OutBuffer().String() // TODO: use an assertion like e2e/image/build_test.go:assertBuildOutput() diff --git a/cli/command/trust/inspect_pretty_test.go b/cli/command/trust/inspect_pretty_test.go index 13519f1390f5..e64c00c06feb 100644 --- a/cli/command/trust/inspect_pretty_test.go +++ b/cli/command/trust/inspect_pretty_test.go @@ -67,6 +67,7 @@ func TestTrustInspectPrettyCommandErrors(t *testing.T) { test.NewFakeCli(&fakeClient{})) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) cmd.Flags().Set("pretty", "true") assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } @@ -79,6 +80,7 @@ func TestTrustInspectPrettyCommandOfflineErrors(t *testing.T) { cmd.Flags().Set("pretty", "true") cmd.SetArgs([]string{"nonexistent-reg-name.io/image"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access nonexistent-reg-name.io/image") cli = test.NewFakeCli(&fakeClient{}) @@ -87,6 +89,7 @@ func TestTrustInspectPrettyCommandOfflineErrors(t *testing.T) { cmd.Flags().Set("pretty", "true") cmd.SetArgs([]string{"nonexistent-reg-name.io/image:tag"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) 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.SetArgs([]string{"reg/unsigned-img"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), "no signatures or cannot access reg/unsigned-img") cli = test.NewFakeCli(&fakeClient{}) @@ -105,6 +109,7 @@ func TestTrustInspectPrettyCommandUninitializedErrors(t *testing.T) { cmd.Flags().Set("pretty", "true") cmd.SetArgs([]string{"reg/unsigned-img:tag"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) 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.SetArgs([]string{"reg/img:unsigned-tag"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) 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(), "Administrative keys for reg/img")) @@ -125,6 +131,7 @@ func TestTrustInspectPrettyCommandEmptyNotaryRepoErrors(t *testing.T) { cmd.Flags().Set("pretty", "true") cmd.SetArgs([]string{"reg/img"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) 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(), "Administrative keys for reg/img")) diff --git a/cli/command/trust/inspect_test.go b/cli/command/trust/inspect_test.go index 692c5a6737df..5823f329093f 100644 --- a/cli/command/trust/inspect_test.go +++ b/cli/command/trust/inspect_test.go @@ -39,6 +39,7 @@ func TestTrustInspectCommandErrors(t *testing.T) { cmd.Flags().Set("pretty", "true") cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -86,6 +87,7 @@ func TestTrustInspectCommandRepositoryErrors(t *testing.T) { cmd := newInspectCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.err) if tc.golden != "" { golden.Assert(t, cli.OutBuffer().String(), tc.golden) diff --git a/cli/command/trust/key_generate_test.go b/cli/command/trust/key_generate_test.go index 4645c9ae3334..9781a5338461 100644 --- a/cli/command/trust/key_generate_test.go +++ b/cli/command/trust/key_generate_test.go @@ -42,6 +42,7 @@ func TestTrustKeyGenerateErrors(t *testing.T) { cmd := newKeyGenerateCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -50,8 +51,8 @@ func TestGenerateKeySuccess(t *testing.T) { pubKeyCWD := t.TempDir() privKeyStorageDir := t.TempDir() - passwd := "password" - cannedPasswordRetriever := passphrase.ConstantRetriever(passwd) + const testPass = "password" + cannedPasswordRetriever := passphrase.ConstantRetriever(testPass) // generate a single key keyName := "alice" privKeyFileStore, err := trustmanager.NewKeyFileStore(privKeyStorageDir, cannedPasswordRetriever) @@ -87,7 +88,7 @@ func TestGenerateKeySuccess(t *testing.T) { // assert encrypted header assert.Check(t, is.Equal("ENCRYPTED PRIVATE KEY", privKeyPEM.Type)) // check that the passphrase matches - _, err = tufutils.ParsePKCS8ToTufKey(privKeyPEM.Bytes, []byte(passwd)) + _, err = tufutils.ParsePKCS8ToTufKey(privKeyPEM.Bytes, []byte(testPass)) assert.NilError(t, err) // check that the public key exists at the correct path if we use the helper: diff --git a/cli/command/trust/key_load_test.go b/cli/command/trust/key_load_test.go index fae5b858cf95..d32883fc6231 100644 --- a/cli/command/trust/key_load_test.go +++ b/cli/command/trust/key_load_test.go @@ -63,6 +63,7 @@ func TestTrustKeyLoadErrors(t *testing.T) { cmd := newKeyLoadCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) assert.Check(t, is.Contains(cli.OutBuffer().String(), tc.expectedOutput)) } diff --git a/cli/command/trust/revoke_test.go b/cli/command/trust/revoke_test.go index 26e6ef4d014c..7521a7bcf266 100644 --- a/cli/command/trust/revoke_test.go +++ b/cli/command/trust/revoke_test.go @@ -52,6 +52,7 @@ func TestTrustRevokeCommandErrors(t *testing.T) { test.NewFakeCli(&fakeClient{})) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -139,6 +140,7 @@ func TestTrustRevokeCommand(t *testing.T) { cmd := newRevokeCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) if tc.expectedErr != "" { assert.ErrorContains(t, cmd.Execute(), tc.expectedErr) } else { @@ -164,6 +166,8 @@ func TestRevokeTrustPromptTermination(t *testing.T) { cli := test.NewFakeCli(&fakeClient{}) cmd := newRevokeCommand(cli) cmd.SetArgs([]string{"example/trust-demo"}) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) test.TerminatePrompt(ctx, t, cmd, cli) golden.Assert(t, cli.OutBuffer().String(), "trust-revoke-prompt-termination.golden") } diff --git a/cli/command/trust/sign_test.go b/cli/command/trust/sign_test.go index 632403ebf5d3..8249ad893f41 100644 --- a/cli/command/trust/sign_test.go +++ b/cli/command/trust/sign_test.go @@ -67,6 +67,7 @@ func TestTrustSignCommandErrors(t *testing.T) { test.NewFakeCli(&fakeClient{})) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), tc.expectedError) } } @@ -77,6 +78,7 @@ func TestTrustSignCommandOfflineErrors(t *testing.T) { cmd := newSignCommand(cli) cmd.SetArgs([]string{"reg-name.io/image:tag"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), "client is offline") } @@ -260,6 +262,7 @@ func TestSignCommandChangeListIsCleanedOnError(t *testing.T) { cmd := newSignCommand(cli) cmd.SetArgs([]string{"ubuntu:latest"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) err := cmd.Execute() assert.Assert(t, err != nil) @@ -277,5 +280,6 @@ func TestSignCommandLocalFlag(t *testing.T) { cmd := newSignCommand(cli) cmd.SetArgs([]string{"--local", "reg-name.io/image:red"}) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) assert.ErrorContains(t, cmd.Execute(), "error contacting notary server: dial tcp: lookup reg-name.io") } diff --git a/cli/command/trust/signer_add_test.go b/cli/command/trust/signer_add_test.go index 49e1d11c7c2c..492c3df86e5a 100644 --- a/cli/command/trust/signer_add_test.go +++ b/cli/command/trust/signer_add_test.go @@ -60,6 +60,7 @@ func TestTrustSignerAddErrors(t *testing.T) { cmd := newSignerAddCommand(cli) cmd.SetArgs(tc.args) cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) 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.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())) } @@ -90,6 +92,7 @@ func TestSignerAddCommandBadKeyPath(t *testing.T) { cmd.SetArgs([]string{"--key", "/path/to/key.pem", "alice", "alpine"}) 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" if runtime.GOOS == "windows" { 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.SetOut(io.Discard) + cmd.SetErr(io.Discard) 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) diff --git a/cli/command/trust/signer_remove_test.go b/cli/command/trust/signer_remove_test.go index 9b54bcaf2f1a..8e2cc146d909 100644 --- a/cli/command/trust/signer_remove_test.go +++ b/cli/command/trust/signer_remove_test.go @@ -30,41 +30,54 @@ func TestTrustSignerRemoveErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := newSignerRemoveCommand( - test.NewFakeCli(&fakeClient{})) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cmd := newSignerRemoveCommand( + test.NewFakeCli(&fakeClient{})) + cmd.SetArgs(tc.args) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + assert.ErrorContains(t, cmd.Execute(), tc.expectedError) + }) } testCasesWithOutput := []struct { - name string - args []string - expectedError string + name string + args []string + expectedError string + expectedErrOut string }{ { - name: "not-an-image", - args: []string{"user", "notanimage"}, - expectedError: "error retrieving signers for notanimage", + name: "not-an-image", + args: []string{"user", "notanimage"}, + expectedError: "error removing signer from: notanimage", + expectedErrOut: "error retrieving signers for notanimage", }, { - name: "sha-reference", - args: []string{"user", "870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"}, - expectedError: "invalid repository name", + name: "sha-reference", + args: []string{"user", "870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"}, + expectedError: "error removing signer from: 870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd", + expectedErrOut: "invalid repository name", }, { - name: "invalid-img-reference", - args: []string{"user", "ALPINE"}, - expectedError: "invalid reference format", + name: "invalid-img-reference", + args: []string{"user", "ALPINE"}, + expectedError: "error removing signer from: ALPINE", + expectedErrOut: "invalid reference format", }, } for _, tc := range testCasesWithOutput { - cli := test.NewFakeCli(&fakeClient{}) - cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository) - cmd := newSignerRemoveCommand(cli) - cmd.SetArgs(tc.args) - cmd.SetOut(io.Discard) - cmd.Execute() - assert.Check(t, is.Contains(cli.ErrBuffer().String(), tc.expectedError)) + tc := tc + t.Run(tc.name, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{}) + cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository) + cmd := newSignerRemoveCommand(cli) + cmd.SetArgs(tc.args) + 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)) + }) } } diff --git a/cli/command/volume/prune_test.go b/cli/command/volume/prune_test.go index 528e5aee4be3..5cb1aca34a2a 100644 --- a/cli/command/volume/prune_test.go +++ b/cli/command/volume/prune_test.go @@ -166,15 +166,20 @@ func TestVolumePrunePromptNo(t *testing.T) { skip.If(t, runtime.GOOS == "windows", "TODO: fix test on windows") for _, input := range []string{"n", "N", "no", "anything", "really"} { - cli := test.NewFakeCli(&fakeClient{ - volumePruneFunc: simplePruneFunc, - }) + input := input + t.Run(input, func(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + volumePruneFunc: simplePruneFunc, + }) - cli.SetIn(streams.NewIn(io.NopCloser(strings.NewReader(input)))) - cmd := NewPruneCommand(cli) - cmd.SetArgs([]string{}) - assert.ErrorContains(t, cmd.Execute(), "volume prune has been cancelled") - golden.Assert(t, cli.OutBuffer().String(), "volume-prune-no.golden") + cli.SetIn(streams.NewIn(io.NopCloser(strings.NewReader(input)))) + cmd := NewPruneCommand(cli) + cmd.SetArgs([]string{}) + cmd.SetOut(io.Discard) + 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.SetArgs([]string{}) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) test.TerminatePrompt(ctx, t, cmd, cli) golden.Assert(t, cli.OutBuffer().String(), "volume-prune-terminate.golden") } diff --git a/cli/config/configfile/file.go b/cli/config/configfile/file.go index ba9bc9d1d0db..ae9dcb3370c7 100644 --- a/cli/config/configfile/file.go +++ b/cli/config/configfile/file.go @@ -303,6 +303,7 @@ func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig, for registryHostname := range configFile.CredentialHelpers { newAuth, err := configFile.GetAuthConfig(registryHostname) 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) continue } diff --git a/cli/required_test.go b/cli/required_test.go index eadc8645c426..9c5fc0b0c8b4 100644 --- a/cli/required_test.go +++ b/cli/required_test.go @@ -144,5 +144,6 @@ func newDummyCommand(validationFunc cobra.PositionalArgs) *cobra.Command { }, } cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) return cmd } diff --git a/opts/port.go b/opts/port.go index 2f2aa329c8ee..099aae3534d5 100644 --- a/opts/port.go +++ b/opts/port.go @@ -149,6 +149,7 @@ func ConvertPortToPortConfig( for _, binding := range portBindings[port] { 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) }