github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli-plugins/manager/candidate_test.go (about) 1 package manager 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 "testing" 8 9 "github.com/spf13/cobra" 10 "gotest.tools/v3/assert" 11 "gotest.tools/v3/assert/cmp" 12 ) 13 14 type fakeCandidate struct { 15 path string 16 exec bool 17 meta string 18 } 19 20 func (c *fakeCandidate) Path() string { 21 return c.path 22 } 23 24 func (c *fakeCandidate) Metadata() ([]byte, error) { 25 if !c.exec { 26 return nil, fmt.Errorf("faked a failure to exec %q", c.path) 27 } 28 return []byte(c.meta), nil 29 } 30 31 func TestValidateCandidate(t *testing.T) { 32 const ( 33 goodPluginName = NamePrefix + "goodplugin" 34 35 builtinName = NamePrefix + "builtin" 36 builtinAlias = NamePrefix + "alias" 37 38 badPrefixPath = "/usr/local/libexec/cli-plugins/wobble" 39 badNamePath = "/usr/local/libexec/cli-plugins/docker-123456" 40 goodPluginPath = "/usr/local/libexec/cli-plugins/" + goodPluginName 41 metaExperimental = `{"SchemaVersion": "0.1.0", "Vendor": "e2e-testing", "Experimental": true}` 42 ) 43 44 fakeroot := &cobra.Command{Use: "docker"} 45 fakeroot.AddCommand(&cobra.Command{ 46 Use: strings.TrimPrefix(builtinName, NamePrefix), 47 Aliases: []string{ 48 strings.TrimPrefix(builtinAlias, NamePrefix), 49 }, 50 }) 51 52 for _, tc := range []struct { 53 name string 54 c *fakeCandidate 55 56 // Either err or invalid may be non-empty, but not both (both can be empty for a good plugin). 57 err string 58 invalid string 59 }{ 60 /* Each failing one of the tests */ 61 {name: "empty path", c: &fakeCandidate{path: ""}, err: "plugin candidate path cannot be empty"}, 62 {name: "bad prefix", c: &fakeCandidate{path: badPrefixPath}, err: fmt.Sprintf("does not have %q prefix", NamePrefix)}, 63 {name: "bad path", c: &fakeCandidate{path: badNamePath}, invalid: "did not match"}, 64 {name: "builtin command", c: &fakeCandidate{path: builtinName}, invalid: `plugin "builtin" duplicates builtin command`}, 65 {name: "builtin alias", c: &fakeCandidate{path: builtinAlias}, invalid: `plugin "alias" duplicates an alias of builtin command "builtin"`}, 66 {name: "fetch failure", c: &fakeCandidate{path: goodPluginPath, exec: false}, invalid: fmt.Sprintf("failed to fetch metadata: faked a failure to exec %q", goodPluginPath)}, 67 {name: "metadata not json", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `xyzzy`}, invalid: "invalid character"}, 68 {name: "empty schemaversion", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{}`}, invalid: `plugin SchemaVersion "" is not valid`}, 69 {name: "invalid schemaversion", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "xyzzy"}`}, invalid: `plugin SchemaVersion "xyzzy" is not valid`}, 70 {name: "no vendor", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0"}`}, invalid: "plugin metadata does not define a vendor"}, 71 {name: "empty vendor", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": ""}`}, invalid: "plugin metadata does not define a vendor"}, 72 // This one should work 73 {name: "valid", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": "e2e-testing"}`}}, 74 {name: "experimental + allowing experimental", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: metaExperimental}}, 75 } { 76 t.Run(tc.name, func(t *testing.T) { 77 p, err := newPlugin(tc.c, fakeroot) 78 if tc.err != "" { 79 assert.ErrorContains(t, err, tc.err) 80 } else if tc.invalid != "" { 81 assert.NilError(t, err) 82 assert.Assert(t, cmp.ErrorType(p.Err, reflect.TypeOf(&pluginError{}))) 83 assert.ErrorContains(t, p.Err, tc.invalid) 84 } else { 85 assert.NilError(t, err) 86 assert.Equal(t, NamePrefix+p.Name, goodPluginName) 87 assert.Equal(t, p.SchemaVersion, "0.1.0") 88 assert.Equal(t, p.Vendor, "e2e-testing") 89 } 90 }) 91 } 92 } 93 94 func TestCandidatePath(t *testing.T) { 95 exp := "/some/path" 96 cand := &candidate{path: exp} 97 assert.Equal(t, exp, cand.Path()) 98 }