github.com/akerouanton/docker@v1.11.0-rc3/integration-cli/docker_cli_volume_test.go (about)

     1  package main
     2  
     3  import (
     4  	"os/exec"
     5  	"strings"
     6  
     7  	"github.com/docker/docker/pkg/integration/checker"
     8  	"github.com/go-check/check"
     9  )
    10  
    11  func (s *DockerSuite) TestVolumeCliCreate(c *check.C) {
    12  	dockerCmd(c, "volume", "create")
    13  
    14  	_, err := runCommand(exec.Command(dockerBinary, "volume", "create", "-d", "nosuchdriver"))
    15  	c.Assert(err, check.Not(check.IsNil))
    16  
    17  	out, _ := dockerCmd(c, "volume", "create", "--name=test")
    18  	name := strings.TrimSpace(out)
    19  	c.Assert(name, check.Equals, "test")
    20  }
    21  
    22  func (s *DockerSuite) TestVolumeCliCreateOptionConflict(c *check.C) {
    23  	dockerCmd(c, "volume", "create", "--name=test")
    24  	out, _, err := dockerCmdWithError("volume", "create", "--name", "test", "--driver", "nosuchdriver")
    25  	c.Assert(err, check.NotNil, check.Commentf("volume create exception name already in use with another driver"))
    26  	c.Assert(out, checker.Contains, "A volume named test already exists")
    27  
    28  	out, _ = dockerCmd(c, "volume", "inspect", "--format='{{ .Driver }}'", "test")
    29  	_, _, err = dockerCmdWithError("volume", "create", "--name", "test", "--driver", strings.TrimSpace(out))
    30  	c.Assert(err, check.IsNil)
    31  }
    32  
    33  func (s *DockerSuite) TestVolumeCliInspect(c *check.C) {
    34  	c.Assert(
    35  		exec.Command(dockerBinary, "volume", "inspect", "doesntexist").Run(),
    36  		check.Not(check.IsNil),
    37  		check.Commentf("volume inspect should error on non-existent volume"),
    38  	)
    39  
    40  	out, _ := dockerCmd(c, "volume", "create")
    41  	name := strings.TrimSpace(out)
    42  	out, _ = dockerCmd(c, "volume", "inspect", "--format='{{ .Name }}'", name)
    43  	c.Assert(strings.TrimSpace(out), check.Equals, name)
    44  
    45  	dockerCmd(c, "volume", "create", "--name", "test")
    46  	out, _ = dockerCmd(c, "volume", "inspect", "--format='{{ .Name }}'", "test")
    47  	c.Assert(strings.TrimSpace(out), check.Equals, "test")
    48  }
    49  
    50  func (s *DockerSuite) TestVolumeCliInspectMulti(c *check.C) {
    51  	dockerCmd(c, "volume", "create", "--name", "test1")
    52  	dockerCmd(c, "volume", "create", "--name", "test2")
    53  	dockerCmd(c, "volume", "create", "--name", "not-shown")
    54  
    55  	out, _, err := dockerCmdWithError("volume", "inspect", "--format='{{ .Name }}'", "test1", "test2", "doesntexist", "not-shown")
    56  	c.Assert(err, checker.NotNil)
    57  	outArr := strings.Split(strings.TrimSpace(out), "\n")
    58  	c.Assert(len(outArr), check.Equals, 3, check.Commentf("\n%s", out))
    59  
    60  	c.Assert(out, checker.Contains, "test1")
    61  	c.Assert(out, checker.Contains, "test2")
    62  	c.Assert(out, checker.Contains, "Error: No such volume: doesntexist")
    63  	c.Assert(out, checker.Not(checker.Contains), "not-shown")
    64  }
    65  
    66  func (s *DockerSuite) TestVolumeCliLs(c *check.C) {
    67  	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
    68  	out, _ := dockerCmd(c, "volume", "create", "--name", "aaa")
    69  
    70  	dockerCmd(c, "volume", "create", "--name", "test")
    71  
    72  	dockerCmd(c, "volume", "create", "--name", "soo")
    73  	dockerCmd(c, "run", "-v", "soo:"+prefix+"/foo", "busybox", "ls", "/")
    74  
    75  	out, _ = dockerCmd(c, "volume", "ls")
    76  	outArr := strings.Split(strings.TrimSpace(out), "\n")
    77  	c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
    78  
    79  	assertVolList(c, out, []string{"aaa", "soo", "test"})
    80  }
    81  
    82  // assertVolList checks volume retrieved with ls command
    83  // equals to expected volume list
    84  // note: out should be `volume ls [option]` result
    85  func assertVolList(c *check.C, out string, expectVols []string) {
    86  	lines := strings.Split(out, "\n")
    87  	var volList []string
    88  	for _, line := range lines[1 : len(lines)-1] {
    89  		volFields := strings.Fields(line)
    90  		// wrap all volume name in volList
    91  		volList = append(volList, volFields[1])
    92  	}
    93  
    94  	// volume ls should contains all expected volumes
    95  	c.Assert(volList, checker.DeepEquals, expectVols)
    96  }
    97  
    98  func (s *DockerSuite) TestVolumeCliLsFilterDangling(c *check.C) {
    99  	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
   100  	dockerCmd(c, "volume", "create", "--name", "testnotinuse1")
   101  	dockerCmd(c, "volume", "create", "--name", "testisinuse1")
   102  	dockerCmd(c, "volume", "create", "--name", "testisinuse2")
   103  
   104  	// Make sure both "created" (but not started), and started
   105  	// containers are included in reference counting
   106  	dockerCmd(c, "run", "--name", "volume-test1", "-v", "testisinuse1:"+prefix+"/foo", "busybox", "true")
   107  	dockerCmd(c, "create", "--name", "volume-test2", "-v", "testisinuse2:"+prefix+"/foo", "busybox", "true")
   108  
   109  	out, _ := dockerCmd(c, "volume", "ls")
   110  
   111  	// No filter, all volumes should show
   112  	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
   113  	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
   114  	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
   115  
   116  	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=false")
   117  
   118  	// Explicitly disabling dangling
   119  	c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
   120  	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
   121  	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
   122  
   123  	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=true")
   124  
   125  	// Filter "dangling" volumes; only "dangling" (unused) volumes should be in the output
   126  	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
   127  	c.Assert(out, check.Not(checker.Contains), "testisinuse1\n", check.Commentf("volume 'testisinuse1' in output, but not expected"))
   128  	c.Assert(out, check.Not(checker.Contains), "testisinuse2\n", check.Commentf("volume 'testisinuse2' in output, but not expected"))
   129  
   130  	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=1")
   131  	// Filter "dangling" volumes; only "dangling" (unused) volumes should be in the output, dangling also accept 1
   132  	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
   133  	c.Assert(out, check.Not(checker.Contains), "testisinuse1\n", check.Commentf("volume 'testisinuse1' in output, but not expected"))
   134  	c.Assert(out, check.Not(checker.Contains), "testisinuse2\n", check.Commentf("volume 'testisinuse2' in output, but not expected"))
   135  
   136  	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=0")
   137  	// dangling=0 is same as dangling=false case
   138  	c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
   139  	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
   140  	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
   141  }
   142  
   143  func (s *DockerSuite) TestVolumeCliLsErrorWithInvalidFilterName(c *check.C) {
   144  	out, _, err := dockerCmdWithError("volume", "ls", "-f", "FOO=123")
   145  	c.Assert(err, checker.NotNil)
   146  	c.Assert(out, checker.Contains, "Invalid filter")
   147  }
   148  
   149  func (s *DockerSuite) TestVolumeCliLsWithIncorrectFilterValue(c *check.C) {
   150  	out, _, err := dockerCmdWithError("volume", "ls", "-f", "dangling=invalid")
   151  	c.Assert(err, check.NotNil)
   152  	c.Assert(out, checker.Contains, "Invalid filter")
   153  }
   154  
   155  func (s *DockerSuite) TestVolumeCliRm(c *check.C) {
   156  	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
   157  	out, _ := dockerCmd(c, "volume", "create")
   158  	id := strings.TrimSpace(out)
   159  
   160  	dockerCmd(c, "volume", "create", "--name", "test")
   161  	dockerCmd(c, "volume", "rm", id)
   162  	dockerCmd(c, "volume", "rm", "test")
   163  
   164  	out, _ = dockerCmd(c, "volume", "ls")
   165  	outArr := strings.Split(strings.TrimSpace(out), "\n")
   166  	c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
   167  
   168  	volumeID := "testing"
   169  	dockerCmd(c, "run", "-v", volumeID+":"+prefix+"/foo", "--name=test", "busybox", "sh", "-c", "echo hello > /foo/bar")
   170  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "volume", "rm", "testing"))
   171  	c.Assert(
   172  		err,
   173  		check.Not(check.IsNil),
   174  		check.Commentf("Should not be able to remove volume that is in use by a container\n%s", out))
   175  
   176  	out, _ = dockerCmd(c, "run", "--volumes-from=test", "--name=test2", "busybox", "sh", "-c", "cat /foo/bar")
   177  	c.Assert(strings.TrimSpace(out), check.Equals, "hello")
   178  	dockerCmd(c, "rm", "-fv", "test2")
   179  	dockerCmd(c, "volume", "inspect", volumeID)
   180  	dockerCmd(c, "rm", "-f", "test")
   181  
   182  	out, _ = dockerCmd(c, "run", "--name=test2", "-v", volumeID+":"+prefix+"/foo", "busybox", "sh", "-c", "cat /foo/bar")
   183  	c.Assert(strings.TrimSpace(out), check.Equals, "hello", check.Commentf("volume data was removed"))
   184  	dockerCmd(c, "rm", "test2")
   185  
   186  	dockerCmd(c, "volume", "rm", volumeID)
   187  	c.Assert(
   188  		exec.Command("volume", "rm", "doesntexist").Run(),
   189  		check.Not(check.IsNil),
   190  		check.Commentf("volume rm should fail with non-existent volume"),
   191  	)
   192  }
   193  
   194  func (s *DockerSuite) TestVolumeCliNoArgs(c *check.C) {
   195  	out, _ := dockerCmd(c, "volume")
   196  	// no args should produce the cmd usage output
   197  	usage := "Usage:	docker volume [OPTIONS] [COMMAND]"
   198  	c.Assert(out, checker.Contains, usage)
   199  
   200  	// invalid arg should error and show the command usage on stderr
   201  	_, stderr, _, err := runCommandWithStdoutStderr(exec.Command(dockerBinary, "volume", "somearg"))
   202  	c.Assert(err, check.NotNil, check.Commentf(stderr))
   203  	c.Assert(stderr, checker.Contains, usage)
   204  
   205  	// invalid flag should error and show the flag error and cmd usage
   206  	_, stderr, _, err = runCommandWithStdoutStderr(exec.Command(dockerBinary, "volume", "--no-such-flag"))
   207  	c.Assert(err, check.NotNil, check.Commentf(stderr))
   208  	c.Assert(stderr, checker.Contains, usage)
   209  	c.Assert(stderr, checker.Contains, "flag provided but not defined: --no-such-flag")
   210  }
   211  
   212  func (s *DockerSuite) TestVolumeCliInspectTmplError(c *check.C) {
   213  	out, _ := dockerCmd(c, "volume", "create")
   214  	name := strings.TrimSpace(out)
   215  
   216  	out, exitCode, err := dockerCmdWithError("volume", "inspect", "--format='{{ .FooBar }}'", name)
   217  	c.Assert(err, checker.NotNil, check.Commentf("Output: %s", out))
   218  	c.Assert(exitCode, checker.Equals, 1, check.Commentf("Output: %s", out))
   219  	c.Assert(out, checker.Contains, "Template parsing error")
   220  }
   221  
   222  func (s *DockerSuite) TestVolumeCliCreateWithOpts(c *check.C) {
   223  	testRequires(c, DaemonIsLinux)
   224  
   225  	dockerCmd(c, "volume", "create", "-d", "local", "--name", "test", "--opt=type=tmpfs", "--opt=device=tmpfs", "--opt=o=size=1m,uid=1000")
   226  	out, _ := dockerCmd(c, "run", "-v", "test:/foo", "busybox", "mount")
   227  
   228  	mounts := strings.Split(out, "\n")
   229  	var found bool
   230  	for _, m := range mounts {
   231  		if strings.Contains(m, "/foo") {
   232  			found = true
   233  			info := strings.Fields(m)
   234  			// tmpfs on <path> type tmpfs (rw,relatime,size=1024k,uid=1000)
   235  			c.Assert(info[0], checker.Equals, "tmpfs")
   236  			c.Assert(info[2], checker.Equals, "/foo")
   237  			c.Assert(info[4], checker.Equals, "tmpfs")
   238  			c.Assert(info[5], checker.Contains, "uid=1000")
   239  			c.Assert(info[5], checker.Contains, "size=1024k")
   240  		}
   241  	}
   242  	c.Assert(found, checker.Equals, true)
   243  }
   244  
   245  func (s *DockerSuite) TestVolumeCliCreateLabel(c *check.C) {
   246  	testVol := "testvolcreatelabel"
   247  	testLabel := "foo"
   248  	testValue := "bar"
   249  
   250  	out, _, err := dockerCmdWithError("volume", "create", "--label", testLabel+"="+testValue, "--name", testVol)
   251  	c.Assert(err, check.IsNil)
   252  
   253  	out, _ = dockerCmd(c, "volume", "inspect", "--format='{{ .Labels."+testLabel+" }}'", testVol)
   254  	c.Assert(strings.TrimSpace(out), check.Equals, testValue)
   255  }
   256  
   257  func (s *DockerSuite) TestVolumeCliCreateLabelMultiple(c *check.C) {
   258  	testVol := "testvolcreatelabel"
   259  
   260  	testLabels := map[string]string{
   261  		"foo": "bar",
   262  		"baz": "foo",
   263  	}
   264  
   265  	args := []string{
   266  		"volume",
   267  		"create",
   268  		"--name",
   269  		testVol,
   270  	}
   271  
   272  	for k, v := range testLabels {
   273  		args = append(args, "--label", k+"="+v)
   274  	}
   275  
   276  	out, _, err := dockerCmdWithError(args...)
   277  	c.Assert(err, check.IsNil)
   278  
   279  	for k, v := range testLabels {
   280  		out, _ = dockerCmd(c, "volume", "inspect", "--format='{{ .Labels."+k+" }}'", testVol)
   281  		c.Assert(strings.TrimSpace(out), check.Equals, v)
   282  	}
   283  }