mirror of https://github.com/docker/cli.git
7 Commits
Author | SHA1 | Message | Date |
---|---|---|---|
Sebastiaan van Stijn |
ca9636a1c3
|
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
|
|
Sebastiaan van Stijn |
dfec976e84
|
linting: fmt.Errorf can be replaced with errors.New (perfsprint)
internal/test/cli.go:175:14: fmt.Errorf can be replaced with errors.New (perfsprint) return nil, fmt.Errorf("no notary client available unless defined") ^ cli/command/cli.go:318:29: fmt.Errorf can be replaced with errors.New (perfsprint) return docker.Endpoint{}, fmt.Errorf("no context store initialized") ^ cli/command/container/attach.go:161:11: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf(result.Error.Message) ^ cli/command/container/opts.go:577:16: fmt.Errorf can be replaced with errors.New (perfsprint) return nil, fmt.Errorf("--health-start-period cannot be negative") ^ cli/command/container/opts.go:580:16: fmt.Errorf can be replaced with errors.New (perfsprint) return nil, fmt.Errorf("--health-start-interval cannot be negative") ^ cli/command/container/stats.go:221:11: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("filtering is not supported when specifying a list of containers") ^ cli/command/container/attach_test.go:82:17: fmt.Errorf can be replaced with errors.New (perfsprint) expectedErr = fmt.Errorf("unexpected error") ^ cli/command/container/create_test.go:234:40: fmt.Errorf can be replaced with errors.New (perfsprint) return container.CreateResponse{}, fmt.Errorf("shouldn't try to pull image") ^ cli/command/container/list_test.go:150:17: fmt.Errorf can be replaced with errors.New (perfsprint) return nil, fmt.Errorf("error listing containers") ^ cli/command/container/rm_test.go:40:31: fmt.Errorf can be replaced with errors.New (perfsprint) return errdefs.NotFound(fmt.Errorf("Error: no such container: " + container)) ^ cli/command/container/run_test.go:138:40: fmt.Errorf can be replaced with errors.New (perfsprint) return container.CreateResponse{}, fmt.Errorf("shouldn't try to pull image") ^ cli/command/image/pull_test.go:115:49: fmt.Errorf can be replaced with errors.New (perfsprint) return io.NopCloser(strings.NewReader("")), fmt.Errorf("shouldn't try to pull image") ^ cli/command/network/connect.go:88:16: fmt.Errorf can be replaced with errors.New (perfsprint) return nil, fmt.Errorf("invalid key/value pair format in driver options") ^ cli/command/plugin/create_test.go:96:11: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("Error creating plugin") ^ cli/command/plugin/disable_test.go:32:12: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("Error disabling plugin") ^ cli/command/plugin/enable_test.go:32:12: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("failed to enable plugin") ^ cli/command/plugin/inspect_test.go:55:22: fmt.Errorf can be replaced with errors.New (perfsprint) return nil, nil, fmt.Errorf("error inspecting plugin") ^ cli/command/plugin/install_test.go:43:17: fmt.Errorf can be replaced with errors.New (perfsprint) return nil, fmt.Errorf("Error installing plugin") ^ cli/command/plugin/install_test.go:51:17: fmt.Errorf can be replaced with errors.New (perfsprint) return nil, fmt.Errorf("(image) when fetching") ^ cli/command/plugin/install_test.go:95:17: fmt.Errorf can be replaced with errors.New (perfsprint) return nil, fmt.Errorf("should not try to install plugin") ^ cli/command/plugin/list_test.go:35:41: fmt.Errorf can be replaced with errors.New (perfsprint) return types.PluginsListResponse{}, fmt.Errorf("error listing plugins") ^ cli/command/plugin/remove_test.go:27:12: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("Error removing plugin") ^ cli/command/registry/login_test.go:36:46: fmt.Errorf can be replaced with errors.New (perfsprint) return registrytypes.AuthenticateOKBody{}, fmt.Errorf("Invalid Username or Password") ^ cli/command/registry/login_test.go:44:46: fmt.Errorf can be replaced with errors.New (perfsprint) return registrytypes.AuthenticateOKBody{}, fmt.Errorf(errUnknownUser) ^ cli/command/system/info.go:190:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("errors pretty printing info") ^ cli/command/system/prune.go:77:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf(`ERROR: The "until" filter is not supported with "--volumes"`) ^ cli/command/system/version_test.go:19:28: fmt.Errorf can be replaced with errors.New (perfsprint) return types.Version{}, fmt.Errorf("no server") ^ cli/command/trust/key_load.go:112:22: fmt.Errorf can be replaced with errors.New (perfsprint) return []byte{}, fmt.Errorf("could not decrypt key") ^ cli/command/trust/revoke.go:44:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("cannot use a digest reference for IMAGE:TAG") ^ cli/command/trust/revoke.go:105:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("no signed tags to remove") ^ cli/command/trust/signer_add.go:56:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("releases is a reserved keyword, please use a different signer name") ^ cli/command/trust/signer_add.go:60:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("path to a public key must be provided using the `--key` flag") ^ opts/config.go:71:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("source is required") ^ opts/mount.go:168:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("type is required") ^ opts/mount.go:172:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("target is required") ^ opts/network.go:90:11: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("network name/id is not specified") ^ opts/network.go:129:18: fmt.Errorf can be replaced with errors.New (perfsprint) return "", "", fmt.Errorf("invalid key value pair format in driver options") ^ opts/opts.go:404:13: fmt.Errorf can be replaced with errors.New (perfsprint) return 0, fmt.Errorf("value is too precise") ^ opts/opts.go:412:18: fmt.Errorf can be replaced with errors.New (perfsprint) return "", "", fmt.Errorf("empty string specified for links") ^ opts/parse.go:84:37: fmt.Errorf can be replaced with errors.New (perfsprint) return container.RestartPolicy{}, fmt.Errorf("invalid restart policy format: no policy provided before colon") ^ opts/parse.go:89:38: fmt.Errorf can be replaced with errors.New (perfsprint) return container.RestartPolicy{}, fmt.Errorf("invalid restart policy format: maximum retry count must be an integer") ^ opts/port.go:105:13: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("hostip is not supported") ^ opts/secret.go:70:10: fmt.Errorf can be replaced with errors.New (perfsprint) return fmt.Errorf("source is required") ^ opts/env_test.go:57:11: fmt.Errorf can be replaced with errors.New (perfsprint) err: fmt.Errorf("invalid environment variable: =a"), ^ opts/env_test.go:93:11: fmt.Errorf can be replaced with errors.New (perfsprint) err: fmt.Errorf("invalid environment variable: ="), ^ cli-plugins/manager/error_test.go:16:11: fmt.Errorf can be replaced with errors.New (perfsprint) inner := fmt.Errorf("testing") ^ Signed-off-by: Sebastiaan van Stijn <github@gone.nl> |
|
Sebastiaan van Stijn |
46d0ba20f1
|
vendor: github.com/docker/docker cdb3f9fb8dca (v25.0.0-dev)
full diff:
|
|
Paweł Gronowski |
b811057181
|
cli/rm_test: Fix TestRemoveForce race condition
Synchronize append on the `removed` slice with mutex because containerRemoveFunc is called in parallel for each removed container by `container rm` cli command. Also reduced the shared access area by separating the scopes of test cases. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com> |
|
Sebastiaan van Stijn |
9688f62d20
|
fix race condition in TestRemoveForce
This test uses two subtests that were sharing the same variable. Subtests run in a goroutine, which could lead to them concurrently accessing the variable, resulting in a panic: === FAIL: cli/command/container TestRemoveForce/without_force (0.00s) Error: Error: No such container: nosuchcontainer --- FAIL: TestRemoveForce/without_force (0.00s) panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x40393f] goroutine 190 [running]: testing.tRunner.func1.2({0xb76380, 0x124c9a0}) /usr/local/go/src/testing/testing.go:1389 +0x24e testing.tRunner.func1() /usr/local/go/src/testing/testing.go:1392 +0x39f panic({0xb76380, 0x124c9a0}) /usr/local/go/src/runtime/panic.go:838 +0x207 sort.StringSlice.Less(...) /usr/local/go/src/sort/sort.go:319 sort.insertionSort({0xd87380, 0xc00051b3b0}, 0x0, 0x2) /usr/local/go/src/sort/sort.go:40 +0xb1 sort.quickSort({0xd87380, 0xc00051b3b0}, 0x18?, 0xb4f060?, 0xc000540e01?) /usr/local/go/src/sort/sort.go:222 +0x171 sort.Sort({0xd87380, 0xc00051b3b0}) /usr/local/go/src/sort/sort.go:231 +0x53 sort.Strings(...) /usr/local/go/src/sort/sort.go:335 github.com/docker/cli/cli/command/container.TestRemoveForce.func2(0xc0005389c0?) /go/src/github.com/docker/cli/cli/command/container/rm_test.go:36 +0x125 testing.tRunner(0xc00053e4e0, 0xc00051b140) /usr/local/go/src/testing/testing.go:1439 +0x102 created by testing.(*T).Run /usr/local/go/src/testing/testing.go:1486 +0x35f === FAIL: cli/command/container TestRemoveForce (0.00s) This patch changes the test to use to separate variables. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> |
|
Sebastiaan van Stijn |
e946bf0804
|
cli/command/container: remove deprecated io/ioutil
Signed-off-by: Sebastiaan van Stijn <github@gone.nl> |
|
Sebastiaan van Stijn |
9a071a993a
|
Return zero exit-code when force-removing non-existing containers
When using `docker rm` / `docker container rm` with the `-f` / `--force` option, attempts to remove non-existing containers should print a warning, but should return a zero exit code ("successful"). Currently, a non-zero exit code is returned, marking the removal as "failed"; $ docker rm -fv 798c9471b695 Error: No such container: 798c9471b695 $ echo $? 1 The command should match the behavior of `rm` / `rm -f`, with the exception that a warning is printed (instead of silently ignored): Running `rm` with `-f` silences output and returns a zero exit code: touch some-file && rm -f no-such-file some-file; echo exit code: $?; ls -la # exit code: 0 # total 0 # drwxr-xr-x 2 sebastiaan staff 64 Aug 14 12:17 . # drwxr-xr-x 199 sebastiaan staff 6368 Aug 14 12:13 .. mkdir some-directory && rm -rf no-such-directory some-directory; echo exit code: $?; ls -la # exit code: 0 # total 0 # drwxr-xr-x 2 sebastiaan staff 64 Aug 14 12:17 . # drwxr-xr-x 199 sebastiaan staff 6368 Aug 14 12:13 .. Note that other reasons for a delete to fail should still result in a non-zero exit code, matching the behavior of `rm`. For instance, in the example below, the `rm` failed because directories can only be removed if the `-r` option is used; touch some-file && mkdir some-directory && rm -f some-directory no-such-file some-file; echo exit code: $?; ls -la # rm: some-directory: is a directory # exit code: 1 # total 0 # drwxr-xr-x 3 sebastiaan staff 96 Aug 14 14:15 . # drwxr-xr-x 199 sebastiaan staff 6368 Aug 14 12:13 .. # drwxr-xr-x 2 sebastiaan staff 64 Aug 14 14:15 some-directory This patch updates the `docker rm` / `docker container rm` command to not produce an error when attempting to remove a missing containers, and instead only print the error, but return a zero (0) exit code. With this patch applied: docker create --name mycontainer busybox \ && docker rm nosuchcontainer mycontainer; \ echo exit code: $?; \ docker ps -a --filter name=mycontainer # df23cc8573f00e97d6e948b48d9ea7d75ce3b4faaab4fe1d3458d3bfa451f39d # mycontainer # Error: No such container: nosuchcontainer # exit code: 0 # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES Signed-off-by: Sebastiaan van Stijn <github@gone.nl> |