integration-cli/docker_cli_volume_test.go
b3b7eb27
 package main
 
 import (
 	"os/exec"
 	"strings"
 
51090717
 	"github.com/docker/docker/pkg/integration/checker"
b3b7eb27
 	"github.com/go-check/check"
 )
 
 func (s *DockerSuite) TestVolumeCliCreate(c *check.C) {
 	dockerCmd(c, "volume", "create")
 
 	_, err := runCommand(exec.Command(dockerBinary, "volume", "create", "-d", "nosuchdriver"))
 	c.Assert(err, check.Not(check.IsNil))
 
 	out, _ := dockerCmd(c, "volume", "create", "--name=test")
 	name := strings.TrimSpace(out)
 	c.Assert(name, check.Equals, "test")
 }
 
0ff3123e
 func (s *DockerSuite) TestVolumeCliCreateOptionConflict(c *check.C) {
 	dockerCmd(c, "volume", "create", "--name=test")
 	out, _, err := dockerCmdWithError("volume", "create", "--name", "test", "--driver", "nosuchdriver")
 	c.Assert(err, check.NotNil, check.Commentf("volume create exception name already in use with another driver"))
d3eca445
 	c.Assert(out, checker.Contains, "A volume named test already exists")
0ff3123e
 
667dcb0e
 	out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Driver }}", "test")
0ff3123e
 	_, _, err = dockerCmdWithError("volume", "create", "--name", "test", "--driver", strings.TrimSpace(out))
 	c.Assert(err, check.IsNil)
 }
 
b3b7eb27
 func (s *DockerSuite) TestVolumeCliInspect(c *check.C) {
 	c.Assert(
 		exec.Command(dockerBinary, "volume", "inspect", "doesntexist").Run(),
 		check.Not(check.IsNil),
899caaca
 		check.Commentf("volume inspect should error on non-existent volume"),
b3b7eb27
 	)
 
 	out, _ := dockerCmd(c, "volume", "create")
 	name := strings.TrimSpace(out)
667dcb0e
 	out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Name }}", name)
b3b7eb27
 	c.Assert(strings.TrimSpace(out), check.Equals, name)
 
 	dockerCmd(c, "volume", "create", "--name", "test")
667dcb0e
 	out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Name }}", "test")
b3b7eb27
 	c.Assert(strings.TrimSpace(out), check.Equals, "test")
 }
 
62953450
 func (s *DockerSuite) TestVolumeCliInspectMulti(c *check.C) {
 	dockerCmd(c, "volume", "create", "--name", "test1")
 	dockerCmd(c, "volume", "create", "--name", "test2")
57b67963
 	dockerCmd(c, "volume", "create", "--name", "not-shown")
62953450
 
57b67963
 	out, _, err := dockerCmdWithError("volume", "inspect", "--format='{{ .Name }}'", "test1", "test2", "doesntexist", "not-shown")
d125ddae
 	c.Assert(err, checker.NotNil)
62953450
 	outArr := strings.Split(strings.TrimSpace(out), "\n")
 	c.Assert(len(outArr), check.Equals, 3, check.Commentf("\n%s", out))
 
57b67963
 	c.Assert(out, checker.Contains, "test1")
 	c.Assert(out, checker.Contains, "test2")
 	c.Assert(out, checker.Contains, "Error: No such volume: doesntexist")
 	c.Assert(out, checker.Not(checker.Contains), "not-shown")
62953450
 }
 
b3b7eb27
 func (s *DockerSuite) TestVolumeCliLs(c *check.C) {
382c96ee
 	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
60ffd6c8
 	out, _ := dockerCmd(c, "volume", "create", "--name", "aaa")
b3b7eb27
 
 	dockerCmd(c, "volume", "create", "--name", "test")
60ffd6c8
 
 	dockerCmd(c, "volume", "create", "--name", "soo")
 	dockerCmd(c, "run", "-v", "soo:"+prefix+"/foo", "busybox", "ls", "/")
b3b7eb27
 
 	out, _ = dockerCmd(c, "volume", "ls")
 	outArr := strings.Split(strings.TrimSpace(out), "\n")
 	c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
 
60ffd6c8
 	assertVolList(c, out, []string{"aaa", "soo", "test"})
 }
 
 // assertVolList checks volume retrieved with ls command
 // equals to expected volume list
 // note: out should be `volume ls [option]` result
 func assertVolList(c *check.C, out string, expectVols []string) {
 	lines := strings.Split(out, "\n")
 	var volList []string
 	for _, line := range lines[1 : len(lines)-1] {
 		volFields := strings.Fields(line)
 		// wrap all volume name in volList
 		volList = append(volList, volFields[1])
 	}
 
 	// volume ls should contains all expected volumes
 	c.Assert(volList, checker.DeepEquals, expectVols)
b3b7eb27
 }
 
