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  }