github.com/endophage/docker@v1.4.2-0.20161027011718-242853499895/integration-cli/docker_cli_update_unix_test.go (about)

     1  // +build !windows
     2  
     3  package main
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/docker/docker/api/types"
    11  	"github.com/docker/docker/pkg/integration/checker"
    12  	"github.com/docker/docker/pkg/parsers/kernel"
    13  	"github.com/go-check/check"
    14  )
    15  
    16  func (s *DockerSuite) TestUpdateRunningContainer(c *check.C) {
    17  	testRequires(c, DaemonIsLinux)
    18  	testRequires(c, memoryLimitSupport)
    19  
    20  	name := "test-update-container"
    21  	dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "busybox", "top")
    22  	dockerCmd(c, "update", "-m", "500M", name)
    23  
    24  	c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "524288000")
    25  
    26  	file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
    27  	out, _ := dockerCmd(c, "exec", name, "cat", file)
    28  	c.Assert(strings.TrimSpace(out), checker.Equals, "524288000")
    29  }
    30  
    31  func (s *DockerSuite) TestUpdateRunningContainerWithRestart(c *check.C) {
    32  	testRequires(c, DaemonIsLinux)
    33  	testRequires(c, memoryLimitSupport)
    34  
    35  	name := "test-update-container"
    36  	dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "busybox", "top")
    37  	dockerCmd(c, "update", "-m", "500M", name)
    38  	dockerCmd(c, "restart", name)
    39  
    40  	c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "524288000")
    41  
    42  	file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
    43  	out, _ := dockerCmd(c, "exec", name, "cat", file)
    44  	c.Assert(strings.TrimSpace(out), checker.Equals, "524288000")
    45  }
    46  
    47  func (s *DockerSuite) TestUpdateStoppedContainer(c *check.C) {
    48  	testRequires(c, DaemonIsLinux)
    49  	testRequires(c, memoryLimitSupport)
    50  
    51  	name := "test-update-container"
    52  	file := "/sys/fs/cgroup/memory/memory.limit_in_bytes"
    53  	dockerCmd(c, "run", "--name", name, "-m", "300M", "busybox", "cat", file)
    54  	dockerCmd(c, "update", "-m", "500M", name)
    55  
    56  	c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "524288000")
    57  
    58  	out, _ := dockerCmd(c, "start", "-a", name)
    59  	c.Assert(strings.TrimSpace(out), checker.Equals, "524288000")
    60  }
    61  
    62  func (s *DockerSuite) TestUpdatePausedContainer(c *check.C) {
    63  	testRequires(c, DaemonIsLinux)
    64  	testRequires(c, cpuShare)
    65  
    66  	name := "test-update-container"
    67  	dockerCmd(c, "run", "-d", "--name", name, "--cpu-shares", "1000", "busybox", "top")
    68  	dockerCmd(c, "pause", name)
    69  	dockerCmd(c, "update", "--cpu-shares", "500", name)
    70  
    71  	c.Assert(inspectField(c, name, "HostConfig.CPUShares"), checker.Equals, "500")
    72  
    73  	dockerCmd(c, "unpause", name)
    74  	file := "/sys/fs/cgroup/cpu/cpu.shares"
    75  	out, _ := dockerCmd(c, "exec", name, "cat", file)
    76  	c.Assert(strings.TrimSpace(out), checker.Equals, "500")
    77  }
    78  
    79  func (s *DockerSuite) TestUpdateWithUntouchedFields(c *check.C) {
    80  	testRequires(c, DaemonIsLinux)
    81  	testRequires(c, memoryLimitSupport)
    82  	testRequires(c, cpuShare)
    83  
    84  	name := "test-update-container"
    85  	dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "--cpu-shares", "800", "busybox", "top")
    86  	dockerCmd(c, "update", "-m", "500M", name)
    87  
    88  	// Update memory and not touch cpus, `cpuset.cpus` should still have the old value
    89  	out := inspectField(c, name, "HostConfig.CPUShares")
    90  	c.Assert(out, check.Equals, "800")
    91  
    92  	file := "/sys/fs/cgroup/cpu/cpu.shares"
    93  	out, _ = dockerCmd(c, "exec", name, "cat", file)
    94  	c.Assert(strings.TrimSpace(out), checker.Equals, "800")
    95  }
    96  
    97  func (s *DockerSuite) TestUpdateContainerInvalidValue(c *check.C) {
    98  	testRequires(c, DaemonIsLinux)
    99  	testRequires(c, memoryLimitSupport)
   100  
   101  	name := "test-update-container"
   102  	dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "busybox", "true")
   103  	out, _, err := dockerCmdWithError("update", "-m", "2M", name)
   104  	c.Assert(err, check.NotNil)
   105  	expected := "Minimum memory limit allowed is 4MB"
   106  	c.Assert(out, checker.Contains, expected)
   107  }
   108  
   109  func (s *DockerSuite) TestUpdateContainerWithoutFlags(c *check.C) {
   110  	testRequires(c, DaemonIsLinux)
   111  	testRequires(c, memoryLimitSupport)
   112  
   113  	name := "test-update-container"
   114  	dockerCmd(c, "run", "-d", "--name", name, "-m", "300M", "busybox", "true")
   115  	_, _, err := dockerCmdWithError("update", name)
   116  	c.Assert(err, check.NotNil)
   117  }
   118  
   119  func (s *DockerSuite) TestUpdateKernelMemory(c *check.C) {
   120  	testRequires(c, DaemonIsLinux, kernelMemorySupport)
   121  
   122  	name := "test-update-container"
   123  	dockerCmd(c, "run", "-d", "--name", name, "--kernel-memory", "50M", "busybox", "top")
   124  	dockerCmd(c, "update", "--kernel-memory", "100M", name)
   125  
   126  	c.Assert(inspectField(c, name, "HostConfig.KernelMemory"), checker.Equals, "104857600")
   127  
   128  	file := "/sys/fs/cgroup/memory/memory.kmem.limit_in_bytes"
   129  	out, _ := dockerCmd(c, "exec", name, "cat", file)
   130  	c.Assert(strings.TrimSpace(out), checker.Equals, "104857600")
   131  }
   132  
   133  func (s *DockerSuite) TestUpdateKernelMemoryUninitialized(c *check.C) {
   134  	testRequires(c, DaemonIsLinux, kernelMemorySupport)
   135  
   136  	isNewKernel := kernel.CheckKernelVersion(4, 6, 0)
   137  	name := "test-update-container"
   138  	dockerCmd(c, "run", "-d", "--name", name, "busybox", "top")
   139  	_, _, err := dockerCmdWithError("update", "--kernel-memory", "100M", name)
   140  	// Update kernel memory to a running container without kernel memory initialized
   141  	// is not allowed before kernel version 4.6.
   142  	if !isNewKernel {
   143  		c.Assert(err, check.NotNil)
   144  	} else {
   145  		c.Assert(err, check.IsNil)
   146  	}
   147  
   148  	dockerCmd(c, "pause", name)
   149  	_, _, err = dockerCmdWithError("update", "--kernel-memory", "200M", name)
   150  	if !isNewKernel {
   151  		c.Assert(err, check.NotNil)
   152  	} else {
   153  		c.Assert(err, check.IsNil)
   154  	}
   155  	dockerCmd(c, "unpause", name)
   156  
   157  	dockerCmd(c, "stop", name)
   158  	dockerCmd(c, "update", "--kernel-memory", "300M", name)
   159  	dockerCmd(c, "start", name)
   160  
   161  	c.Assert(inspectField(c, name, "HostConfig.KernelMemory"), checker.Equals, "314572800")
   162  
   163  	file := "/sys/fs/cgroup/memory/memory.kmem.limit_in_bytes"
   164  	out, _ := dockerCmd(c, "exec", name, "cat", file)
   165  	c.Assert(strings.TrimSpace(out), checker.Equals, "314572800")
   166  }
   167  
   168  func (s *DockerSuite) TestUpdateSwapMemoryOnly(c *check.C) {
   169  	testRequires(c, DaemonIsLinux)
   170  	testRequires(c, memoryLimitSupport)
   171  	testRequires(c, swapMemorySupport)
   172  
   173  	name := "test-update-container"
   174  	dockerCmd(c, "run", "-d", "--name", name, "--memory", "300M", "--memory-swap", "500M", "busybox", "top")
   175  	dockerCmd(c, "update", "--memory-swap", "600M", name)
   176  
   177  	c.Assert(inspectField(c, name, "HostConfig.MemorySwap"), checker.Equals, "629145600")
   178  
   179  	file := "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"
   180  	out, _ := dockerCmd(c, "exec", name, "cat", file)
   181  	c.Assert(strings.TrimSpace(out), checker.Equals, "629145600")
   182  }
   183  
   184  func (s *DockerSuite) TestUpdateInvalidSwapMemory(c *check.C) {
   185  	testRequires(c, DaemonIsLinux)
   186  	testRequires(c, memoryLimitSupport)
   187  	testRequires(c, swapMemorySupport)
   188  
   189  	name := "test-update-container"
   190  	dockerCmd(c, "run", "-d", "--name", name, "--memory", "300M", "--memory-swap", "500M", "busybox", "top")
   191  	_, _, err := dockerCmdWithError("update", "--memory-swap", "200M", name)
   192  	// Update invalid swap memory should fail.
   193  	// This will pass docker config validation, but failed at kernel validation
   194  	c.Assert(err, check.NotNil)
   195  
   196  	// Update invalid swap memory with failure should not change HostConfig
   197  	c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "314572800")
   198  	c.Assert(inspectField(c, name, "HostConfig.MemorySwap"), checker.Equals, "524288000")
   199  
   200  	dockerCmd(c, "update", "--memory-swap", "600M", name)
   201  
   202  	c.Assert(inspectField(c, name, "HostConfig.MemorySwap"), checker.Equals, "629145600")
   203  
   204  	file := "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"
   205  	out, _ := dockerCmd(c, "exec", name, "cat", file)
   206  	c.Assert(strings.TrimSpace(out), checker.Equals, "629145600")
   207  }
   208  
   209  func (s *DockerSuite) TestUpdateStats(c *check.C) {
   210  	testRequires(c, DaemonIsLinux)
   211  	testRequires(c, memoryLimitSupport)
   212  	testRequires(c, cpuCfsQuota)
   213  	name := "foo"
   214  	dockerCmd(c, "run", "-d", "-ti", "--name", name, "-m", "500m", "busybox")
   215  
   216  	c.Assert(waitRun(name), checker.IsNil)
   217  
   218  	getMemLimit := func(id string) uint64 {
   219  		resp, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", id), nil, "")
   220  		c.Assert(err, checker.IsNil)
   221  		c.Assert(resp.Header.Get("Content-Type"), checker.Equals, "application/json")
   222  
   223  		var v *types.Stats
   224  		err = json.NewDecoder(body).Decode(&v)
   225  		c.Assert(err, checker.IsNil)
   226  		body.Close()
   227  
   228  		return v.MemoryStats.Limit
   229  	}
   230  	preMemLimit := getMemLimit(name)
   231  
   232  	dockerCmd(c, "update", "--cpu-quota", "2000", name)
   233  
   234  	curMemLimit := getMemLimit(name)
   235  
   236  	c.Assert(preMemLimit, checker.Equals, curMemLimit)
   237  
   238  }
   239  
   240  func (s *DockerSuite) TestUpdateMemoryWithSwapMemory(c *check.C) {
   241  	testRequires(c, DaemonIsLinux)
   242  	testRequires(c, memoryLimitSupport)
   243  	testRequires(c, swapMemorySupport)
   244  
   245  	name := "test-update-container"
   246  	dockerCmd(c, "run", "-d", "--name", name, "--memory", "300M", "busybox", "top")
   247  	out, _, err := dockerCmdWithError("update", "--memory", "800M", name)
   248  	c.Assert(err, checker.NotNil)
   249  	c.Assert(out, checker.Contains, "Memory limit should be smaller than already set memoryswap limit")
   250  
   251  	dockerCmd(c, "update", "--memory", "800M", "--memory-swap", "1000M", name)
   252  }