github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/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 = 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 = image.IDFromDigest(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 f := filters.NewArgs(filters.Arg("invalid", "foo")) 91 92 _, err = d.Containers(context.Background(), &types.ContainerListOptions{ 93 Filters: f, 94 }) 95 assert.Assert(t, is.Error(err, "invalid filter 'invalid'")) 96 } 97 98 func TestNameFilter(t *testing.T) { 99 db, err := container.NewViewDB() 100 assert.Assert(t, err == nil) 101 d := &Daemon{ 102 containersReplica: db, 103 } 104 105 var ( 106 one = setupContainerWithName(t, "a1", d) 107 two = setupContainerWithName(t, "a2", d) 108 three = setupContainerWithName(t, "b1", d) 109 ) 110 111 // moby/moby #37453 - ^ regex not working due to prefix slash 112 // not being stripped 113 containerList, err := d.Containers(context.Background(), &types.ContainerListOptions{ 114 Filters: filters.NewArgs(filters.Arg("name", "^a")), 115 }) 116 assert.NilError(t, err) 117 assert.Assert(t, is.Len(containerList, 2)) 118 assert.Assert(t, containerListContainsName(containerList, one.Name)) 119 assert.Assert(t, containerListContainsName(containerList, two.Name)) 120 121 // Same as above but with slash prefix should produce the same result 122 containerListWithPrefix, err := d.Containers(context.Background(), &types.ContainerListOptions{ 123 Filters: filters.NewArgs(filters.Arg("name", "^/a")), 124 }) 125 assert.NilError(t, err) 126 assert.Assert(t, is.Len(containerListWithPrefix, 2)) 127 assert.Assert(t, containerListContainsName(containerListWithPrefix, one.Name)) 128 assert.Assert(t, containerListContainsName(containerListWithPrefix, two.Name)) 129 130 // Same as above but make sure it works for exact names 131 containerList, err = d.Containers(context.Background(), &types.ContainerListOptions{ 132 Filters: filters.NewArgs(filters.Arg("name", "b1")), 133 }) 134 assert.NilError(t, err) 135 assert.Assert(t, is.Len(containerList, 1)) 136 assert.Assert(t, containerListContainsName(containerList, three.Name)) 137 138 // Same as above but with slash prefix should produce the same result 139 containerListWithPrefix, err = d.Containers(context.Background(), &types.ContainerListOptions{ 140 Filters: filters.NewArgs(filters.Arg("name", "/b1")), 141 }) 142 assert.NilError(t, err) 143 assert.Assert(t, is.Len(containerListWithPrefix, 1)) 144 assert.Assert(t, containerListContainsName(containerListWithPrefix, three.Name)) 145 }