github.com/jwhonce/docker@v0.6.7-0.20190327063223-da823cf3a5a3/integration/container/update_linux_test.go (about) 1 package container // import "github.com/docker/docker/integration/container" 2 3 import ( 4 "context" 5 "strconv" 6 "strings" 7 "testing" 8 "time" 9 10 containertypes "github.com/docker/docker/api/types/container" 11 "github.com/docker/docker/client" 12 "github.com/docker/docker/integration/internal/container" 13 "github.com/docker/docker/internal/test/request" 14 "gotest.tools/assert" 15 is "gotest.tools/assert/cmp" 16 "gotest.tools/poll" 17 "gotest.tools/skip" 18 ) 19 20 func TestUpdateMemory(t *testing.T) { 21 skip.If(t, testEnv.DaemonInfo.OSType == "windows") 22 skip.If(t, !testEnv.DaemonInfo.MemoryLimit) 23 skip.If(t, !testEnv.DaemonInfo.SwapLimit) 24 25 defer setupTest(t)() 26 client := testEnv.APIClient() 27 ctx := context.Background() 28 29 cID := container.Run(t, ctx, client, func(c *container.TestContainerConfig) { 30 c.HostConfig.Resources = containertypes.Resources{ 31 Memory: 200 * 1024 * 1024, 32 } 33 }) 34 35 poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) 36 37 const ( 38 setMemory int64 = 314572800 39 setMemorySwap int64 = 524288000 40 ) 41 42 _, err := client.ContainerUpdate(ctx, cID, containertypes.UpdateConfig{ 43 Resources: containertypes.Resources{ 44 Memory: setMemory, 45 MemorySwap: setMemorySwap, 46 }, 47 }) 48 assert.NilError(t, err) 49 50 inspect, err := client.ContainerInspect(ctx, cID) 51 assert.NilError(t, err) 52 assert.Check(t, is.Equal(setMemory, inspect.HostConfig.Memory)) 53 assert.Check(t, is.Equal(setMemorySwap, inspect.HostConfig.MemorySwap)) 54 55 res, err := container.Exec(ctx, client, cID, 56 []string{"cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes"}) 57 assert.NilError(t, err) 58 assert.Assert(t, is.Len(res.Stderr(), 0)) 59 assert.Equal(t, 0, res.ExitCode) 60 assert.Check(t, is.Equal(strconv.FormatInt(setMemory, 10), strings.TrimSpace(res.Stdout()))) 61 62 res, err = container.Exec(ctx, client, cID, 63 []string{"cat", "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"}) 64 assert.NilError(t, err) 65 assert.Assert(t, is.Len(res.Stderr(), 0)) 66 assert.Equal(t, 0, res.ExitCode) 67 assert.Check(t, is.Equal(strconv.FormatInt(setMemorySwap, 10), strings.TrimSpace(res.Stdout()))) 68 } 69 70 func TestUpdateCPUQuota(t *testing.T) { 71 defer setupTest(t)() 72 client := testEnv.APIClient() 73 ctx := context.Background() 74 75 cID := container.Run(t, ctx, client) 76 77 for _, test := range []struct { 78 desc string 79 update int64 80 }{ 81 {desc: "some random value", update: 15000}, 82 {desc: "a higher value", update: 20000}, 83 {desc: "a lower value", update: 10000}, 84 {desc: "unset value", update: -1}, 85 } { 86 _, err := client.ContainerUpdate(ctx, cID, containertypes.UpdateConfig{ 87 Resources: containertypes.Resources{ 88 CPUQuota: test.update, 89 }, 90 }) 91 assert.NilError(t, err) 92 93 inspect, err := client.ContainerInspect(ctx, cID) 94 assert.NilError(t, err) 95 assert.Check(t, is.Equal(test.update, inspect.HostConfig.CPUQuota)) 96 97 res, err := container.Exec(ctx, client, cID, 98 []string{"/bin/cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"}) 99 assert.NilError(t, err) 100 assert.Assert(t, is.Len(res.Stderr(), 0)) 101 assert.Equal(t, 0, res.ExitCode) 102 103 assert.Check(t, is.Equal(strconv.FormatInt(test.update, 10), strings.TrimSpace(res.Stdout()))) 104 } 105 } 106 107 func TestUpdatePidsLimit(t *testing.T) { 108 skip.If(t, testEnv.DaemonInfo.OSType == "windows") 109 skip.If(t, !testEnv.DaemonInfo.PidsLimit) 110 111 defer setupTest(t)() 112 apiClient := testEnv.APIClient() 113 oldAPIclient := request.NewAPIClient(t, client.WithVersion("1.24")) 114 ctx := context.Background() 115 116 intPtr := func(i int64) *int64 { 117 return &i 118 } 119 120 for _, test := range []struct { 121 desc string 122 oldAPI bool 123 initial *int64 124 update *int64 125 expect int64 126 expectCg string 127 }{ 128 {desc: "update from none", update: intPtr(32), expect: 32, expectCg: "32"}, 129 {desc: "no change", initial: intPtr(32), expect: 32, expectCg: "32"}, 130 {desc: "update lower", initial: intPtr(32), update: intPtr(16), expect: 16, expectCg: "16"}, 131 {desc: "update on old api ignores value", oldAPI: true, initial: intPtr(32), update: intPtr(16), expect: 32, expectCg: "32"}, 132 {desc: "unset limit with zero", initial: intPtr(32), update: intPtr(0), expect: 0, expectCg: "max"}, 133 {desc: "unset limit with minus one", initial: intPtr(32), update: intPtr(-1), expect: 0, expectCg: "max"}, 134 {desc: "unset limit with minus two", initial: intPtr(32), update: intPtr(-2), expect: 0, expectCg: "max"}, 135 } { 136 c := apiClient 137 if test.oldAPI { 138 c = oldAPIclient 139 } 140 141 t.Run(test.desc, func(t *testing.T) { 142 // Using "network=host" to speed up creation (13.96s vs 6.54s) 143 cID := container.Run(t, ctx, apiClient, container.WithPidsLimit(test.initial), container.WithNetworkMode("host")) 144 145 _, err := c.ContainerUpdate(ctx, cID, containertypes.UpdateConfig{ 146 Resources: containertypes.Resources{ 147 PidsLimit: test.update, 148 }, 149 }) 150 assert.NilError(t, err) 151 152 inspect, err := c.ContainerInspect(ctx, cID) 153 assert.NilError(t, err) 154 assert.Assert(t, inspect.HostConfig.Resources.PidsLimit != nil) 155 assert.Equal(t, *inspect.HostConfig.Resources.PidsLimit, test.expect) 156 157 ctx, cancel := context.WithTimeout(ctx, 60*time.Second) 158 defer cancel() 159 160 res, err := container.Exec(ctx, c, cID, []string{"cat", "/sys/fs/cgroup/pids/pids.max"}) 161 assert.NilError(t, err) 162 assert.Assert(t, is.Len(res.Stderr(), 0)) 163 164 out := strings.TrimSpace(res.Stdout()) 165 assert.Equal(t, out, test.expectCg) 166 }) 167 } 168 }