github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/cli/e2e/cli-plugins/run_test.go (about) 1 package cliplugins 2 3 import ( 4 "testing" 5 6 "gotest.tools/v3/assert" 7 is "gotest.tools/v3/assert/cmp" 8 "gotest.tools/v3/golden" 9 "gotest.tools/v3/icmd" 10 ) 11 12 const shortHFlagDeprecated = "Flag shorthand -h has been deprecated, please use --help\n" 13 14 // TestRunNonexisting ensures correct behaviour when running a nonexistent plugin. 15 func TestRunNonexisting(t *testing.T) { 16 run, _, cleanup := prepare(t) 17 defer cleanup() 18 19 res := icmd.RunCmd(run("nonexistent")) 20 res.Assert(t, icmd.Expected{ 21 ExitCode: 1, 22 Out: icmd.None, 23 }) 24 golden.Assert(t, res.Stderr(), "docker-nonexistent-err.golden") 25 } 26 27 // TestHelpNonexisting ensures correct behaviour when invoking help on a nonexistent plugin. 28 func TestHelpNonexisting(t *testing.T) { 29 run, _, cleanup := prepare(t) 30 defer cleanup() 31 32 res := icmd.RunCmd(run("help", "nonexistent")) 33 res.Assert(t, icmd.Expected{ 34 ExitCode: 1, 35 Out: icmd.None, 36 }) 37 golden.Assert(t, res.Stderr(), "docker-help-nonexistent-err.golden") 38 } 39 40 // TestNonexistingHelp ensures correct behaviour when invoking a 41 // nonexistent plugin with `--help`. 42 func TestNonexistingHelp(t *testing.T) { 43 run, _, cleanup := prepare(t) 44 defer cleanup() 45 46 res := icmd.RunCmd(run("nonexistent", "--help")) 47 res.Assert(t, icmd.Expected{ 48 ExitCode: 0, 49 // This should actually be the whole docker help 50 // output, so spot check instead having of a golden 51 // with everything in, which will change too frequently. 52 Out: "Usage: docker [OPTIONS] COMMAND\n\nA self-sufficient runtime for containers", 53 Err: icmd.None, 54 }) 55 // Short -h should be the same, modulo the deprecation message 56 exp := shortHFlagDeprecated + res.Stdout() 57 res = icmd.RunCmd(run("nonexistent", "-h")) 58 res.Assert(t, icmd.Expected{ 59 ExitCode: 0, 60 // This should be identical to the --help case above 61 Out: exp, 62 Err: icmd.None, 63 }) 64 } 65 66 // TestRunBad ensures correct behaviour when running an existent but invalid plugin 67 func TestRunBad(t *testing.T) { 68 run, _, cleanup := prepare(t) 69 defer cleanup() 70 71 res := icmd.RunCmd(run("badmeta")) 72 res.Assert(t, icmd.Expected{ 73 ExitCode: 1, 74 Out: icmd.None, 75 }) 76 golden.Assert(t, res.Stderr(), "docker-badmeta-err.golden") 77 } 78 79 // TestHelpBad ensures correct behaviour when invoking help on a existent but invalid plugin. 80 func TestHelpBad(t *testing.T) { 81 run, _, cleanup := prepare(t) 82 defer cleanup() 83 84 res := icmd.RunCmd(run("help", "badmeta")) 85 res.Assert(t, icmd.Expected{ 86 ExitCode: 1, 87 Out: icmd.None, 88 }) 89 golden.Assert(t, res.Stderr(), "docker-help-badmeta-err.golden") 90 } 91 92 // TestBadHelp ensures correct behaviour when invoking an 93 // existent but invalid plugin with `--help`. 94 func TestBadHelp(t *testing.T) { 95 run, _, cleanup := prepare(t) 96 defer cleanup() 97 98 res := icmd.RunCmd(run("badmeta", "--help")) 99 res.Assert(t, icmd.Expected{ 100 ExitCode: 0, 101 // This should be literally the whole docker help 102 // output, so spot check instead of a golden with 103 // everything in which will change all the time. 104 Out: "Usage: docker [OPTIONS] COMMAND\n\nA self-sufficient runtime for containers", 105 Err: icmd.None, 106 }) 107 // Short -h should be the same, modulo the deprecation message 108 exp := shortHFlagDeprecated + res.Stdout() 109 res = icmd.RunCmd(run("badmeta", "-h")) 110 res.Assert(t, icmd.Expected{ 111 ExitCode: 0, 112 // This should be identical to the --help case above 113 Out: exp, 114 Err: icmd.None, 115 }) 116 } 117 118 // TestRunGood ensures correct behaviour when running a valid plugin 119 func TestRunGood(t *testing.T) { 120 run, _, cleanup := prepare(t) 121 defer cleanup() 122 123 res := icmd.RunCmd(run("helloworld")) 124 res.Assert(t, icmd.Expected{ 125 ExitCode: 0, 126 Out: "Hello World!", 127 Err: icmd.None, 128 }) 129 } 130 131 // TestHelpGood ensures correct behaviour when invoking help on a 132 // valid plugin. A global argument is included to ensure it does not 133 // interfere. 134 func TestHelpGood(t *testing.T) { 135 run, _, cleanup := prepare(t) 136 defer cleanup() 137 138 res := icmd.RunCmd(run("-l", "info", "help", "helloworld")) 139 res.Assert(t, icmd.Expected{ 140 ExitCode: 0, 141 Err: icmd.None, 142 }) 143 golden.Assert(t, res.Stdout(), "docker-help-helloworld.golden") 144 } 145 146 // TestGoodHelp ensures correct behaviour when calling a valid plugin 147 // with `--help`. A global argument is used to ensure it does not 148 // interfere. 149 func TestGoodHelp(t *testing.T) { 150 run, _, cleanup := prepare(t) 151 defer cleanup() 152 153 res := icmd.RunCmd(run("-l", "info", "helloworld", "--help")) 154 res.Assert(t, icmd.Expected{ 155 ExitCode: 0, 156 Err: icmd.None, 157 }) 158 // This is the same golden file as `TestHelpGood`, above. 159 golden.Assert(t, res.Stdout(), "docker-help-helloworld.golden") 160 // Short -h should be the same, modulo the deprecation message 161 exp := shortHFlagDeprecated + res.Stdout() 162 res = icmd.RunCmd(run("-l", "info", "helloworld", "-h")) 163 res.Assert(t, icmd.Expected{ 164 ExitCode: 0, 165 // This should be identical to the --help case above 166 Out: exp, 167 Err: icmd.None, 168 }) 169 } 170 171 // TestRunGoodSubcommand ensures correct behaviour when running a valid plugin with a subcommand 172 func TestRunGoodSubcommand(t *testing.T) { 173 run, _, cleanup := prepare(t) 174 defer cleanup() 175 176 res := icmd.RunCmd(run("helloworld", "goodbye")) 177 res.Assert(t, icmd.Expected{ 178 ExitCode: 0, 179 Out: "Goodbye World!", 180 Err: icmd.None, 181 }) 182 } 183 184 // TestHelpGoodSubcommand ensures correct behaviour when invoking help on a 185 // valid plugin subcommand. A global argument is included to ensure it does not 186 // interfere. 187 func TestHelpGoodSubcommand(t *testing.T) { 188 run, _, cleanup := prepare(t) 189 defer cleanup() 190 191 res := icmd.RunCmd(run("-l", "info", "help", "helloworld", "goodbye")) 192 res.Assert(t, icmd.Expected{ 193 ExitCode: 0, 194 Err: icmd.None, 195 }) 196 golden.Assert(t, res.Stdout(), "docker-help-helloworld-goodbye.golden") 197 } 198 199 // TestGoodSubcommandHelp ensures correct behaviour when calling a valid plugin 200 // with a subcommand and `--help`. A global argument is used to ensure it does not 201 // interfere. 202 func TestGoodSubcommandHelp(t *testing.T) { 203 run, _, cleanup := prepare(t) 204 defer cleanup() 205 206 res := icmd.RunCmd(run("-l", "info", "helloworld", "goodbye", "--help")) 207 res.Assert(t, icmd.Expected{ 208 ExitCode: 0, 209 Err: icmd.None, 210 }) 211 // This is the same golden file as `TestHelpGoodSubcommand`, above. 212 golden.Assert(t, res.Stdout(), "docker-help-helloworld-goodbye.golden") 213 } 214 215 // TestCliInitialized tests the code paths which ensure that the Cli 216 // object is initialized whether the plugin uses PersistentRunE or not 217 func TestCliInitialized(t *testing.T) { 218 run, _, cleanup := prepare(t) 219 defer cleanup() 220 221 var apiversion string 222 t.Run("withhook", func(t *testing.T) { 223 res := icmd.RunCmd(run("helloworld", "--pre-run", "apiversion")) 224 res.Assert(t, icmd.Success) 225 assert.Assert(t, res.Stdout() != "") 226 apiversion = res.Stdout() 227 assert.Assert(t, is.Equal(res.Stderr(), "Plugin PersistentPreRunE called")) 228 }) 229 t.Run("withouthook", func(t *testing.T) { 230 res := icmd.RunCmd(run("nopersistentprerun")) 231 res.Assert(t, icmd.Success) 232 assert.Assert(t, is.Equal(res.Stdout(), apiversion)) 233 }) 234 } 235 236 // TestPluginErrorCode tests when the plugin return with a given exit status. 237 // We want to verify that the exit status does not get output to stdout and also that we return the exit code. 238 func TestPluginErrorCode(t *testing.T) { 239 run, _, cleanup := prepare(t) 240 defer cleanup() 241 res := icmd.RunCmd(run("helloworld", "exitstatus2")) 242 res.Assert(t, icmd.Expected{ 243 ExitCode: 2, 244 Out: icmd.None, 245 Err: "Exiting with error status 2", 246 }) 247 }