github.com/dpiddy/docker@v1.12.2-rc1/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  	out, _ = dockerCmd(c, "volume", "ls", "--filter", "name=testisin")
   143  	c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
   144  	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("execpeted volume 'testisinuse1' in output"))
   145  	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
   146  
   147  	out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=invalidDriver")
   148  	outArr := strings.Split(strings.TrimSpace(out), "\n")
   149  	c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
   150  
   151  	out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=local")
   152  	outArr = strings.Split(strings.TrimSpace(out), "\n")
   153  	c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
   154  
   155  	out, _ = dockerCmd(c, "volume", "ls", "--filter", "driver=loc")
   156  	outArr = strings.Split(strings.TrimSpace(out), "\n")
   157  	c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
   158  
   159  }
   160  
   161  func (s *DockerSuite) TestVolumeCliLsErrorWithInvalidFilterName(c *check.C) {
   162  	out, _, err := dockerCmdWithError("volume", "ls", "-f", "FOO=123")
   163  	c.Assert(err, checker.NotNil)
   164  	c.Assert(out, checker.Contains, "Invalid filter")
   165  }
   166  
   167  func (s *DockerSuite) TestVolumeCliLsWithIncorrectFilterValue(c *check.C) {
   168  	out, _, err := dockerCmdWithError("volume", "ls", "-f", "dangling=invalid")
   169  	c.Assert(err, check.NotNil)
   170  	c.Assert(out, checker.Contains, "Invalid filter")
   171  }
   172  
   173  func (s *DockerSuite) TestVolumeCliRm(c *check.C) {
   174  	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
   175  	out, _ := dockerCmd(c, "volume", "create")
   176  	id := strings.TrimSpace(out)
   177  
   178  	dockerCmd(c, "volume", "create", "--name", "test")
   179  	dockerCmd(c, "volume", "rm", id)
   180  	dockerCmd(c, "volume", "rm", "test")
   181  
   182  	out, _ = dockerCmd(c, "volume", "ls")
   183  	outArr := strings.Split(strings.TrimSpace(out), "\n")
   184  	c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
   185  
   186  	volumeID := "testing"
   187  	dockerCmd(c, "run", "-v", volumeID+":"+prefix+"/foo", "--name=test", "busybox", "sh", "-c", "echo hello > /foo/bar")
   188  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "volume", "rm", "testing"))
   189  	c.Assert(
   190  		err,
   191  		check.Not(check.IsNil),
   192  		check.Commentf("Should not be able to remove volume that is in use by a container\n%s", out))
   193  
   194  	out, _ = dockerCmd(c, "run", "--volumes-from=test", "--name=test2", "busybox", "sh", "-c", "cat /foo/bar")
   195  	c.Assert(strings.TrimSpace(out), check.Equals, "hello")
   196  	dockerCmd(c, "rm", "-fv", "test2")
   197  	dockerCmd(c, "volume", "inspect", volumeID)
   198  	dockerCmd(c, "rm", "-f", "test")
   199  
   200  	out, _ = dockerCmd(c, "run", "--name=test2", "-v", volumeID+":"+prefix+"/foo", "busybox", "sh", "-c", "cat /foo/bar")
   201  	c.Assert(strings.TrimSpace(out), check.Equals, "hello", check.Commentf("volume data was removed"))
   202  	dockerCmd(c, "rm", "test2")
   203  
   204  	dockerCmd(c, "volume", "rm", volumeID)
   205  	c.Assert(
   206  		exec.Command("volume", "rm", "doesntexist").Run(),
   207  		check.Not(check.IsNil),
   208  		check.Commentf("volume rm should fail with non-existent volume"),
   209  	)
   210  }
   211  
   212  func (s *DockerSuite) TestVolumeCliNoArgs(c *check.C) {
   213  	out, _ := dockerCmd(c, "volume")
   214  	// no args should produce the cmd usage output
   215  	usage := "Usage:	docker volume COMMAND"
   216  	c.Assert(out, checker.Contains, usage)
   217  
   218  	// invalid arg should error and show the command usage on stderr
   219  	_, stderr, _, err := runCommandWithStdoutStderr(exec.Command(dockerBinary, "volume", "somearg"))
   220  	c.Assert(err, check.NotNil, check.Commentf(stderr))
   221  	c.Assert(stderr, checker.Contains, usage)
   222  
   223  	// invalid flag should error and show the flag error and cmd usage
   224  	_, stderr, _, err = runCommandWithStdoutStderr(exec.Command(dockerBinary, "volume", "--no-such-flag"))
   225  	c.Assert(err, check.NotNil, check.Commentf(stderr))
   226  	c.Assert(stderr, checker.Contains, usage)
   227  	c.Assert(stderr, checker.Contains, "unknown flag: --no-such-flag")
   228  }
   229  
   230  func (s *DockerSuite) TestVolumeCliInspectTmplError(c *check.C) {
   231  	out, _ := dockerCmd(c, "volume", "create")
   232  	name := strings.TrimSpace(out)
   233  
   234  	out, exitCode, err := dockerCmdWithError("volume", "inspect", "--format='{{ .FooBar }}'", name)
   235  	c.Assert(err, checker.NotNil, check.Commentf("Output: %s", out))
   236  	c.Assert(exitCode, checker.Equals, 1, check.Commentf("Output: %s", out))
   237  	c.Assert(out, checker.Contains, "Template parsing error")
   238  }
   239  
   240  func (s *DockerSuite) TestVolumeCliCreateWithOpts(c *check.C) {
   241  	testRequires(c, DaemonIsLinux)
   242  
   243  	dockerCmd(c, "volume", "create", "-d", "local", "--name", "test", "--opt=type=tmpfs", "--opt=device=tmpfs", "--opt=o=size=1m,uid=1000")
   244  	out, _ := dockerCmd(c, "run", "-v", "test:/foo", "busybox", "mount")
   245  
   246  	mounts := strings.Split(out, "\n")
   247  	var found bool
   248  	for _, m := range mounts {
   249  		if strings.Contains(m, "/foo") {
   250  			found = true
   251  			info := strings.Fields(m)
   252  			// tmpfs on <path> type tmpfs (rw,relatime,size=1024k,uid=1000)
   253  			c.Assert(info[0], checker.Equals, "tmpfs")
   254  			c.Assert(info[2], checker.Equals, "/foo")
   255  			c.Assert(info[4], checker.Equals, "tmpfs")
   256  			c.Assert(info[5], checker.Contains, "uid=1000")
   257  			c.Assert(info[5], checker.Contains, "size=1024k")
   258  		}
   259  	}
   260  	c.Assert(found, checker.Equals, true)
   261  }
   262  
   263  func (s *DockerSuite) TestVolumeCliCreateLabel(c *check.C) {
   264  	testVol := "testvolcreatelabel"
   265  	testLabel := "foo"
   266  	testValue := "bar"
   267  
   268  	out, _, err := dockerCmdWithError("volume", "create", "--label", testLabel+"="+testValue, "--name", testVol)
   269  	c.Assert(err, check.IsNil)
   270  
   271  	out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Labels."+testLabel+" }}", testVol)
   272  	c.Assert(strings.TrimSpace(out), check.Equals, testValue)
   273  }
   274  
   275  func (s *DockerSuite) TestVolumeCliCreateLabelMultiple(c *check.C) {
   276  	testVol := "testvolcreatelabel"
   277  
   278  	testLabels := map[string]string{
   279  		"foo": "bar",
   280  		"baz": "foo",
   281  	}
   282  
   283  	args := []string{
   284  		"volume",
   285  		"create",
   286  		"--name",
   287  		testVol,
   288  	}
   289  
   290  	for k, v := range testLabels {
   291  		args = append(args, "--label", k+"="+v)
   292  	}
   293  
   294  	out, _, err := dockerCmdWithError(args...)
   295  	c.Assert(err, check.IsNil)
   296  
   297  	for k, v := range testLabels {
   298  		out, _ = dockerCmd(c, "volume", "inspect", "--format={{ .Labels."+k+" }}", testVol)
   299  		c.Assert(strings.TrimSpace(out), check.Equals, v)
   300  	}
   301  }