1cbf9047
 func (s *DockerSuite) TestVolumeCliLsFilterDangling(c *check.C) {
382c96ee
 	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
1cbf9047
 	dockerCmd(c, "volume", "create", "--name", "testnotinuse1")
 	dockerCmd(c, "volume", "create", "--name", "testisinuse1")
 	dockerCmd(c, "volume", "create", "--name", "testisinuse2")
 
 	// Make sure both "created" (but not started), and started
 	// containers are included in reference counting
2af5034c
 	dockerCmd(c, "run", "--name", "volume-test1", "-v", "testisinuse1:"+prefix+"/foo", "busybox", "true")
 	dockerCmd(c, "create", "--name", "volume-test2", "-v", "testisinuse2:"+prefix+"/foo", "busybox", "true")
1cbf9047
 
 	out, _ := dockerCmd(c, "volume", "ls")
 
 	// No filter, all volumes should show
 	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
 	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
 	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
 
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=false")
 
1431b623
 	// Explicitly disabling dangling
 	c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
1cbf9047
 	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
 	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
 
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=true")
 
927b334e
 	// Filter "dangling" volumes; only "dangling" (unused) volumes should be in the output
1cbf9047
 	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
 	c.Assert(out, check.Not(checker.Contains), "testisinuse1\n", check.Commentf("volume 'testisinuse1' in output, but not expected"))
 	c.Assert(out, check.Not(checker.Contains), "testisinuse2\n", check.Commentf("volume 'testisinuse2' in output, but not expected"))
66c253cb
 
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=1")
 	// Filter "dangling" volumes; only "dangling" (unused) volumes should be in the output, dangling also accept 1
 	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
 	c.Assert(out, check.Not(checker.Contains), "testisinuse1\n", check.Commentf("volume 'testisinuse1' in output, but not expected"))
 	c.Assert(out, check.Not(checker.Contains), "testisinuse2\n", check.Commentf("volume 'testisinuse2' in output, but not expected"))
 
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=0")
 	// dangling=0 is same as dangling=false case
1431b623
 	c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
66c253cb
 	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
 	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
8e9305ef
 
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "name=testisin")
 	c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
 	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("execpeted volume 'testisinuse1' in output"))
 	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
 
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=invalidDriver")
 	outArr := strings.Split(strings.TrimSpace(out), "\n")
 	c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
 
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=local")
 	outArr = strings.Split(strings.TrimSpace(out), "\n")
 	c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
 
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=loc")
 	outArr = strings.Split(strings.TrimSpace(out), "\n")
 	c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
 
66c253cb
 }
 
 func (s *DockerSuite) TestVolumeCliLsErrorWithInvalidFilterName(c *check.C) {
 	out, _, err := dockerCmdWithError("volume", "ls", "-f", "FOO=123")
 	c.Assert(err, checker.NotNil)
 	c.Assert(out, checker.Contains, "Invalid filter")
 }
 
 func (s *DockerSuite) TestVolumeCliLsWithIncorrectFilterValue(c *check.C) {
 	out, _, err := dockerCmdWithError("volume", "ls", "-f", "dangling=invalid")
 	c.Assert(err, check.NotNil)
 	c.Assert(out, checker.Contains, "Invalid filter")
1cbf9047
 }
 
b3b7eb27
 func (s *DockerSuite) TestVolumeCliRm(c *check.C) {
382c96ee
 	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
b3b7eb27
 	out, _ := dockerCmd(c, "volume", "create")
 	id := strings.TrimSpace(out)
 
 	dockerCmd(c, "volume", "create", "--name", "test")
 	dockerCmd(c, "volume", "rm", id)
 	dockerCmd(c, "volume", "rm", "test")
 
 	out, _ = dockerCmd(c, "volume", "ls")
 	outArr := strings.Split(strings.TrimSpace(out), "\n")
 	c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
 
 	volumeID := "testing"
2af5034c
 	dockerCmd(c, "run", "-v", volumeID+":"+prefix+"/foo", "--name=test", "busybox", "sh", "-c", "echo hello > /foo/bar")
b3b7eb27
 	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "volume", "rm", "testing"))
 	c.Assert(
 		err,
 		check.Not(check.IsNil),
 		check.Commentf("Should not be able to remove volume that is in use by a container\n%s", out))
 
 	out, _ = dockerCmd(c, "run", "--volumes-from=test", "--name=test2", "busybox", "sh", "-c", "cat /foo/bar")
 	c.Assert(strings.TrimSpace(out), check.Equals, "hello")
 	dockerCmd(c, "rm", "-fv", "test2")
 	dockerCmd(c, "volume", "inspect", volumeID)
 	dockerCmd(c, "rm", "-f", "test")
 
