Repository: containerd/containerd
File: plugins/mount/erofs/plugin_linux_test.go (Go)

Code before:
		t.Fatalf("failed to create layer dir: %v", err)
	}
	if err := os.WriteFile(filepath.Join(layerDir, "test.txt"), []byte("hello"), 0644); err != nil {
		t.Fatalf("failed to write test file: %v", err)
	}

	cmd := exec.Command("mkfs.erofs", layerPath, layerDir)
	if output, err := cmd.CombinedOutput(); err != nil {
		t.Fatalf("failed to create erofs image: %v, output: %s", err, output)
	}

	mountPoint := filepath.Join(tempDir, "mnt")
	if err := os.MkdirAll(mountPoint, 0755); err != nil {
		t.Fatalf("failed to create mount point: %v", err)
	}

	// Test direct file-backed mount
	m := mount.Mount{
		Type:    "erofs",
		Source:  layerPath,
		Options: []string{"ro"},
	}

	err := mount.Fsmount(m, mountPoint)
	if errors.Is(err, unix.ENOTBLK) {
		t.Skip("file-backed mount not supported (requires Linux 6.12+)")
	}
	if err != nil {
		t.Fatalf("fsmount failed: %v", err)
	}
	defer mount.Unmount(mountPoint, 0)

	content, err := os.ReadFile(filepath.Join(mountPoint, "test.txt"))
	if err != nil {
		t.Fatalf("failed to read test file: %v", err)
	}
	if string(content) != "hello" {
		t.Fatalf("unexpected content: %s", content)
	}
}

// TestFsmountLoopDevice tests fsmount with loop device
func TestFsmountLoopDevice(t *testing.T) {
	testutil.RequiresRoot(t)

	if _, err := exec.LookPath("mkfs.erofs"); err != nil {
		t.Skipf("mkfs.erofs not found: %v", err)
	}

	if !snapshotserofs.FindErofs() {
		t.Skip("erofs kernel support not available")

Review comment (bug):
https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md

cc @hsiangkao current support version is 6.11. Maybe we can add this testcase later.
Just in case the CI is broken once runner image has been upgraded.


```
=== SKIP: plugins/mount/erofs TestFsmountFileBacked (0.00s)
    plugin_linux_test.go:79: file-backed mount not supported (requires Linux 6.12+)
```

Code after:
	if err := os.MkdirAll(layerDir, 0755); err != nil {
		t.Fatalf("failed to create layer dir: %v", err)
	}
	if err := os.WriteFile(filepath.Join(layerDir, "test.txt"), []byte("hello"), 0644); err != nil {
		t.Fatalf("failed to write test file: %v", err)
	}

	cmd := exec.Command("mkfs.erofs", layerPath, layerDir)
	if output, err := cmd.CombinedOutput(); err != nil {
		t.Fatalf("failed to create erofs image: %v, output: %s", err, output)
	}

	loopFile, err := mount.SetupLoop(layerPath, mount.LoopParams{
		Readonly:  true,
		Autoclear: true,
	})
	if err != nil {
		t.Fatalf("failed to setup loop device: %v", err)
	}
	loopDev := loopFile.Name()
	defer func() {
		loopFile.Close()
		mount.DetachLoopDevice(loopDev)
	}()

	mountPoint := filepath.Join(tempDir, "mnt")
	if err := os.MkdirAll(mountPoint, 0755); err != nil {
		t.Fatalf("failed to create mount point: %v", err)
	}

	m := mount.Mount{
		Type:    "erofs",
		Source:  loopDev,
		Options: []string{"ro"},
	}

	err = fsmount.Fsmount(m, mountPoint)
	if err != nil {
		t.Fatalf("fsmount with loop device failed: %v", err)
	}
	defer mount.Unmount(mountPoint, 0)

	content, err := os.ReadFile(filepath.Join(mountPoint, "test.txt"))
	if err != nil {
		t.Fatalf("failed to read test file: %v", err)
	}
	if string(content) != "hello" {
		t.Fatalf("unexpected content: %s", content)
	}
}