|
@@ -1,15 +1,82 @@
|
|
package daemon
|
|
package daemon
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
+ "io/ioutil"
|
|
|
|
+ "os"
|
|
|
|
+ "path/filepath"
|
|
|
|
+ "strings"
|
|
"testing"
|
|
"testing"
|
|
|
|
|
|
"github.com/docker/docker/api/types"
|
|
"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/api/types/filters"
|
|
"github.com/docker/docker/container"
|
|
"github.com/docker/docker/container"
|
|
|
|
+ "github.com/docker/docker/image"
|
|
|
|
+ "github.com/opencontainers/go-digest"
|
|
|
|
+ "github.com/pborman/uuid"
|
|
"gotest.tools/assert"
|
|
"gotest.tools/assert"
|
|
is "gotest.tools/assert/cmp"
|
|
is "gotest.tools/assert/cmp"
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+var root string
|
|
|
|
+
|
|
|
|
+func TestMain(m *testing.M) {
|
|
|
|
+ var err error
|
|
|
|
+ root, err = ioutil.TempDir("", "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 {
|
|
|
|
+ var (
|
|
|
|
+ id = uuid.New()
|
|
|
|
+ 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
|
|
|
|
+ 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 _, container := range containers {
|
|
|
|
+ for _, containerName := range container.Names {
|
|
|
|
+ if strings.TrimPrefix(containerName, "/") == name {
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false
|
|
|
|
+}
|
|
|
|
+
|
|
func TestListInvalidFilter(t *testing.T) {
|
|
func TestListInvalidFilter(t *testing.T) {
|
|
db, err := container.NewViewDB()
|
|
db, err := container.NewViewDB()
|
|
assert.Assert(t, err == nil)
|
|
assert.Assert(t, err == nil)
|
|
@@ -24,3 +91,35 @@ func TestListInvalidFilter(t *testing.T) {
|
|
})
|
|
})
|
|
assert.Assert(t, is.Error(err, "Invalid filter 'invalid'"))
|
|
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.Assert(t, err == nil)
|
|
|
|
+ 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 make sure it works for exact names
|
|
|
|
+ containerList, err = d.Containers(&types.ContainerListOptions{
|
|
|
|
+ Filters: filters.NewArgs(filters.Arg("name", "b1")),
|
|
|
|
+ })
|
|
|
|
+ assert.Assert(t, err == nil)
|
|
|
|
+ assert.Assert(t, is.Len(containerList, 1))
|
|
|
|
+ assert.Assert(t, containerListContainsName(containerList, three.Name))
|
|
|
|
+}
|