Skip to content

Commit

Permalink
added unit- and e2e-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Omer Preminger committed Jun 6, 2023
1 parent 413c567 commit 1e682e3
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 57 deletions.
73 changes: 69 additions & 4 deletions e2e/actions/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,14 @@ func (c actionTests) actionOciOverlay(t *testing.T) {
}
}

// Create a copy of the extfs test image to be used for testing writable
// extfs image overlays
writableExtfsImgPath := filepath.Join(testDir, "writable-extfs.img")
err = fs.CopyFile(extfsImgPath, writableExtfsImgPath, 0o755)
if err != nil {
t.Fatalf("could not copy %q to %q: %s", extfsImgPath, writableExtfsImgPath, err)
}

tests := []struct {
name string
args []string
Expand Down Expand Up @@ -1223,8 +1231,7 @@ func (c actionTests) actionOciOverlay(t *testing.T) {
"--overlay", filepath.Join(testDir, "my_rw_ol_dir0"),
imageRef, "cat", "/testfile.1", "/maskable_testfile", filepath.Join("/", imgTestFilePath),
},
requiredCmds: []string{"squashfuse"},
exitCode: 255,
exitCode: 255,
},
{
name: "ThreeWritables",
Expand All @@ -1236,8 +1243,66 @@ func (c actionTests) actionOciOverlay(t *testing.T) {
"--overlay", filepath.Join(testDir, "my_rw_ol_dir2"),
imageRef, "cat", "/testfile.1", "/maskable_testfile", filepath.Join("/", imgTestFilePath),
},
requiredCmds: []string{"squashfuse"},
exitCode: 255,
exitCode: 255,
},
{
name: "WritableExtfs",
args: []string{"--overlay", writableExtfsImgPath, imageRef, "sh", "-c", "echo my_test_string > /my_test_file"},
requiredCmds: []string{"fuse2fs"},
exitCode: 0,
},
{
name: "WritableExtfsRevisit",
args: []string{"--overlay", writableExtfsImgPath, imageRef, "cat", "/my_test_file"},
requiredCmds: []string{"fuse2fs"},
exitCode: 0,
wantOutputs: []e2e.SingularityCmdResultOp{
e2e.ExpectOutput(e2e.ExactMatch, "my_test_string"),
},
},
{
name: "WritableExtfsWithDirs",
args: []string{
"--overlay", filepath.Join(testDir, "my_ro_ol_dir0:ro"),
"--overlay", filepath.Join(testDir, "my_ro_ol_dir1:ro"),
"--overlay", writableExtfsImgPath,
imageRef, "cat", "/my_test_file",
},
requiredCmds: []string{"fuse2fs"},
exitCode: 0,
wantOutputs: []e2e.SingularityCmdResultOp{
e2e.ExpectOutput(e2e.ExactMatch, "my_test_string"),
},
},
{
name: "WritableExtfsWithMix",
args: []string{
"--overlay", filepath.Join(testDir, "my_ro_ol_dir0:ro"),
"--overlay", extfsImgPath + ":ro",
"--overlay", filepath.Join(testDir, "my_ro_ol_dir1:ro"),
"--overlay", writableExtfsImgPath,
imageRef, "cat", "/my_test_file",
},
exitCode: 0,
requiredCmds: []string{"fuse2fs"},
wantOutputs: []e2e.SingularityCmdResultOp{
e2e.ExpectOutput(e2e.ExactMatch, "my_test_string"),
},
},
{
name: "WritableExtfsWithAll",
args: []string{
"--overlay", filepath.Join(testDir, "my_ro_ol_dir0:ro"),
"--overlay", extfsImgPath + ":ro",
"--overlay", filepath.Join(testDir, "my_ro_ol_dir1:ro"),
"--overlay", writableExtfsImgPath,
imageRef, "cat", "/my_test_file",
},
exitCode: 0,
requiredCmds: []string{"squashfuse", "fuse2fs"},
wantOutputs: []e2e.SingularityCmdResultOp{
e2e.ExpectOutput(e2e.ExactMatch, "my_test_string"),
},
},
}

Expand Down
72 changes: 62 additions & 10 deletions internal/pkg/util/fs/overlay/overlay_item_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"testing"

"github.com/sylabs/singularity/internal/pkg/test/tool/require"
"github.com/sylabs/singularity/internal/pkg/util/fs"
"github.com/sylabs/singularity/pkg/image"
)

Expand All @@ -21,6 +22,12 @@ const (
extfsTestString string = "extfs-test-string\n"
)

var (
imgsPath = filepath.Join("..", "..", "..", "..", "..", "test", "images")
squashfsImgPath = filepath.Join(imgsPath, "squashfs-for-overlay.img")
extfsImgPath = filepath.Join(imgsPath, "extfs-for-overlay.img")
)

