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