From 07184599f71af0ef5b29d025bf1eae6432ae37f3 Mon Sep 17 00:00:00 2001 From: Shishir Mahajan Date: Thu, 4 Feb 2016 10:05:41 -0500 Subject: [PATCH] Tests for PR # 19123: daemon option (--storage-opt dm.basesize) for increasing the base device size on daemon restart Signed-off-by: Shishir Mahajan --- integration-cli/docker_cli_daemon_test.go | 39 +++++++++++++++++++++++ integration-cli/docker_utils.go | 28 ++++++++++++++++ integration-cli/requirements.go | 12 +++++++ 3 files changed, 79 insertions(+) diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index 535c2da85c..42ffe6cd4d 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -20,6 +20,7 @@ import ( "time" "github.com/docker/docker/pkg/integration/checker" + "github.com/docker/go-units" "github.com/docker/libnetwork/iptables" "github.com/docker/libtrust" "github.com/go-check/check" @@ -154,6 +155,44 @@ func (s *DockerDaemonSuite) TestDaemonStartIptablesFalse(c *check.C) { } } +// Make sure we cannot shrink base device at daemon restart. +func (s *DockerDaemonSuite) TestDaemonRestartWithInvalidBasesize(c *check.C) { + testRequires(c, Devicemapper) + c.Assert(s.d.Start(), check.IsNil) + + oldBasesizeBytes := s.d.getBaseDeviceSize(c) + var newBasesizeBytes int64 = 1073741824 //1GB in bytes + + if newBasesizeBytes < oldBasesizeBytes { + err := s.d.Restart("--storage-opt", fmt.Sprintf("dm.basesize=%d", newBasesizeBytes)) + c.Assert(err, check.IsNil, check.Commentf("daemon should not have started as new base device size is less than existing base device size: %v", err)) + } + c.Assert(s.d.Stop(), check.IsNil) +} + +// Make sure we can grow base device at daemon restart. +func (s *DockerDaemonSuite) TestDaemonRestartWithIncreasedBasesize(c *check.C) { + testRequires(c, Devicemapper) + c.Assert(s.d.Start(), check.IsNil) + + oldBasesizeBytes := s.d.getBaseDeviceSize(c) + + var newBasesizeBytes int64 = 53687091200 //50GB in bytes + + if newBasesizeBytes < oldBasesizeBytes { + c.Skip(fmt.Sprintf("New base device size (%v) must be greater than (%s)", units.HumanSize(float64(newBasesizeBytes)), units.HumanSize(float64(oldBasesizeBytes)))) + } + + err := s.d.Restart("--storage-opt", fmt.Sprintf("dm.basesize=%d", newBasesizeBytes)) + c.Assert(err, check.IsNil, check.Commentf("we should have been able to start the daemon with increased base device size: %v", err)) + + basesizeAfterRestart := s.d.getBaseDeviceSize(c) + newBasesize, err := convertBasesize(newBasesizeBytes) + c.Assert(err, check.IsNil, check.Commentf("Error in converting base device size: %v", err)) + c.Assert(newBasesize, check.Equals, basesizeAfterRestart, check.Commentf("Basesize passed is not equal to Basesize set")) + c.Assert(s.d.Stop(), check.IsNil) +} + // Issue #8444: If docker0 bridge is modified (intentionally or unintentionally) and // no longer has an IP associated, we should gracefully handle that case and associate // an IP with it rather than fail daemon start diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 4a9f0e6fa2..78d530c7a5 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -25,11 +25,13 @@ import ( "github.com/docker/docker/opts" "github.com/docker/docker/pkg/httputils" "github.com/docker/docker/pkg/integration" + "github.com/docker/docker/pkg/integration/checker" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/stringutils" "github.com/docker/engine-api/types" "github.com/docker/go-connections/sockets" "github.com/docker/go-connections/tlsconfig" + "github.com/docker/go-units" "github.com/go-check/check" ) @@ -463,6 +465,32 @@ func (d *Daemon) waitRun(contID string) error { return waitInspectWithArgs(contID, "{{.State.Running}}", "true", 10*time.Second, args...) } +func (d *Daemon) getBaseDeviceSize(c *check.C) int64 { + + infoCmdOutput, _, err := runCommandPipelineWithOutput( + exec.Command(dockerBinary, "-H", d.sock(), "info"), + exec.Command("grep", "Base Device Size"), + ) + c.Assert(err, checker.IsNil) + basesizeSlice := strings.Split(infoCmdOutput, ":") + basesize := strings.Trim(basesizeSlice[1], " ") + basesize = strings.Trim(basesize, "\n")[:len(basesize)-3] + basesizeFloat, err := strconv.ParseFloat(strings.Trim(basesize, " "), 64) + c.Assert(err, checker.IsNil) + basesizeBytes := int64(basesizeFloat) * (1024 * 1024 * 1024) + return basesizeBytes +} + +func convertBasesize(basesizeBytes int64) (int64, error) { + basesize := units.HumanSize(float64(basesizeBytes)) + basesize = strings.Trim(basesize, " ")[:len(basesize)-3] + basesizeFloat, err := strconv.ParseFloat(strings.Trim(basesize, " "), 64) + if err != nil { + return 0, err + } + return int64(basesizeFloat) * 1024 * 1024 * 1024, nil +} + // Cmd will execute a docker CLI command against this Daemon. // Example: d.Cmd("version") will run docker -H unix://path/to/unix.sock version func (d *Daemon) Cmd(name string, arg ...string) (string, error) { diff --git a/integration-cli/requirements.go b/integration-cli/requirements.go index f155e226f2..8439f0774b 100644 --- a/integration-cli/requirements.go +++ b/integration-cli/requirements.go @@ -103,6 +103,18 @@ var ( }, "Test requires underlying root filesystem not be backed by overlay.", } + + Devicemapper = testRequirement{ + func() bool { + cmd := exec.Command("grep", "^devicemapper / devicemapper", "/proc/mounts") + if err := cmd.Run(); err != nil { + return false + } + return true + }, + "Test requires underlying root filesystem to be backed by devicemapper.", + } + IPv6 = testRequirement{ func() bool { cmd := exec.Command("test", "-f", "/proc/net/if_inet6")