func mkTempDirOrFatal(t *testing.T) string {
tmpDir, err := os.MkdirTemp("", "testoverlayitem-")
if err != nil {
Expand Down Expand Up @@ -207,24 +214,69 @@ func tryImageRO(t *testing.T, olStr string, typeCode int, typeStr, expectStr str
})

testFileStagedPath := filepath.Join(item.StagingDir, testFilePath)
data, err := os.ReadFile(testFileStagedPath)
if err != nil {
t.Fatalf("error while trying to read from file %q: %s", testFileStagedPath, err)
}
foundStr := string(data)
if foundStr != expectStr {
t.Errorf("incorrect file contents in %s img: expected %q, but found: %q", typeStr, expectStr, foundStr)
}
checkForStringInOverlay(t, typeStr, testFileStagedPath, expectStr)
}

func TestSquashfsRO(t *testing.T) {
require.Command(t, "squashfuse")
require.Command(t, "fusermount")
tryImageRO(t, filepath.Join("..", "..", "..", "..", "..", "test", "images", "squashfs-for-overlay.img"), image.SQUASHFS, "squashfs", squashfsTestString)
tryImageRO(t, squashfsImgPath, image.SQUASHFS, "squashfs", squashfsTestString)
}

func TestExtfsRO(t *testing.T) {
require.Command(t, "fuse2fs")
require.Command(t, "fusermount")
tryImageRO(t, filepath.Join("..", "..", "..", "..", "..", "test", "images", "extfs-for-overlay.img")+":ro", image.EXT3, "extfs", extfsTestString)
tryImageRO(t, extfsImgPath+":ro", image.EXT3, "extfs", extfsTestString)
}

func TestExtfsRW(t *testing.T) {
require.Command(t, "fuse2fs")
require.Command(t, "fuse-overlayfs")
require.Command(t, "fusermount")
tmpDir := mkTempDirOrFatal(t)

// Create a copy of the extfs test image to be used for testing writable
// extfs image overlays
writableExtfsImgPath := filepath.Join(tmpDir, "writable-extfs.img")
err := fs.CopyFile(extfsImgPath, writableExtfsImgPath, 0o755)
if err != nil {
t.Fatalf("could not copy %q to %q: %s", extfsImgPath, writableExtfsImgPath, err)
}

item, err := NewItemFromString(writableExtfsImgPath)
if err != nil {
t.Fatalf("failed to mount extfs image at %q: %s", writableExtfsImgPath, err)
}

if item.Type != image.EXT3 {
t.Errorf("item.Type is %v (should be %v)", item.Type, image.EXT3)
}

if err := item.Mount(); err != nil {
t.Fatalf("unable to mount extfs image for reading & writing: %s", err)
}
t.Cleanup(func() {
item.Unmount()
})

testFileStagedPath := filepath.Join(item.StagingDir, testFilePath)
checkForStringInOverlay(t, "extfs", testFileStagedPath, extfsTestString)
otherTestFileStagedPath := testFileStagedPath + "_other"
otherExtfsTestString := "another string"
err = os.WriteFile(otherTestFileStagedPath, []byte(otherExtfsTestString), 0o755)
if err != nil {
t.Errorf("could not write to file %q in extfs image %q: %s", otherTestFileStagedPath, writableExtfsImgPath, err)
}
checkForStringInOverlay(t, "extfs", otherTestFileStagedPath, otherExtfsTestString)
}

func checkForStringInOverlay(t *testing.T, typeStr, stagedPath, expectStr string) {
data, err := os.ReadFile(stagedPath)
if err != nil {
t.Fatalf("error while trying to read from file %q: %s", stagedPath, err)
}
foundStr := string(data)
if foundStr != expectStr {
t.Errorf("incorrect file contents in %s img: expected %q, but found: %q", typeStr, expectStr, foundStr)
}
}
4 changes: 2 additions & 2 deletions internal/pkg/util/fs/overlay/overlay_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const (
upperDir
)

