2018-12-11 09:15:04 -05:00
|
|
|
package cliplugins
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
2020-02-22 12:12:14 -05:00
|
|
|
"gotest.tools/v3/assert"
|
|
|
|
is "gotest.tools/v3/assert/cmp"
|
|
|
|
"gotest.tools/v3/golden"
|
|
|
|
"gotest.tools/v3/icmd"
|
2018-12-11 09:15:04 -05:00
|
|
|
)
|
|
|
|
|
2024-04-26 14:16:51 -04:00
|
|
|
const shortHFlagDeprecated = "Flag shorthand -h has been deprecated, use --help\n"
|
2019-03-28 11:32:23 -04:00
|
|
|
|
2018-12-11 09:15:04 -05:00
|
|
|
// TestRunNonexisting ensures correct behaviour when running a nonexistent plugin.
|
|
|
|
func TestRunNonexisting(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-11 09:15:04 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
res := icmd.RunCmd(run("nonexistent"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 1,
|
2019-03-28 10:30:51 -04:00
|
|
|
Out: icmd.None,
|
2018-12-11 09:15:04 -05:00
|
|
|
})
|
|
|
|
golden.Assert(t, res.Stderr(), "docker-nonexistent-err.golden")
|
|
|
|
}
|
|
|
|
|
2018-12-11 09:52:59 -05:00
|
|
|
// TestHelpNonexisting ensures correct behaviour when invoking help on a nonexistent plugin.
|
|
|
|
func TestHelpNonexisting(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-11 09:52:59 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
res := icmd.RunCmd(run("help", "nonexistent"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 1,
|
2019-03-28 10:30:51 -04:00
|
|
|
Out: icmd.None,
|
2018-12-11 09:52:59 -05:00
|
|
|
})
|
|
|
|
golden.Assert(t, res.Stderr(), "docker-help-nonexistent-err.golden")
|
|
|
|
}
|
|
|
|
|
2018-12-17 11:23:55 -05:00
|
|
|
// TestNonexistingHelp ensures correct behaviour when invoking a
|
|
|
|
// nonexistent plugin with `--help`.
|
|
|
|
func TestNonexistingHelp(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-17 11:23:55 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
res := icmd.RunCmd(run("nonexistent", "--help"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
// This should actually be the whole docker help
|
|
|
|
// output, so spot check instead having of a golden
|
|
|
|
// with everything in, which will change too frequently.
|
2020-10-02 09:41:17 -04:00
|
|
|
Out: "Usage: docker [OPTIONS] COMMAND\n\nA self-sufficient runtime for containers",
|
2019-03-28 10:30:51 -04:00
|
|
|
Err: icmd.None,
|
2018-12-17 11:23:55 -05:00
|
|
|
})
|
2019-03-28 11:32:23 -04:00
|
|
|
// Short -h should be the same, modulo the deprecation message
|
|
|
|
exp := shortHFlagDeprecated + res.Stdout()
|
|
|
|
res = icmd.RunCmd(run("nonexistent", "-h"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
// This should be identical to the --help case above
|
|
|
|
Out: exp,
|
|
|
|
Err: icmd.None,
|
|
|
|
})
|
2018-12-17 11:23:55 -05:00
|
|
|
}
|
|
|
|
|
2018-12-11 09:15:04 -05:00
|
|
|
// TestRunBad ensures correct behaviour when running an existent but invalid plugin
|
|
|
|
func TestRunBad(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-11 09:15:04 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
res := icmd.RunCmd(run("badmeta"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 1,
|
2019-03-28 10:30:51 -04:00
|
|
|
Out: icmd.None,
|
2018-12-11 09:15:04 -05:00
|
|
|
})
|
|
|
|
golden.Assert(t, res.Stderr(), "docker-badmeta-err.golden")
|
|
|
|
}
|
|
|
|
|
2018-12-11 09:52:59 -05:00
|
|
|
// TestHelpBad ensures correct behaviour when invoking help on a existent but invalid plugin.
|
|
|
|
func TestHelpBad(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-11 09:52:59 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
res := icmd.RunCmd(run("help", "badmeta"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
2023-03-27 22:08:07 -04:00
|
|
|
ExitCode: 1,
|
2019-03-28 10:30:51 -04:00
|
|
|
Out: icmd.None,
|
2018-12-11 09:52:59 -05:00
|
|
|
})
|
|
|
|
golden.Assert(t, res.Stderr(), "docker-help-badmeta-err.golden")
|
|
|
|
}
|
|
|
|
|
2018-12-17 11:23:55 -05:00
|
|
|
// TestBadHelp ensures correct behaviour when invoking an
|
|
|
|
// existent but invalid plugin with `--help`.
|
|
|
|
func TestBadHelp(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-17 11:23:55 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
res := icmd.RunCmd(run("badmeta", "--help"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
// This should be literally the whole docker help
|
|
|
|
// output, so spot check instead of a golden with
|
|
|
|
// everything in which will change all the time.
|
2020-10-02 09:41:17 -04:00
|
|
|
Out: "Usage: docker [OPTIONS] COMMAND\n\nA self-sufficient runtime for containers",
|
2019-03-28 10:30:51 -04:00
|
|
|
Err: icmd.None,
|
2018-12-17 11:23:55 -05:00
|
|
|
})
|
2019-03-28 11:32:23 -04:00
|
|
|
// Short -h should be the same, modulo the deprecation message
|
2022-03-30 09:27:25 -04:00
|
|
|
usage := res.Stdout()
|
2019-03-28 11:32:23 -04:00
|
|
|
res = icmd.RunCmd(run("badmeta", "-h"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
// This should be identical to the --help case above
|
2023-03-27 22:08:07 -04:00
|
|
|
Out: shortHFlagDeprecated + usage,
|
|
|
|
Err: icmd.None,
|
2019-03-28 11:32:23 -04:00
|
|
|
})
|
2018-12-17 11:23:55 -05:00
|
|
|
}
|
|
|
|
|
2018-12-11 09:15:04 -05:00
|
|
|
// TestRunGood ensures correct behaviour when running a valid plugin
|
|
|
|
func TestRunGood(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-11 09:15:04 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
res := icmd.RunCmd(run("helloworld"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
Out: "Hello World!",
|
2019-03-28 10:30:51 -04:00
|
|
|
Err: icmd.None,
|
2018-12-11 09:15:04 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-12-11 09:52:59 -05:00
|
|
|
// TestHelpGood ensures correct behaviour when invoking help on a
|
|
|
|
// valid plugin. A global argument is included to ensure it does not
|
|
|
|
// interfere.
|
|
|
|
func TestHelpGood(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-11 09:52:59 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
2019-04-03 06:29:36 -04:00
|
|
|
res := icmd.RunCmd(run("-l", "info", "help", "helloworld"))
|
2019-03-28 10:30:51 -04:00
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
Err: icmd.None,
|
|
|
|
})
|
2018-12-11 09:52:59 -05:00
|
|
|
golden.Assert(t, res.Stdout(), "docker-help-helloworld.golden")
|
|
|
|
}
|
|
|
|
|
2018-12-17 11:23:55 -05:00
|
|
|
// TestGoodHelp ensures correct behaviour when calling a valid plugin
|
|
|
|
// with `--help`. A global argument is used to ensure it does not
|
|
|
|
// interfere.
|
|
|
|
func TestGoodHelp(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-17 11:23:55 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
2019-04-03 06:29:36 -04:00
|
|
|
res := icmd.RunCmd(run("-l", "info", "helloworld", "--help"))
|
2019-03-28 10:30:51 -04:00
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
Err: icmd.None,
|
|
|
|
})
|
2018-12-17 11:23:55 -05:00
|
|
|
// This is the same golden file as `TestHelpGood`, above.
|
|
|
|
golden.Assert(t, res.Stdout(), "docker-help-helloworld.golden")
|
2019-03-28 11:32:23 -04:00
|
|
|
// Short -h should be the same, modulo the deprecation message
|
|
|
|
exp := shortHFlagDeprecated + res.Stdout()
|
2019-04-03 06:29:36 -04:00
|
|
|
res = icmd.RunCmd(run("-l", "info", "helloworld", "-h"))
|
2019-03-28 11:32:23 -04:00
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
// This should be identical to the --help case above
|
|
|
|
Out: exp,
|
|
|
|
Err: icmd.None,
|
|
|
|
})
|
2018-12-17 11:23:55 -05:00
|
|
|
}
|
|
|
|
|
2018-12-11 09:15:04 -05:00
|
|
|
// TestRunGoodSubcommand ensures correct behaviour when running a valid plugin with a subcommand
|
|
|
|
func TestRunGoodSubcommand(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-11 09:15:04 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
res := icmd.RunCmd(run("helloworld", "goodbye"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
Out: "Goodbye World!",
|
2019-03-28 10:30:51 -04:00
|
|
|
Err: icmd.None,
|
2018-12-11 09:15:04 -05:00
|
|
|
})
|
|
|
|
}
|
2018-12-11 09:52:59 -05:00
|
|
|
|
|
|
|
// TestHelpGoodSubcommand ensures correct behaviour when invoking help on a
|
|
|
|
// valid plugin subcommand. A global argument is included to ensure it does not
|
|
|
|
// interfere.
|
|
|
|
func TestHelpGoodSubcommand(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-11 09:52:59 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
2019-04-03 06:29:36 -04:00
|
|
|
res := icmd.RunCmd(run("-l", "info", "help", "helloworld", "goodbye"))
|
2019-03-28 10:30:51 -04:00
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
Err: icmd.None,
|
|
|
|
})
|
2018-12-11 09:52:59 -05:00
|
|
|
golden.Assert(t, res.Stdout(), "docker-help-helloworld-goodbye.golden")
|
|
|
|
}
|
2018-12-17 11:23:55 -05:00
|
|
|
|
|
|
|
// TestGoodSubcommandHelp ensures correct behaviour when calling a valid plugin
|
|
|
|
// with a subcommand and `--help`. A global argument is used to ensure it does not
|
|
|
|
// interfere.
|
|
|
|
func TestGoodSubcommandHelp(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-17 11:23:55 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
2019-04-03 06:29:36 -04:00
|
|
|
res := icmd.RunCmd(run("-l", "info", "helloworld", "goodbye", "--help"))
|
2019-03-28 10:30:51 -04:00
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 0,
|
|
|
|
Err: icmd.None,
|
|
|
|
})
|
2018-12-17 11:23:55 -05:00
|
|
|
// This is the same golden file as `TestHelpGoodSubcommand`, above.
|
|
|
|
golden.Assert(t, res.Stdout(), "docker-help-helloworld-goodbye.golden")
|
|
|
|
}
|
2018-12-17 10:55:38 -05:00
|
|
|
|
|
|
|
// TestCliInitialized tests the code paths which ensure that the Cli
|
2019-04-30 05:19:58 -04:00
|
|
|
// object is initialized whether the plugin uses PersistentRunE or not
|
2018-12-17 10:55:38 -05:00
|
|
|
func TestCliInitialized(t *testing.T) {
|
2019-02-18 06:49:41 -05:00
|
|
|
run, _, cleanup := prepare(t)
|
2018-12-17 10:55:38 -05:00
|
|
|
defer cleanup()
|
|
|
|
|
2019-04-30 05:19:58 -04:00
|
|
|
var apiversion string
|
|
|
|
t.Run("withhook", func(t *testing.T) {
|
|
|
|
res := icmd.RunCmd(run("helloworld", "--pre-run", "apiversion"))
|
|
|
|
res.Assert(t, icmd.Success)
|
|
|
|
assert.Assert(t, res.Stdout() != "")
|
|
|
|
apiversion = res.Stdout()
|
|
|
|
assert.Assert(t, is.Equal(res.Stderr(), "Plugin PersistentPreRunE called"))
|
|
|
|
})
|
|
|
|
t.Run("withouthook", func(t *testing.T) {
|
|
|
|
res := icmd.RunCmd(run("nopersistentprerun"))
|
|
|
|
res.Assert(t, icmd.Success)
|
|
|
|
assert.Assert(t, is.Equal(res.Stdout(), apiversion))
|
|
|
|
})
|
2018-12-17 10:55:38 -05:00
|
|
|
}
|
2019-02-22 12:49:44 -05:00
|
|
|
|
|
|
|
// TestPluginErrorCode tests when the plugin return with a given exit status.
|
|
|
|
// We want to verify that the exit status does not get output to stdout and also that we return the exit code.
|
|
|
|
func TestPluginErrorCode(t *testing.T) {
|
|
|
|
run, _, cleanup := prepare(t)
|
|
|
|
defer cleanup()
|
|
|
|
res := icmd.RunCmd(run("helloworld", "exitstatus2"))
|
|
|
|
res.Assert(t, icmd.Expected{
|
|
|
|
ExitCode: 2,
|
2019-03-28 10:30:51 -04:00
|
|
|
Out: icmd.None,
|
2019-02-22 12:49:44 -05:00
|
|
|
Err: "Exiting with error status 2",
|
|
|
|
})
|
|
|
|
}
|