github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/cli/e2e/cli-plugins/help_test.go (about) 1 package cliplugins 2 3 import ( 4 "bufio" 5 "regexp" 6 "strings" 7 "testing" 8 9 "gotest.tools/v3/assert" 10 is "gotest.tools/v3/assert/cmp" 11 "gotest.tools/v3/icmd" 12 ) 13 14 // TestGlobalHelp ensures correct behaviour when running `docker help` 15 func TestGlobalHelp(t *testing.T) { 16 run, _, cleanup := prepare(t) 17 defer cleanup() 18 19 res := icmd.RunCmd(run("help")) 20 res.Assert(t, icmd.Expected{ 21 ExitCode: 0, 22 }) 23 assert.Assert(t, is.Equal(res.Stderr(), "")) 24 scanner := bufio.NewScanner(strings.NewReader(res.Stdout())) 25 26 // Instead of baking in the full current output of `docker 27 // help`, which can be expected to change regularly, bake in 28 // some checkpoints. Key things we are looking for: 29 // 30 // - The top-level description 31 // - Each of the main headings 32 // - Some builtin commands under the main headings 33 // - The `helloworld` plugin in the appropriate place 34 // - The `badmeta` plugin under the "Invalid Plugins" heading. 35 // 36 // Regexps are needed because the width depends on `unix.TIOCGWINSZ` or similar. 37 helloworldre := regexp.MustCompile(`^ helloworld\*\s+A basic Hello World plugin for tests \(Docker Inc\., testing\)$`) 38 badmetare := regexp.MustCompile(`^ badmeta\s+invalid metadata: invalid character 'i' looking for beginning of object key string$`) 39 var helloworldcount, badmetacount int 40 for _, expected := range []*regexp.Regexp{ 41 regexp.MustCompile(`^A self-sufficient runtime for containers$`), 42 regexp.MustCompile(`^Management Commands:$`), 43 regexp.MustCompile(`^ container\s+Manage containers$`), 44 helloworldre, 45 regexp.MustCompile(`^ image\s+Manage images$`), 46 regexp.MustCompile(`^Commands:$`), 47 regexp.MustCompile(`^ create\s+Create a new container$`), 48 regexp.MustCompile(`^Invalid Plugins:$`), 49 badmetare, 50 nil, // scan to end of input rather than stopping at badmetare 51 } { 52 var found bool 53 for scanner.Scan() { 54 text := scanner.Text() 55 if helloworldre.MatchString(text) { 56 helloworldcount++ 57 } 58 if badmetare.MatchString(text) { 59 badmetacount++ 60 } 61 62 if expected != nil && expected.MatchString(text) { 63 found = true 64 break 65 } 66 } 67 assert.Assert(t, expected == nil || found, "Did not find match for %q in `docker help` output", expected) 68 } 69 // We successfully scanned all the input 70 assert.Assert(t, !scanner.Scan()) 71 assert.NilError(t, scanner.Err()) 72 // Plugins should only be listed once. 73 assert.Assert(t, is.Equal(helloworldcount, 1)) 74 assert.Assert(t, is.Equal(badmetacount, 1)) 75 76 // Running with `--help` should produce the same. 77 t.Run("help_flag", func(t *testing.T) { 78 res2 := icmd.RunCmd(run("--help")) 79 res2.Assert(t, icmd.Expected{ 80 ExitCode: 0, 81 }) 82 assert.Assert(t, is.Equal(res2.Stdout(), res.Stdout())) 83 assert.Assert(t, is.Equal(res2.Stderr(), "")) 84 }) 85 86 // Running just `docker` (without `help` nor `--help`) should produce the same thing, except on Stderr. 87 t.Run("bare", func(t *testing.T) { 88 res2 := icmd.RunCmd(run()) 89 res2.Assert(t, icmd.Expected{ 90 ExitCode: 0, 91 }) 92 assert.Assert(t, is.Equal(res2.Stdout(), "")) 93 assert.Assert(t, is.Equal(res2.Stderr(), res.Stdout())) 94 }) 95 96 t.Run("badopt", func(t *testing.T) { 97 // Running `docker --badopt` should also produce the 98 // same thing, give or take the leading error message 99 // and a trailing carriage return (due to main() using 100 // Println in the error case). 101 res2 := icmd.RunCmd(run("--badopt")) 102 res2.Assert(t, icmd.Expected{ 103 ExitCode: 125, 104 }) 105 assert.Assert(t, is.Equal(res2.Stdout(), "")) 106 exp := "unknown flag: --badopt\nSee 'docker --help'.\n" + res.Stdout() + "\n" 107 assert.Assert(t, is.Equal(res2.Stderr(), exp)) 108 }) 109 }