| package cliplugins | |
| import ( | |
| "fmt" | |
| "os" | |
| "testing" | |
| "gotest.tools/v3/icmd" | |
| ) | |
| // TestRunGoodArgument ensures correct behaviour when running a valid plugin with an `--argument`. | |
| func TestRunGoodArgument(t *testing.T) { | |
| run, _, cleanup := prepare(t) | |
| defer cleanup() | |
| res := icmd.RunCmd(run("helloworld", "--who", "Cleveland")) | |
| res.Assert(t, icmd.Expected{ | |
| ExitCode: 0, | |
| Out: "Hello Cleveland", | |
| }) | |
| } | |
| // TestClashWithGlobalArgs ensures correct behaviour when a plugin | |
| // has an argument with the same name as one of the globals. | |
| func TestClashWithGlobalArgs(t *testing.T) { | |
| run, _, cleanup := prepare(t) | |
| defer cleanup() | |
| for _, tc := range []struct { | |
| name string | |
| args []string | |
| expectedOut, expectedErr string | |
| }{ | |
| { | |
| name: "short-without-val", | |
| args: []string{"-D"}, | |
| expectedOut: "Hello World", | |
| expectedErr: "Plugin debug mode enabled", | |
| }, | |
| { | |
| name: "long-without-val", | |
| args: []string{"--debug"}, | |
| expectedOut: "Hello World", | |
| expectedErr: "Plugin debug mode enabled", | |
| }, | |
| { | |
| name: "short-with-val", | |
| args: []string{"-c", "Christmas"}, | |
| expectedOut: "Merry Christmas", | |
| expectedErr: icmd.None, | |
| }, | |
| { | |
| name: "short-with-val", | |
| args: []string{"--context", "Christmas"}, | |
| expectedOut: "Merry Christmas", | |
| expectedErr: icmd.None, | |
| }, | |
| } { | |
| t.Run(tc.name, func(t *testing.T) { | |
| args := append([]string{"helloworld"}, tc.args...) | |
| res := icmd.RunCmd(run(args...)) | |
| res.Assert(t, icmd.Expected{ | |
| ExitCode: 0, | |
| Out: tc.expectedOut, | |
| Err: tc.expectedErr, | |
| }) | |
| }) | |
| } | |
| } | |
| // TestGlobalArgsOnlyParsedOnce checks that global args are only parsed | |
| // once (cf https://github.com/docker/cli/issues/1801). These tests | |
| // rely on `-H` being a list type (i.e. NewNamedListOptsRef) which | |
| // reject multiple uses dynamically (see `getServerHost()` in | |
| // github.com/docker/cli/cli/command/cli.go) in order to detect this | |
| // scenario. | |
| func TestGlobalArgsOnlyParsedOnce(t *testing.T) { | |
| run, _, cleanup := prepare(t) | |
| defer cleanup() | |
| // We can rely on `$DOCKER_HOST` being set due to the call to | |
| // `environment.Setup` in our `TestMain`. | |
| dh := os.Getenv("DOCKER_HOST") | |
| for _, tc := range []struct { | |
| name string | |
| args []string | |
| expectedExitCode int | |
| expectedOut, expectedErr string | |
| }{ | |
| { | |
| // This is checking the precondition wrt -H mentioned in the function comment | |
| name: "fails-if-H-used-twice", | |
| args: []string{"-H", dh, "-H", dh, "version", "-f", "{{.Client.Version}}"}, | |
| expectedExitCode: 125, | |
| expectedOut: icmd.None, | |
| expectedErr: fmt.Sprintf(`invalid argument %q for "-H, --host" flag: specify only one -H`, dh), | |
| }, | |
| { | |
| name: "builtin", | |
| args: []string{"-H", dh, "version", "-f", "{{.Client.Version}}"}, | |
| expectedExitCode: 0, | |
| expectedOut: "", // Will be the client version, but the specifics aren't important so long as stderr is empty. | |
| expectedErr: icmd.None, | |
| }, | |
| { | |
| name: "plugin", | |
| args: []string{"-H", dh, "helloworld", "apiversion"}, | |
| expectedExitCode: 0, | |
| expectedOut: "", // Will be the client version, but the specifics aren't important so long as stderr is empty. | |
| expectedErr: icmd.None, | |
| }, | |
| } { | |
| t.Run(tc.name, func(t *testing.T) { | |
| res := icmd.RunCmd(run(tc.args...)) | |
| res.Assert(t, icmd.Expected{ | |
| ExitCode: tc.expectedExitCode, | |
| Out: tc.expectedOut, | |
| Err: tc.expectedErr, | |
| }) | |
| }) | |
| } | |
| } | |
| // TestUnknownGlobal checks that unknown globals report errors | |
| func TestUnknownGlobal(t *testing.T) { | |
| run, _, cleanup := prepare(t) | |
| defer cleanup() | |
| for name, args := range map[string][]string{ | |
| "no-val": {"--unknown", "helloworld"}, | |
| "separate-val": {"--unknown", "foo", "helloworld"}, | |
| "joined-val": {"--unknown=foo", "helloworld"}, | |
| } { | |
| t.Run(name, func(t *testing.T) { | |
| res := icmd.RunCmd(run(args...)) | |
| res.Assert(t, icmd.Expected{ | |
| ExitCode: 125, | |
| Out: icmd.None, | |
| Err: "unknown flag: --unknown", | |
| }) | |
| }) | |
| } | |
| } | |
| // TestCliPluginsVersion checks that `-v` and friends DTRT | |
| func TestCliPluginsVersion(t *testing.T) { | |
| run, _, cleanup := prepare(t) | |
| defer cleanup() | |
| for _, tc := range []struct { | |
| name string | |
| args []string | |
| expCode int | |
| expOut, expErr string | |
| }{ | |
| { | |
| name: "global-version", | |
| args: []string{"version"}, | |
| expCode: 0, | |
| expOut: "Client:\n Version:", | |
| expErr: icmd.None, | |
| }, | |
| { | |
| name: "global-version-flag", | |
| args: []string{"--version"}, | |
| expCode: 0, | |
| expOut: "Docker version", | |
| expErr: icmd.None, | |
| }, | |
| { | |
| name: "global-short-version-flag", | |
| args: []string{"-v"}, | |
| expCode: 0, | |
| expOut: "Docker version", | |
| expErr: icmd.None, | |
| }, | |
| { | |
| name: "global-with-unknown-arg", | |
| args: []string{"version", "foo"}, | |
| expCode: 1, | |
| expOut: icmd.None, | |
| expErr: `docker: 'docker version' accepts no arguments`, | |
| }, | |
| { | |
| name: "global-with-plugin-arg", | |
| args: []string{"version", "helloworld"}, | |
| expCode: 1, | |
| expOut: icmd.None, | |
| expErr: `docker: 'docker version' accepts no arguments`, | |
| }, | |
| { | |
| name: "global-version-flag-with-unknown-arg", | |
| args: []string{"--version", "foo"}, | |
| expCode: 0, | |
| expOut: "Docker version", | |
| expErr: icmd.None, | |
| }, | |
| { | |
| name: "global-short-version-flag-with-unknown-arg", | |
| args: []string{"-v", "foo"}, | |
| expCode: 0, | |
| expOut: "Docker version", | |
| expErr: icmd.None, | |
| }, | |
| { | |
| name: "global-version-flag-with-plugin", | |
| args: []string{"--version", "helloworld"}, | |
| expCode: 125, | |
| expOut: icmd.None, | |
| expErr: "unknown flag: --version", | |
| }, | |
| { | |
| name: "global-short-version-flag-with-plugin", | |
| args: []string{"-v", "helloworld"}, | |
| expCode: 125, | |
| expOut: icmd.None, | |
| expErr: "unknown shorthand flag: 'v' in -v", | |
| }, | |
| { | |
| name: "plugin-with-version", | |
| args: []string{"helloworld", "version"}, | |
| expCode: 0, | |
| expOut: "Hello World", | |
| expErr: icmd.None, | |
| }, | |
| { | |
| name: "plugin-with-version-flag", | |
| args: []string{"helloworld", "--version"}, | |
| expCode: 125, | |
| expOut: icmd.None, | |
| expErr: "unknown flag: --version", | |
| }, | |
| { | |
| name: "plugin-with-short-version-flag", | |
| args: []string{"helloworld", "-v"}, | |
| expCode: 125, | |
| expOut: icmd.None, | |
| expErr: "unknown shorthand flag: 'v' in -v", | |
| }, | |
| { | |
| name: "", | |
| args: []string{}, | |
| expCode: 0, | |
| expOut: "", | |
| expErr: "", | |
| }, | |
| } { | |
| t.Run(tc.name, func(t *testing.T) { | |
| res := icmd.RunCmd(run(tc.args...)) | |
| res.Assert(t, icmd.Expected{ | |
| ExitCode: tc.expCode, | |
| Out: tc.expOut, | |
| Err: tc.expErr, | |
| }) | |
| }) | |
| } | |
| } |