github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/cli/cli-plugins/manager/manager_test.go (about)

     1  package manager
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/docker/cli/cli/config"
     8  	"github.com/docker/cli/cli/config/configfile"
     9  	"github.com/docker/cli/internal/test"
    10  	"github.com/spf13/cobra"
    11  	"gotest.tools/v3/assert"
    12  	"gotest.tools/v3/fs"
    13  )
    14  
    15  func TestListPluginCandidates(t *testing.T) {
    16  	// Populate a selection of directories with various shadowed and bogus/obscure plugin candidates.
    17  	// For the purposes of this test no contents is required and permissions are irrelevant.
    18  	dir := fs.NewDir(t, t.Name(),
    19  		fs.WithDir(
    20  			"plugins1",
    21  			fs.WithFile("docker-plugin1", ""),                        // This appears in each directory
    22  			fs.WithFile("not-a-plugin", ""),                          // Should be ignored
    23  			fs.WithFile("docker-symlinked1", ""),                     // This and ...
    24  			fs.WithSymlink("docker-symlinked2", "docker-symlinked1"), // ... this should both appear
    25  			fs.WithDir("ignored1"),                                   // A directory should be ignored
    26  		),
    27  		fs.WithDir(
    28  			"plugins2",
    29  			fs.WithFile("docker-plugin1", ""),
    30  			fs.WithFile("also-not-a-plugin", ""),
    31  			fs.WithFile("docker-hardlink1", ""),                     // This and ...
    32  			fs.WithHardlink("docker-hardlink2", "docker-hardlink1"), // ... this should both appear
    33  			fs.WithDir("ignored2"),
    34  		),
    35  		fs.WithDir(
    36  			"plugins3-target", // Will be referenced as a symlink from below
    37  			fs.WithFile("docker-plugin1", ""),
    38  			fs.WithDir("ignored3"),
    39  			fs.WithSymlink("docker-brokensymlink", "broken"),           // A broken symlink is still a candidate (but would fail tests later)
    40  			fs.WithFile("non-plugin-symlinked", ""),                    // This shouldn't appear, but ...
    41  			fs.WithSymlink("docker-symlinked", "non-plugin-symlinked"), // ... this link to it should.
    42  		),
    43  		fs.WithSymlink("plugins3", "plugins3-target"),
    44  		fs.WithFile("/plugins4", ""),
    45  		fs.WithSymlink("plugins5", "plugins5-nonexistent-target"),
    46  	)
    47  	defer dir.Remove()
    48  
    49  	var dirs []string
    50  	for _, d := range []string{"plugins1", "nonexistent", "plugins2", "plugins3", "plugins4", "plugins5"} {
    51  		dirs = append(dirs, dir.Join(d))
    52  	}
    53  
    54  	candidates, err := listPluginCandidates(dirs)
    55  	assert.NilError(t, err)
    56  	exp := map[string][]string{
    57  		"plugin1": {
    58  			dir.Join("plugins1", "docker-plugin1"),
    59  			dir.Join("plugins2", "docker-plugin1"),
    60  			dir.Join("plugins3", "docker-plugin1"),
    61  		},
    62  		"symlinked1": {
    63  			dir.Join("plugins1", "docker-symlinked1"),
    64  		},
    65  		"symlinked2": {
    66  			dir.Join("plugins1", "docker-symlinked2"),
    67  		},
    68  		"hardlink1": {
    69  			dir.Join("plugins2", "docker-hardlink1"),
    70  		},
    71  		"hardlink2": {
    72  			dir.Join("plugins2", "docker-hardlink2"),
    73  		},
    74  		"brokensymlink": {
    75  			dir.Join("plugins3", "docker-brokensymlink"),
    76  		},
    77  		"symlinked": {
    78  			dir.Join("plugins3", "docker-symlinked"),
    79  		},
    80  	}
    81  
    82  	assert.DeepEqual(t, candidates, exp)
    83  }
    84  
    85  func TestListPluginsIsSorted(t *testing.T) {
    86  	dir := fs.NewDir(t, t.Name(),
    87  		fs.WithFile("docker-bbb", `
    88  #!/bin/sh
    89  echo '{"SchemaVersion":"0.1.0"}'`, fs.WithMode(0777)),
    90  		fs.WithFile("docker-aaa", `
    91  #!/bin/sh
    92  echo '{"SchemaVersion":"0.1.0"}'`, fs.WithMode(0777)),
    93  	)
    94  	defer dir.Remove()
    95  
    96  	cli := test.NewFakeCli(nil)
    97  	cli.SetConfigFile(&configfile.ConfigFile{CLIPluginsExtraDirs: []string{dir.Path()}})
    98  
    99  	plugins, err := ListPlugins(cli, &cobra.Command{})
   100  	assert.NilError(t, err)
   101  
   102  	// We're only interested in the plugins we created for testing this, and only
   103  	// if they appear in the expected order
   104  	var names []string
   105  	for _, p := range plugins {
   106  		if p.Name == "aaa" || p.Name == "bbb" {
   107  			names = append(names, p.Name)
   108  		}
   109  	}
   110  	assert.DeepEqual(t, names, []string{"aaa", "bbb"})
   111  }
   112  
   113  func TestErrPluginNotFound(t *testing.T) {
   114  	var err error = errPluginNotFound("test")
   115  	err.(errPluginNotFound).NotFound()
   116  	assert.Error(t, err, "Error: No such CLI plugin: test")
   117  	assert.Assert(t, IsNotFound(err))
   118  	assert.Assert(t, !IsNotFound(nil))
   119  }
   120  
   121  func TestGetPluginDirs(t *testing.T) {
   122  	cli := test.NewFakeCli(nil)
   123  
   124  	pluginDir, err := config.Path("cli-plugins")
   125  	assert.NilError(t, err)
   126  	expected := append([]string{pluginDir}, defaultSystemPluginDirs...)
   127  
   128  	var pluginDirs []string
   129  	pluginDirs, err = getPluginDirs(cli)
   130  	assert.Equal(t, strings.Join(expected, ":"), strings.Join(pluginDirs, ":"))
   131  	assert.NilError(t, err)
   132  
   133  	extras := []string{
   134  		"foo", "bar", "baz",
   135  	}
   136  	expected = append(extras, expected...)
   137  	cli.SetConfigFile(&configfile.ConfigFile{
   138  		CLIPluginsExtraDirs: extras,
   139  	})
   140  	pluginDirs, err = getPluginDirs(cli)
   141  	assert.DeepEqual(t, expected, pluginDirs)
   142  	assert.NilError(t, err)
   143  }