Skip to content

Commit 594342a

Browse files
committed
Rewrite TestRunBindMountBind
Signed-off-by: apostasie <[email protected]>
1 parent 1a81a20 commit 594342a

File tree

1 file changed

+91
-54
lines changed

1 file changed

+91
-54
lines changed

cmd/nerdctl/container/container_run_mount_linux_test.go

Lines changed: 91 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727
"gotest.tools/v3/assert"
2828

2929
"github.com/containerd/containerd/v2/core/mount"
30+
"github.com/containerd/nerdctl/mod/tigron/expect"
31+
"github.com/containerd/nerdctl/mod/tigron/test"
3032

3133
"github.com/containerd/nerdctl/v2/cmd/nerdctl/helpers"
3234
"github.com/containerd/nerdctl/v2/pkg/rootlessutil"
@@ -304,68 +306,103 @@ func TestRunBindMountTmpfs(t *testing.T) {
304306
base.Cmd("run", "--rm", "--mount", "type=tmpfs,target=/tmp,tmpfs-size=64m", testutil.AlpineImage, "grep", "/tmp", "/proc/mounts").AssertOutWithFunc(f([]string{"rw", "nosuid", "nodev", "size=65536k"}))
305307
}
306308

307-
func TestRunBindMountBind(t *testing.T) {
308-
t.Parallel()
309-
base := testutil.NewBase(t)
310-
tID := testutil.Identifier(t)
311-
rwDir, err := os.MkdirTemp(t.TempDir(), "rw")
312-
if err != nil {
313-
t.Fatal(err)
314-
}
315-
roDir, err := os.MkdirTemp(t.TempDir(), "ro")
316-
if err != nil {
317-
t.Fatal(err)
318-
}
309+
func mountExistsWithOpt(mountPoint, mountOpt string) test.Comparator {
310+
return func(stdout, info string, t *testing.T) {
311+
lines := strings.Split(strings.TrimSpace(stdout), "\n")
312+
mountOutput := []string{}
313+
for _, line := range lines {
314+
if strings.Contains(line, mountPoint) {
315+
mountOutput = strings.Split(line, " ")
316+
break
317+
}
318+
}
319319

320-
containerName := tID
321-
defer base.Cmd("rm", "-f", containerName).AssertOK()
322-
base.Cmd("run",
323-
"-d",
324-
"--name", containerName,
325-
"--mount", fmt.Sprintf("type=bind,src=%s,target=/mnt1", rwDir),
326-
"--mount", fmt.Sprintf("type=bind,src=%s,target=/mnt2,ro", roDir),
327-
testutil.AlpineImage,
328-
"top",
329-
).AssertOK()
330-
base.Cmd("exec", containerName, "sh", "-exc", "echo -n str1 > /mnt1/file1").AssertOK()
331-
base.Cmd("exec", containerName, "sh", "-exc", "echo -n str2 > /mnt2/file2").AssertFail()
320+
assert.Assert(t, len(mountOutput) > 0, "we should have found the mount point in /proc/mounts")
321+
assert.Assert(t, len(mountOutput) >= 4, "invalid format for mount line")
332322

333-
base.Cmd("run",
334-
"--rm",
335-
"--mount", fmt.Sprintf("type=bind,src=%s,target=/mnt1", rwDir),
336-
testutil.AlpineImage,
337-
"cat", "/mnt1/file1",
338-
).AssertOutExactly("str1")
323+
options := strings.Split(mountOutput[3], ",")
339324

340-
// check `bind-propagation`
341-
f := func(allow string) func(stdout string) error {
342-
return func(stdout string) error {
343-
lines := strings.Split(strings.TrimSpace(stdout), "\n")
344-
if len(lines) != 1 {
345-
return fmt.Errorf("expected 1 lines, got %q", stdout)
346-
}
347-
fields := strings.Split(lines[0], " ")
348-
if len(fields) < 4 {
349-
return fmt.Errorf("invalid /proc/mounts format %q", stdout)
325+
found := false
326+
for _, opt := range options {
327+
if mountOpt == opt {
328+
found = true
329+
break
350330
}
331+
}
332+
333+
assert.Assert(t, found, "mount option %s not found", mountOpt)
334+
}
335+
}
351336

352-
options := strings.Split(fields[3], ",")
337+
func TestRunBindMountBind(t *testing.T) {
338+
testCase := nerdtest.Setup()
339+
340+
testCase.Setup = func(data test.Data, helpers test.Helpers) {
341+
// Run a container with bind mount directories, one rw, the other ro
342+
rwDir := data.Temp().Dir("rw")
343+
roDir := data.Temp().Dir("ro")
344+
345+
helpers.Ensure(
346+
"run",
347+
"-d",
348+
"--name", data.Identifier("container"),
349+
"--mount", fmt.Sprintf("type=bind,src=%s,target=/mntrw", rwDir),
350+
"--mount", fmt.Sprintf("type=bind,src=%s,target=/mntro,ro", roDir),
351+
testutil.AlpineImage,
352+
"top",
353+
)
354+
355+
// Save host rwDir location and container id for subtests
356+
data.Labels().Set("container", data.Identifier("container"))
357+
data.Labels().Set("rwDir", rwDir)
358+
}
353359

354-
found := false
355-
for _, s := range options {
356-
if allow == s {
357-
found = true
358-
break
360+
testCase.SubTests = []*test.Case{
361+
{
362+
Description: "ensure we cannot write to ro mount",
363+
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
364+
return helpers.Command("exec", data.Labels().Get("container"), "sh", "-exc", "echo -n failure > /mntro/file")
365+
},
366+
Expected: test.Expects(expect.ExitCodeGenericFail, nil, nil),
367+
},
368+
{
369+
Description: "ensure we can write to rw, and read it back from another container mounting the same target",
370+
Setup: func(data test.Data, helpers test.Helpers) {
371+
helpers.Ensure("exec", data.Labels().Get("container"), "sh", "-exc", "echo -n success > /mntrw/file")
372+
},
373+
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
374+
return helpers.Command(
375+
"run",
376+
"--rm",
377+
"--mount", fmt.Sprintf("type=bind,src=%s,target=/mntrw", data.Labels().Get("rwDir")),
378+
testutil.AlpineImage,
379+
"cat", "/mntrw/file",
380+
)
381+
},
382+
Expected: test.Expects(expect.ExitCodeSuccess, nil, expect.Equals("success")),
383+
},
384+
{
385+
Description: "Check that mntrw is seen in /proc/mounts",
386+
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
387+
return helpers.Command("exec", data.Labels().Get("container"), "cat", "/proc/mounts")
388+
},
389+
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
390+
return &test.Expected{
391+
Output: expect.All(
392+
// Ensure we have mntrw in the mount list
393+
mountExistsWithOpt("/mntrw", "rw"),
394+
mountExistsWithOpt("/mntro", "ro"),
395+
),
359396
}
360-
}
361-
if !found {
362-
return fmt.Errorf("expected stdout to contain %q, got %+v", allow, options)
363-
}
364-
return nil
365-
}
397+
},
398+
},
366399
}
367-
base.Cmd("exec", containerName, "grep", "/mnt1", "/proc/mounts").AssertOutWithFunc(f("rw"))
368-
base.Cmd("exec", containerName, "grep", "/mnt2", "/proc/mounts").AssertOutWithFunc(f("ro"))
400+
401+
testCase.Cleanup = func(data test.Data, helpers test.Helpers) {
402+
helpers.Anyhow("rm", "-f", data.Identifier("container"))
403+
}
404+
405+
testCase.Run(t)
369406
}
370407

371408
func TestRunMountBindMode(t *testing.T) {

0 commit comments

Comments
 (0)