github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/daemon/list_test.go (about) 1 package daemon 2 3 import ( 4 "os" 5 "path/filepath" 6 "testing" 7 8 "github.com/docker/docker/api/types" 9 containertypes "github.com/docker/docker/api/types/container" 10 "github.com/docker/docker/api/types/filters" 11 "github.com/docker/docker/container" 12 "github.com/docker/docker/image" 13 "github.com/google/uuid" 14 "github.com/opencontainers/go-digest" 15 "gotest.tools/v3/assert" 16 is "gotest.tools/v3/assert/cmp" 17 ) 18 19 var root string 20 21 func TestMain(m *testing.M) { 22 var err error 23 root, err = os.MkdirTemp("", "docker-container-test-") 24 if err != nil { 25 panic(err) 26 } 27 defer os.RemoveAll(root) 28 29 os.Exit(m.Run()) 30 } 31 32 // This sets up a container with a name so that name filters 33 // work against it. It takes in a pointer to Daemon so that 34 // minor operations are not repeated by the caller 35 func setupContainerWithName(t *testing.T, name string, daemon *Daemon) *container.Container { 36 t.Helper() 37 var ( 38 id = uuid.New().String() 39 computedImageID = digest.FromString(id) 40 cRoot = filepath.Join(root, id) 41 ) 42 if err := os.MkdirAll(cRoot, 0755); err != nil { 43 t.Fatal(err) 44 } 45 46 c := container.NewBaseContainer(id, cRoot) 47 // these are for passing includeContainerInList 48 if name[0] != '/' { 49 name = "/" + name 50 } 51 c.Name = name 52 c.Running = true 53 c.HostConfig = &containertypes.HostConfig{} 54 55 // these are for passing the refreshImage reducer 56 c.ImageID = image.IDFromDigest(computedImageID) 57 c.Config = &containertypes.Config{ 58 Image: computedImageID.String(), 59 } 60 61 // this is done here to avoid requiring these 62 // operations n x number of containers in the 63 // calling function 64 daemon.containersReplica.Save(c) 65 daemon.reserveName(id, name) 66 67 return c 68 } 69 70 func containerListContainsName(containers []*types.Container, name string) bool { 71 for _, ctr := range containers { 72 for _, containerName := range ctr.Names { 73 if containerName == name { 74 return true 75 } 76 } 77 } 78 79 return false 80 } 81 82 func TestListInvalidFilter(t *testing.T) { 83 db, err := container.NewViewDB() 84 assert.Assert(t, err == nil) 85 d := &Daemon{ 86 containersReplica: db, 87 } 88 89 f := filters.NewArgs(filters.Arg("invalid", "foo")) 90 91 _, err = d.Containers(&types.ContainerListOptions{ 92 Filters: f, 93 }) 94 assert.Assert(t, is.Error(err, "invalid filter 'invalid'")) 95 } 96 97 func TestNameFilter(t *testing.T) { 98 db, err := container.NewViewDB() 99 assert.Assert(t, err == nil) 100 d := &Daemon{ 101 containersReplica: db, 102 } 103 104 var ( 105 one = setupContainerWithName(t, "a1", d) 106 two = setupContainerWithName(t, "a2", d) 107 three = setupContainerWithName(t, "b1", d) 108 ) 109 110 // moby/moby #37453 - ^ regex not working due to prefix slash 111 // not being stripped 112 containerList, err := d.Containers(&types.ContainerListOptions{ 113 Filters: filters.NewArgs(filters.Arg("name", "^a")), 114 }) 115 assert.NilError(t, err) 116 assert.Assert(t, is.Len(containerList, 2)) 117 assert.Assert(t, containerListContainsName(containerList, one.Name)) 118 assert.Assert(t, containerListContainsName(containerList, two.Name)) 119 120 // Same as above but with slash prefix should produce the same result 121 containerListWithPrefix, err := d.Containers(&types.ContainerListOptions{ 122 Filters: filters.NewArgs(filters.Arg("name", "^/a")), 123 }) 124 assert.NilError(t, err) 125 assert.Assert(t, is.Len(containerListWithPrefix, 2)) 126 assert.Assert(t, containerListContainsName(containerListWithPrefix, one.Name)) 127 assert.Assert(t, containerListContainsName(containerListWithPrefix, two.Name)) 128 129 // Same as above but make sure it works for exact names 130 containerList, err = d.Containers(&types.ContainerListOptions{ 131 Filters: filters.NewArgs(filters.Arg("name", "b1")), 132 }) 133 assert.NilError(t, err) 134 assert.Assert(t, is.Len(containerList, 1)) 135 assert.Assert(t, containerListContainsName(containerList, three.Name)) 136 137 // Same as above but with slash prefix should produce the same result 138 containerListWithPrefix, err = d.Containers(&types.ContainerListOptions{ 139 Filters: filters.NewArgs(filters.Arg("name", "/b1")), 140 }) 141 assert.NilError(t, err) 142 assert.Assert(t, is.Len(containerListWithPrefix, 1)) 143 assert.Assert(t, containerListContainsName(containerListWithPrefix, three.Name)) 144 }