1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/daemon/cluster/executor/container/validate_test.go
Stephen J Day 92899ffac8
cluster/executor: check mounts at start
While it is important to not create controllers for an invalid task,
certain properties should only be checked immediately before use. Early
host validation of mounts prevents resolution of the task Executor when
the mounts are not relevant to execution flow. In this case, we have a
check for the existence of a bind mount path in a creation function that
prevents a task controller from being resolved. Such early validation
prevents one from interacting directly with a controller and result in
unnecessary error reporting.

In accordance with the above, we move the validation of the existence of
host bind mount paths to the `Controller.Start` phase. We also call
these "checks", as they are valid mounts but reference non-existent
paths.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
2017-02-06 13:09:53 -08:00

141 lines
3.6 KiB
Go

package container
import (
"io/ioutil"
"os"
"strings"
"testing"
"github.com/docker/docker/daemon"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/swarmkit/api"
)
func newTestControllerWithMount(m api.Mount) (*controller, error) {
return newController(&daemon.Daemon{}, &api.Task{
ID: stringid.GenerateRandomID(),
ServiceID: stringid.GenerateRandomID(),
Spec: api.TaskSpec{
Runtime: &api.TaskSpec_Container{
Container: &api.ContainerSpec{
Image: "image_name",
Labels: map[string]string{
"com.docker.swarm.task.id": "id",
},
Mounts: []api.Mount{m},
},
},
},
}, nil)
}
func TestControllerValidateMountBind(t *testing.T) {
// with improper source
if _, err := newTestControllerWithMount(api.Mount{
Type: api.MountTypeBind,
Source: "foo",
Target: testAbsPath,
}); err == nil || !strings.Contains(err.Error(), "invalid bind mount source") {
t.Fatalf("expected error, got: %v", err)
}
// with non-existing source
if _, err := newTestControllerWithMount(api.Mount{
Type: api.MountTypeBind,
Source: testAbsNonExistent,
Target: testAbsPath,
}); err != nil {
t.Fatalf("controller should not error at creation: %v", err)
}
// with proper source
tmpdir, err := ioutil.TempDir("", "TestControllerValidateMountBind")
if err != nil {
t.Fatalf("failed to create temp dir: %v", err)
}
defer os.Remove(tmpdir)
if _, err := newTestControllerWithMount(api.Mount{
Type: api.MountTypeBind,
Source: tmpdir,
Target: testAbsPath,
}); err != nil {
t.Fatalf("expected error, got: %v", err)
}
}
func TestControllerValidateMountVolume(t *testing.T) {
// with improper source
if _, err := newTestControllerWithMount(api.Mount{
Type: api.MountTypeVolume,
Source: testAbsPath,
Target: testAbsPath,
}); err == nil || !strings.Contains(err.Error(), "invalid volume mount source") {
t.Fatalf("expected error, got: %v", err)
}
// with proper source
if _, err := newTestControllerWithMount(api.Mount{
Type: api.MountTypeVolume,
Source: "foo",
Target: testAbsPath,
}); err != nil {
t.Fatalf("expected error, got: %v", err)
}
}
func TestControllerValidateMountTarget(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "TestControllerValidateMountTarget")
if err != nil {
t.Fatalf("failed to create temp dir: %v", err)
}
defer os.Remove(tmpdir)
// with improper target
if _, err := newTestControllerWithMount(api.Mount{
Type: api.MountTypeBind,
Source: testAbsPath,
Target: "foo",
}); err == nil || !strings.Contains(err.Error(), "invalid mount target") {
t.Fatalf("expected error, got: %v", err)
}
// with proper target
if _, err := newTestControllerWithMount(api.Mount{
Type: api.MountTypeBind,
Source: tmpdir,
Target: testAbsPath,
}); err != nil {
t.Fatalf("expected no error, got: %v", err)
}
}
func TestControllerValidateMountTmpfs(t *testing.T) {
// with improper target
if _, err := newTestControllerWithMount(api.Mount{
Type: api.MountTypeTmpfs,
Source: "foo",
Target: testAbsPath,
}); err == nil || !strings.Contains(err.Error(), "invalid tmpfs source") {
t.Fatalf("expected error, got: %v", err)
}
// with proper target
if _, err := newTestControllerWithMount(api.Mount{
Type: api.MountTypeTmpfs,
Target: testAbsPath,
}); err != nil {
t.Fatalf("expected no error, got: %v", err)
}
}
func TestControllerValidateMountInvalidType(t *testing.T) {
// with improper target
if _, err := newTestControllerWithMount(api.Mount{
Type: api.Mount_MountType(9999),
Source: "foo",
Target: testAbsPath,
}); err == nil || !strings.Contains(err.Error(), "invalid mount type") {
t.Fatalf("expected error, got: %v", err)
}
}