From 5db336798c2fc17eb20f049508bb291db8a69d71 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 11 Dec 2018 14:15:04 +0000 Subject: [PATCH] Add some simple e2e tests for executing CLI plugins To help with this add a bad plugin which produces invalid metadata and arrange for it to be built in the e2e container. Signed-off-by: Ian Campbell --- dockerfiles/Dockerfile.e2e | 2 +- e2e/cli-plugins/plugins/badmeta/main.go | 19 ++++++ e2e/cli-plugins/run_test.go | 60 +++++++++++++++++++ .../testdata/docker-badmeta-err.golden | 2 + .../testdata/docker-nonexistent-err.golden | 2 + e2e/cli-plugins/util_test.go | 24 ++++++++ scripts/build/plugins | 2 +- scripts/test/e2e/run | 1 + 8 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 e2e/cli-plugins/plugins/badmeta/main.go create mode 100644 e2e/cli-plugins/run_test.go create mode 100644 e2e/cli-plugins/testdata/docker-badmeta-err.golden create mode 100644 e2e/cli-plugins/testdata/docker-nonexistent-err.golden create mode 100644 e2e/cli-plugins/util_test.go diff --git a/dockerfiles/Dockerfile.e2e b/dockerfiles/Dockerfile.e2e index b2f57e0a10..eedda3b7f5 100644 --- a/dockerfiles/Dockerfile.e2e +++ b/dockerfiles/Dockerfile.e2e @@ -38,6 +38,6 @@ ARG VERSION ARG GITCOMMIT ENV VERSION=${VERSION} GITCOMMIT=${GITCOMMIT} RUN ./scripts/build/binary -RUN ./scripts/build/plugins +RUN ./scripts/build/plugins e2e/cli-plugins/plugins/* CMD ./scripts/test/e2e/entry diff --git a/e2e/cli-plugins/plugins/badmeta/main.go b/e2e/cli-plugins/plugins/badmeta/main.go new file mode 100644 index 0000000000..10bd0eff72 --- /dev/null +++ b/e2e/cli-plugins/plugins/badmeta/main.go @@ -0,0 +1,19 @@ +package main + +// This is not a real plugin, but just returns malformated metadata +// from the subcommand and otherwise exits with failure. + +import ( + "fmt" + "os" + + "github.com/docker/cli/cli-plugins/manager" +) + +func main() { + if len(os.Args) == 2 && os.Args[1] == manager.MetadataSubcommandName { + fmt.Println(`{invalid-json}`) + os.Exit(0) + } + os.Exit(1) +} diff --git a/e2e/cli-plugins/run_test.go b/e2e/cli-plugins/run_test.go new file mode 100644 index 0000000000..e4cd94d59a --- /dev/null +++ b/e2e/cli-plugins/run_test.go @@ -0,0 +1,60 @@ +package cliplugins + +import ( + "testing" + + "gotest.tools/assert" + is "gotest.tools/assert/cmp" + "gotest.tools/golden" + "gotest.tools/icmd" +) + +// TestRunNonexisting ensures correct behaviour when running a nonexistent plugin. +func TestRunNonexisting(t *testing.T) { + run, cleanup := prepare(t) + defer cleanup() + + res := icmd.RunCmd(run("nonexistent")) + res.Assert(t, icmd.Expected{ + ExitCode: 1, + }) + assert.Assert(t, is.Equal(res.Stdout(), "")) + golden.Assert(t, res.Stderr(), "docker-nonexistent-err.golden") +} + +// TestRunBad ensures correct behaviour when running an existent but invalid plugin +func TestRunBad(t *testing.T) { + run, cleanup := prepare(t) + defer cleanup() + + res := icmd.RunCmd(run("badmeta")) + res.Assert(t, icmd.Expected{ + ExitCode: 1, + }) + assert.Assert(t, is.Equal(res.Stdout(), "")) + golden.Assert(t, res.Stderr(), "docker-badmeta-err.golden") +} + +// TestRunGood ensures correct behaviour when running a valid plugin +func TestRunGood(t *testing.T) { + run, cleanup := prepare(t) + defer cleanup() + + res := icmd.RunCmd(run("helloworld")) + res.Assert(t, icmd.Expected{ + ExitCode: 0, + Out: "Hello World!", + }) +} + +// TestRunGoodSubcommand ensures correct behaviour when running a valid plugin with a subcommand +func TestRunGoodSubcommand(t *testing.T) { + run, cleanup := prepare(t) + defer cleanup() + + res := icmd.RunCmd(run("helloworld", "goodbye")) + res.Assert(t, icmd.Expected{ + ExitCode: 0, + Out: "Goodbye World!", + }) +} diff --git a/e2e/cli-plugins/testdata/docker-badmeta-err.golden b/e2e/cli-plugins/testdata/docker-badmeta-err.golden new file mode 100644 index 0000000000..df2344638a --- /dev/null +++ b/e2e/cli-plugins/testdata/docker-badmeta-err.golden @@ -0,0 +1,2 @@ +docker: 'badmeta' is not a docker command. +See 'docker --help' diff --git a/e2e/cli-plugins/testdata/docker-nonexistent-err.golden b/e2e/cli-plugins/testdata/docker-nonexistent-err.golden new file mode 100644 index 0000000000..f2265f6b9e --- /dev/null +++ b/e2e/cli-plugins/testdata/docker-nonexistent-err.golden @@ -0,0 +1,2 @@ +docker: 'nonexistent' is not a docker command. +See 'docker --help' diff --git a/e2e/cli-plugins/util_test.go b/e2e/cli-plugins/util_test.go new file mode 100644 index 0000000000..0ab1aa9566 --- /dev/null +++ b/e2e/cli-plugins/util_test.go @@ -0,0 +1,24 @@ +package cliplugins + +import ( + "fmt" + "os" + "testing" + + "gotest.tools/fs" + "gotest.tools/icmd" +) + +func prepare(t *testing.T) (func(args ...string) icmd.Cmd, func()) { + cfg := fs.NewDir(t, "plugin-test", + fs.WithFile("config.json", fmt.Sprintf(`{"cliPluginsExtraDirs": [%q]}`, os.Getenv("DOCKER_CLI_E2E_PLUGINS_EXTRA_DIRS"))), + ) + run := func(args ...string) icmd.Cmd { + return icmd.Command("docker", append([]string{"--config", cfg.Path()}, args...)...) + } + cleanup := func() { + cfg.Remove() + } + return run, cleanup + +} diff --git a/scripts/build/plugins b/scripts/build/plugins index bc14748b92..fce2689cdc 100755 --- a/scripts/build/plugins +++ b/scripts/build/plugins @@ -8,7 +8,7 @@ set -eu -o pipefail source ./scripts/build/.variables mkdir -p "build/plugins-${GOOS}-${GOARCH}" -for p in cli-plugins/examples/* ; do +for p in cli-plugins/examples/* "$@" ; do [ -d "$p" ] || continue n=$(basename "$p") diff --git a/scripts/test/e2e/run b/scripts/test/e2e/run index 7a401db9ce..d494019419 100755 --- a/scripts/test/e2e/run +++ b/scripts/test/e2e/run @@ -69,6 +69,7 @@ function runtests { TEST_SKIP_PLUGIN_TESTS="${SKIP_PLUGIN_TESTS-}" \ GOPATH="$GOPATH" \ PATH="$PWD/build/:/usr/bin" \ + DOCKER_CLI_E2E_PLUGINS_EXTRA_DIRS="$PWD/build/plugins-linux-amd64" \ "$(which go)" test -v ./e2e/... ${TESTFLAGS-} }