2af5034c
 	out, _ = dockerCmd(c, "run", "--name=test2", "-v", volumeID+":"+prefix+"/foo", "busybox", "sh", "-c", "cat /foo/bar")
b3b7eb27
 	c.Assert(strings.TrimSpace(out), check.Equals, "hello", check.Commentf("volume data was removed"))
 	dockerCmd(c, "rm", "test2")
 
 	dockerCmd(c, "volume", "rm", volumeID)
 	c.Assert(
 		exec.Command("volume", "rm", "doesntexist").Run(),
 		check.Not(check.IsNil),
899caaca
 		check.Commentf("volume rm should fail with non-existent volume"),
b3b7eb27
 	)
 }
38da4318
 
 func (s *DockerSuite) TestVolumeCliNoArgs(c *check.C) {
 	out, _ := dockerCmd(c, "volume")
2feebd95
 	// no args should produce the cmd usage output
667dcb0e
 	usage := "Usage:	docker volume COMMAND"
2feebd95
 	c.Assert(out, checker.Contains, usage)
38da4318
 
 	// invalid arg should error and show the command usage on stderr
 	_, stderr, _, err := runCommandWithStdoutStderr(exec.Command(dockerBinary, "volume", "somearg"))
2feebd95
 	c.Assert(err, check.NotNil, check.Commentf(stderr))
 	c.Assert(stderr, checker.Contains, usage)
 
 	// invalid flag should error and show the flag error and cmd usage
 	_, stderr, _, err = runCommandWithStdoutStderr(exec.Command(dockerBinary, "volume", "--no-such-flag"))
 	c.Assert(err, check.NotNil, check.Commentf(stderr))
 	c.Assert(stderr, checker.Contains, usage)
667dcb0e
 	c.Assert(stderr, checker.Contains, "unknown flag: --no-such-flag")
38da4318
 }
b9d30280
 
 func (s *DockerSuite) TestVolumeCliInspectTmplError(c *check.C) {
 	out, _ := dockerCmd(c, "volume", "create")
 	name := strings.TrimSpace(out)
 
 	out, exitCode, err := dockerCmdWithError("volume", "inspect", "--format='{{ .FooBar }}'", name)
 	c.Assert(err, checker.NotNil, check.Commentf("Output: %s", out))
 	c.Assert(exitCode, checker.Equals, 1, check.Commentf("Output: %s", out))
 	c.Assert(out, checker.Contains, "Template parsing error")
 }
b05b2370
 
 func (s *DockerSuite) TestVolumeCliCreateWithOpts(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 
 	dockerCmd(c, "volume", "create", "-d", "local", "--name", "test", "--opt=type=tmpfs", "--opt=device=tmpfs", "--opt=o=size=1m,uid=1000")
 	out, _ := dockerCmd(c, "run", "-v", "test:/foo", "busybox", "mount")
 
 	mounts := strings.Split(out, "\n")
 	var found bool
 	for _, m := range mounts {
 		if strings.Contains(m, "/foo") {
 			found = true
 			info := strings.Fields(m)
 			// tmpfs on <path> type tmpfs (rw,relatime,size=1024k,uid=1000)
 			c.Assert(info[0], checker.Equals, "tmpfs")
 			c.Assert(info[2], checker.Equals, "/foo")
 			c.Assert(info[4], checker.Equals, "tmpfs")
 			c.Assert(info[5], checker.Contains, "uid=1000")
 			c.Assert(info[5], checker.Contains, "size=1024k")
 		}
 	}
 	c.Assert(found, checker.Equals, true)
 }
fc214b44
 
 func (s *DockerSuite) TestVolumeCliCreateLabel(c *check.C) {
 	testVol := "testvolcreatelabel"
 	testLabel := "foo"
 	testValue := "bar"
 
 	out, _, err := dockerCmdWithError("volume", "create", "--label", testLabel+"="+testValue, "--name", testVol)
 	c.Assert(err, check.IsNil)
 
667dcb0e
 	out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Labels."+testLabel+" }}", testVol)
fc214b44
 	c.Assert(strings.TrimSpace(out), check.Equals, testValue)
 }
 
 func (s *DockerSuite) TestVolumeCliCreateLabelMultiple(c *check.C) {
 	testVol := "testvolcreatelabel"
 
 	testLabels := map[string]string{
 		"foo": "bar",
 		"baz": "foo",
 	}
 
 	args := []string{
 		"volume",
 		"create",
 		"--name",
 		testVol,
 	}
 
 	for k, v := range testLabels {
 		args = append(args, "--label", k+"="+v)
 	}
 
 	out, _, err := dockerCmdWithError(args...)
 	c.Assert(err, check.IsNil)
 
 	for k, v := range testLabels {
667dcb0e
 		out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Labels."+k+" }}", testVol)
fc214b44
 		c.Assert(strings.TrimSpace(out), check.Equals, v)
 	}
 }