type fs struct {
type filesys struct {
name string
overlayDir dir
}
Expand All @@ -45,7 +45,7 @@ const (
panfs int64 = 0xAAD7AAEA
)

var incompatibleFs = map[int64]fs{
var incompatibleFs = map[int64]filesys{
// NFS filesystem
nfs: {
name: "NFS",
Expand Down
110 changes: 69 additions & 41 deletions internal/pkg/util/fs/overlay/overlay_set_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"testing"

"github.com/sylabs/singularity/internal/pkg/test/tool/require"
"github.com/sylabs/singularity/internal/pkg/util/fs"
)

func addROItemOrFatal(t *testing.T, s *Set, olStr string) *Item {
Expand Down Expand Up @@ -62,13 +63,13 @@ func TestAllTypesAtOnce(t *testing.T) {
squashfsSupported := false
if _, err := exec.LookPath("squashfs"); err == nil {
squashfsSupported = true
addROItemOrFatal(t, &s, filepath.Join("..", "..", "..", "..", "..", "test", "images", "squashfs-for-overlay.img"))
addROItemOrFatal(t, &s, squashfsImgPath)
}

extfsSupported := false
if _, err := exec.LookPath("fuse2fs"); err == nil {
extfsSupported = true
addROItemOrFatal(t, &s, filepath.Join("..", "..", "..", "..", "..", "test", "images", "extfs-for-overlay.img")+":ro")
addROItemOrFatal(t, &s, extfsImgPath+":ro")
}

tmpRWDir := mkTempDirOrFatal(t)
Expand Down Expand Up @@ -122,50 +123,77 @@ func TestPersistentWriteToDir(t *testing.T) {
}
s := Set{WritableOverlay: i}

rootfsDir := mkTempDirOrFatal(t)
performPersistentWriteTest(t, s)
})(t)
}

// This cleanup will serve adequately for both iterations of the overlay-set
// mounting, below. If it happens to get called while the set is not
// mounted, it should fail silently.
t.Cleanup(func() {
if t.Failed() {
s.Unmount(rootfsDir)
}
})
func TestPersistentWriteToExtfsImg(t *testing.T) {
require.Command(t, "fuse2fs")
require.Command(t, "fuse-overlayfs")
require.Command(t, "fusermount")
tmpDir := mkTempDirOrFatal(t)

// Mount the overlay set, write a string to a file, and unmount.
if err := s.Mount(rootfsDir); err != nil {
t.Fatalf("failed to mount overlay set: %s", err)
}
expectStr := "my_test_string"
bytes := []byte(expectStr)
testFilePath := "my_test_file"
testFileMountedPath := filepath.Join(rootfsDir, testFilePath)
if err := os.WriteFile(testFileMountedPath, bytes, 0o644); err != nil {
t.Fatalf("while trying to write file inside mounted overlay-set: %s", err)
}
// Create a copy of the extfs test image to be used for testing writable
// extfs image overlays
writableExtfsImgPath := filepath.Join(tmpDir, "writable-extfs.img")
err := fs.CopyFile(extfsImgPath, writableExtfsImgPath, 0o755)
if err != nil {
t.Fatalf("could not copy %q to %q: %s", extfsImgPath, writableExtfsImgPath, err)
}

if err := s.Unmount(rootfsDir); err != nil {
t.Fatalf("while trying to unmount overlay set: %s", err)
}
i, err := NewItemFromString(writableExtfsImgPath)
if err != nil {
t.Fatalf("failed to create writable-dir overlay item (%q): %s", writableExtfsImgPath, err)
}
s := Set{WritableOverlay: i}

// Mount the same set again, and check that we see the file with the
// expected contents.
if err := s.Mount(rootfsDir); err != nil {
t.Fatalf("failed to mount overlay set: %s", err)
}
data, err := os.ReadFile(testFileMountedPath)
if err != nil {
t.Fatalf("error while trying to read from file %q: %s", testFileMountedPath, err)
}
foundStr := string(data)
if foundStr != expectStr {
t.Errorf("incorrect file contents in mounted overlay set: expected %q, but found: %q", expectStr, foundStr)
}
if err := s.Unmount(rootfsDir); err != nil {
t.Errorf("while trying to unmount overlay set: %s", err)
performPersistentWriteTest(t, s)
}

func performPersistentWriteTest(t *testing.T, s Set) {
rootfsDir := mkTempDirOrFatal(t)

// This cleanup will serve adequately for both iterations of the overlay-set
// mounting, below. If it happens to get called while the set is not
// mounted, it should fail silently.
// Mount the overlay set, write a string to a file, and unmount.
// Mount the same set again, and check that we see the file with the
// expected contents.
t.Cleanup(func() {
if t.Failed() {
s.Unmount(rootfsDir)
}
})(t)
})

if err := s.Mount(rootfsDir); err != nil {
t.Fatalf("failed to mount overlay set: %s", err)
}
expectStr := "my_test_string"
bytes := []byte(expectStr)
testFilePath := "my_test_file"
testFileMountedPath := filepath.Join(rootfsDir, testFilePath)
if err := os.WriteFile(testFileMountedPath, bytes, 0o644); err != nil {
t.Fatalf("while trying to write file inside mounted overlay-set: %s", err)
}

if err := s.Unmount(rootfsDir); err != nil {
t.Fatalf("while trying to unmount overlay set: %s", err)
}

if err := s.Mount(rootfsDir); err != nil {
t.Fatalf("failed to mount overlay set: %s", err)
}
data, err := os.ReadFile(testFileMountedPath)
if err != nil {
t.Fatalf("error while trying to read from file %q: %s", testFileMountedPath, err)
}
foundStr := string(data)
if foundStr != expectStr {
t.Errorf("incorrect file contents in mounted overlay set: expected %q, but found: %q", expectStr, foundStr)
}
if err := s.Unmount(rootfsDir); err != nil {
t.Errorf("while trying to unmount overlay set: %s", err)
}
}

func TestDuplicateItemsInSet(t *testing.T) {
Expand Down

0 comments on commit 1e682e3

Please sign in to comment.