Some of these tests were making assumptions about the daemon's internals
by using `config.DefaultShmSize` from the daemon config package.
Rewrite them to start a daemon with a custom default, and verify the
tests to use that default.
This migrates the following tests from integration-cli to integration;
- `DockerAPISuite.TestPostContainersCreateShmSizeNegative`
- `DockerAPISuite.TestPostContainersCreateShmSizeHostConfigOmitted`
- `DockerAPISuite.TestPostContainersCreateShmSizeOmitted`
- `DockerAPISuite.TestPostContainersCreateWithShmSize`
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -11,14 +11,12 @@ import ( |
| 11 | 11 |
"net/http" |
| 12 | 12 |
"os" |
| 13 | 13 |
"path/filepath" |
| 14 |
- "regexp" |
|
| 15 | 14 |
"runtime" |
| 16 | 15 |
"strings" |
| 17 | 16 |
"testing" |
| 18 | 17 |
"time" |
| 19 | 18 |
|
| 20 | 19 |
cerrdefs "github.com/containerd/errdefs" |
| 21 |
- dconfig "github.com/docker/docker/daemon/config" |
|
| 22 | 20 |
"github.com/docker/docker/daemon/volume" |
| 23 | 21 |
"github.com/docker/docker/integration-cli/cli" |
| 24 | 22 |
"github.com/docker/docker/integration-cli/cli/build" |
| ... | ... |
@@ -1139,110 +1137,6 @@ func (s *DockerAPISuite) TestPostContainersCreateWithWrongCpusetValues(c *testin |
| 1139 | 1139 |
assert.ErrorContains(c, err, expected) |
| 1140 | 1140 |
} |
| 1141 | 1141 |
|
| 1142 |
-func (s *DockerAPISuite) TestPostContainersCreateShmSizeNegative(c *testing.T) {
|
|
| 1143 |
- // ShmSize is not supported on Windows |
|
| 1144 |
- testRequires(c, DaemonIsLinux) |
|
| 1145 |
- config := container.Config{
|
|
| 1146 |
- Image: "busybox", |
|
| 1147 |
- } |
|
| 1148 |
- hostConfig := container.HostConfig{
|
|
| 1149 |
- ShmSize: -1, |
|
| 1150 |
- } |
|
| 1151 |
- |
|
| 1152 |
- apiClient, err := client.NewClientWithOpts(client.FromEnv) |
|
| 1153 |
- assert.NilError(c, err) |
|
| 1154 |
- defer apiClient.Close() |
|
| 1155 |
- |
|
| 1156 |
- _, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig, &network.NetworkingConfig{}, nil, "")
|
|
| 1157 |
- assert.ErrorContains(c, err, "SHM size can not be less than 0") |
|
| 1158 |
-} |
|
| 1159 |
- |
|
| 1160 |
-func (s *DockerAPISuite) TestPostContainersCreateShmSizeHostConfigOmitted(c *testing.T) {
|
|
| 1161 |
- // ShmSize is not supported on Windows |
|
| 1162 |
- testRequires(c, DaemonIsLinux) |
|
| 1163 |
- |
|
| 1164 |
- config := container.Config{
|
|
| 1165 |
- Image: "busybox", |
|
| 1166 |
- Cmd: []string{"mount"},
|
|
| 1167 |
- } |
|
| 1168 |
- |
|
| 1169 |
- apiClient, err := client.NewClientWithOpts(client.FromEnv) |
|
| 1170 |
- assert.NilError(c, err) |
|
| 1171 |
- defer apiClient.Close() |
|
| 1172 |
- |
|
| 1173 |
- ctr, err := apiClient.ContainerCreate(testutil.GetContext(c), &config, &container.HostConfig{}, &network.NetworkingConfig{}, nil, "")
|
|
| 1174 |
- assert.NilError(c, err) |
|
| 1175 |
- |
|
| 1176 |
- containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID) |
|
| 1177 |
- assert.NilError(c, err) |
|
| 1178 |
- |
|
| 1179 |
- assert.Equal(c, containerJSON.HostConfig.ShmSize, dconfig.DefaultShmSize) |
|
| 1180 |
- |
|
| 1181 |
- out := cli.DockerCmd(c, "start", "-i", containerJSON.ID).Combined() |
|
| 1182 |
- shmRegexp := regexp.MustCompile(`shm on /dev/shm type tmpfs(.*)size=65536k`) |
|
| 1183 |
- if !shmRegexp.MatchString(out) {
|
|
| 1184 |
- c.Fatalf("Expected shm of 64MB in mount command, got %v", out)
|
|
| 1185 |
- } |
|
| 1186 |
-} |
|
| 1187 |
- |
|
| 1188 |
-func (s *DockerAPISuite) TestPostContainersCreateShmSizeOmitted(c *testing.T) {
|
|
| 1189 |
- // ShmSize is not supported on Windows |
|
| 1190 |
- testRequires(c, DaemonIsLinux) |
|
| 1191 |
- config := container.Config{
|
|
| 1192 |
- Image: "busybox", |
|
| 1193 |
- Cmd: []string{"mount"},
|
|
| 1194 |
- } |
|
| 1195 |
- |
|
| 1196 |
- apiClient, err := client.NewClientWithOpts(client.FromEnv) |
|
| 1197 |
- assert.NilError(c, err) |
|
| 1198 |
- defer apiClient.Close() |
|
| 1199 |
- |
|
| 1200 |
- ctr, err := apiClient.ContainerCreate(testutil.GetContext(c), &config, &container.HostConfig{}, &network.NetworkingConfig{}, nil, "")
|
|
| 1201 |
- assert.NilError(c, err) |
|
| 1202 |
- |
|
| 1203 |
- containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID) |
|
| 1204 |
- assert.NilError(c, err) |
|
| 1205 |
- |
|
| 1206 |
- assert.Equal(c, containerJSON.HostConfig.ShmSize, int64(67108864)) |
|
| 1207 |
- |
|
| 1208 |
- out := cli.DockerCmd(c, "start", "-i", containerJSON.ID).Combined() |
|
| 1209 |
- shmRegexp := regexp.MustCompile(`shm on /dev/shm type tmpfs(.*)size=65536k`) |
|
| 1210 |
- if !shmRegexp.MatchString(out) {
|
|
| 1211 |
- c.Fatalf("Expected shm of 64MB in mount command, got %v", out)
|
|
| 1212 |
- } |
|
| 1213 |
-} |
|
| 1214 |
- |
|
| 1215 |
-func (s *DockerAPISuite) TestPostContainersCreateWithShmSize(c *testing.T) {
|
|
| 1216 |
- // ShmSize is not supported on Windows |
|
| 1217 |
- testRequires(c, DaemonIsLinux) |
|
| 1218 |
- config := container.Config{
|
|
| 1219 |
- Image: "busybox", |
|
| 1220 |
- Cmd: []string{"mount"},
|
|
| 1221 |
- } |
|
| 1222 |
- |
|
| 1223 |
- hostConfig := container.HostConfig{
|
|
| 1224 |
- ShmSize: 1073741824, |
|
| 1225 |
- } |
|
| 1226 |
- |
|
| 1227 |
- apiClient, err := client.NewClientWithOpts(client.FromEnv) |
|
| 1228 |
- assert.NilError(c, err) |
|
| 1229 |
- defer apiClient.Close() |
|
| 1230 |
- |
|
| 1231 |
- ctr, err := apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig, &network.NetworkingConfig{}, nil, "")
|
|
| 1232 |
- assert.NilError(c, err) |
|
| 1233 |
- |
|
| 1234 |
- containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID) |
|
| 1235 |
- assert.NilError(c, err) |
|
| 1236 |
- |
|
| 1237 |
- assert.Equal(c, containerJSON.HostConfig.ShmSize, int64(1073741824)) |
|
| 1238 |
- |
|
| 1239 |
- out := cli.DockerCmd(c, "start", "-i", containerJSON.ID).Combined() |
|
| 1240 |
- shmRegex := regexp.MustCompile(`shm on /dev/shm type tmpfs(.*)size=1048576k`) |
|
| 1241 |
- if !shmRegex.MatchString(out) {
|
|
| 1242 |
- c.Fatalf("Expected shm of 1GB in mount command, got %v", out)
|
|
| 1243 |
- } |
|
| 1244 |
-} |
|
| 1245 |
- |
|
| 1246 | 1142 |
func (s *DockerAPISuite) TestPostContainersCreateMemorySwappinessHostConfigOmitted(c *testing.T) {
|
| 1247 | 1143 |
// Swappiness is not supported on Windows |
| 1248 | 1144 |
testRequires(c, DaemonIsLinux) |
| ... | ... |
@@ -9,10 +9,12 @@ import ( |
| 9 | 9 |
"strings" |
| 10 | 10 |
"testing" |
| 11 | 11 |
|
| 12 |
+ cerrdefs "github.com/containerd/errdefs" |
|
| 12 | 13 |
"github.com/docker/docker/integration/internal/container" |
| 13 | 14 |
net "github.com/docker/docker/integration/internal/network" |
| 14 | 15 |
"github.com/docker/docker/testutil" |
| 15 | 16 |
"github.com/docker/docker/testutil/daemon" |
| 17 |
+ "github.com/docker/go-units" |
|
| 16 | 18 |
"github.com/moby/moby/api/stdcopy" |
| 17 | 19 |
containertypes "github.com/moby/moby/api/types/container" |
| 18 | 20 |
"github.com/moby/moby/api/types/versions" |
| ... | ... |
@@ -457,8 +459,8 @@ func TestCgroupRW(t *testing.T) {
|
| 457 | 457 |
} |
| 458 | 458 |
for _, tc := range testCases {
|
| 459 | 459 |
t.Run(tc.name, func(t *testing.T) {
|
| 460 |
- config := container.NewTestConfig(tc.ops...) |
|
| 461 |
- resp, err := container.CreateFromConfig(ctx, apiClient, config) |
|
| 460 |
+ cfg := container.NewTestConfig(tc.ops...) |
|
| 461 |
+ resp, err := container.CreateFromConfig(ctx, apiClient, cfg) |
|
| 462 | 462 |
if err != nil {
|
| 463 | 463 |
assert.Equal(t, tc.expectedErrMsg, err.Error()) |
| 464 | 464 |
return |
| ... | ... |
@@ -488,3 +490,79 @@ func TestCgroupRW(t *testing.T) {
|
| 488 | 488 |
}) |
| 489 | 489 |
} |
| 490 | 490 |
} |
| 491 |
+ |
|
| 492 |
+func TestContainerShmSize(t *testing.T) {
|
|
| 493 |
+ ctx := setupTest(t) |
|
| 494 |
+ |
|
| 495 |
+ const defaultSize = "1000k" |
|
| 496 |
+ defaultSizeBytes, err := units.RAMInBytes(defaultSize) |
|
| 497 |
+ assert.NilError(t, err) |
|
| 498 |
+ |
|
| 499 |
+ d := daemon.New(t) |
|
| 500 |
+ d.StartWithBusybox(ctx, t, "--default-shm-size="+defaultSize) |
|
| 501 |
+ defer d.Stop(t) |
|
| 502 |
+ |
|
| 503 |
+ apiClient := d.NewClientT(t) |
|
| 504 |
+ |
|
| 505 |
+ tests := []struct {
|
|
| 506 |
+ doc string |
|
| 507 |
+ opt container.ConfigOpt |
|
| 508 |
+ expSize string |
|
| 509 |
+ expErr string |
|
| 510 |
+ }{
|
|
| 511 |
+ {
|
|
| 512 |
+ doc: "nil hostConfig", |
|
| 513 |
+ opt: container.WithHostConfig(nil), |
|
| 514 |
+ expSize: defaultSize, |
|
| 515 |
+ }, |
|
| 516 |
+ {
|
|
| 517 |
+ doc: "empty hostConfig", |
|
| 518 |
+ opt: container.WithHostConfig(&containertypes.HostConfig{}),
|
|
| 519 |
+ expSize: defaultSize, |
|
| 520 |
+ }, |
|
| 521 |
+ {
|
|
| 522 |
+ doc: "custom shmSize", |
|
| 523 |
+ opt: container.WithHostConfig(&containertypes.HostConfig{ShmSize: defaultSizeBytes * 2}),
|
|
| 524 |
+ expSize: "2000k", |
|
| 525 |
+ }, |
|
| 526 |
+ {
|
|
| 527 |
+ doc: "negative shmSize", |
|
| 528 |
+ opt: container.WithHostConfig(&containertypes.HostConfig{ShmSize: -1}),
|
|
| 529 |
+ expErr: "Error response from daemon: SHM size can not be less than 0", |
|
| 530 |
+ }, |
|
| 531 |
+ } |
|
| 532 |
+ |
|
| 533 |
+ for _, tc := range tests {
|
|
| 534 |
+ t.Run(tc.doc, func(t *testing.T) {
|
|
| 535 |
+ if tc.expErr != "" {
|
|
| 536 |
+ cfg := container.NewTestConfig(container.WithCmd("sh", "-c", "grep /dev/shm /proc/self/mountinfo"), tc.opt)
|
|
| 537 |
+ _, err := container.CreateFromConfig(ctx, apiClient, cfg) |
|
| 538 |
+ assert.Check(t, is.ErrorContains(err, tc.expErr)) |
|
| 539 |
+ assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument)) |
|
| 540 |
+ return |
|
| 541 |
+ } |
|
| 542 |
+ |
|
| 543 |
+ cID := container.Run(ctx, t, apiClient, |
|
| 544 |
+ container.WithCmd("sh", "-c", "grep /dev/shm /proc/self/mountinfo"),
|
|
| 545 |
+ tc.opt, |
|
| 546 |
+ ) |
|
| 547 |
+ |
|
| 548 |
+ t.Cleanup(func() {
|
|
| 549 |
+ container.Remove(ctx, t, apiClient, cID, containertypes.RemoveOptions{})
|
|
| 550 |
+ }) |
|
| 551 |
+ |
|
| 552 |
+ expectedSize, err := units.RAMInBytes(tc.expSize) |
|
| 553 |
+ assert.NilError(t, err) |
|
| 554 |
+ |
|
| 555 |
+ ctr := container.Inspect(ctx, t, apiClient, cID) |
|
| 556 |
+ assert.Check(t, is.Equal(ctr.HostConfig.ShmSize, expectedSize)) |
|
| 557 |
+ |
|
| 558 |
+ out, err := container.Output(ctx, apiClient, cID) |
|
| 559 |
+ assert.NilError(t, err) |
|
| 560 |
+ |
|
| 561 |
+ // e.g., "218 213 0:87 / /dev/shm rw,nosuid,nodev,noexec,relatime - tmpfs shm rw,size=1000k" |
|
| 562 |
+ assert.Assert(t, is.Contains(out.Stdout, "/dev/shm "), "shm mount not found in output: \n%v", out.Stdout) |
|
| 563 |
+ assert.Check(t, is.Contains(out.Stdout, "size="+tc.expSize)) |
|
| 564 |
+ }) |
|
| 565 |
+ } |
|
| 566 |
+} |
| ... | ... |
@@ -12,6 +12,9 @@ import ( |
| 12 | 12 |
ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
| 13 | 13 |
) |
| 14 | 14 |
|
| 15 |
+// ConfigOpt is an option to apply to a container. |
|
| 16 |
+type ConfigOpt func(*TestContainerConfig) |
|
| 17 |
+ |
|
| 15 | 18 |
// WithName sets the name of the container |
| 16 | 19 |
func WithName(name string) func(*TestContainerConfig) {
|
| 17 | 20 |
return func(c *TestContainerConfig) {
|
| ... | ... |
@@ -361,3 +364,10 @@ func WithContainerWideMacAddress(address string) func(c *TestContainerConfig) {
|
| 361 | 361 |
c.Config.MacAddress = address //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44. |
| 362 | 362 |
} |
| 363 | 363 |
} |
| 364 |
+ |
|
| 365 |
+// WithHostConfig sets a custom [container.HostConfig] for the container. |
|
| 366 |
+func WithHostConfig(hc *container.HostConfig) func(c *TestContainerConfig) {
|
|
| 367 |
+ return func(c *TestContainerConfig) {
|
|
| 368 |
+ c.HostConfig = hc |
|
| 369 |
+ } |
|
| 370 |
+} |