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