File: squashfs_test.go

package info (click to toggle)
apptainer 1.4.5-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 12,780 kB
  • sloc: sh: 3,329; ansic: 1,706; awk: 414; python: 103; makefile: 54
file content (136 lines) | stat: -rw-r--r-- 3,716 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright (c) Contributors to the Apptainer project, established as
//   Apptainer a Series of LF Projects LLC.
//   For website terms of use, trademark policy, privacy policy and other
//   project policies see https://lfprojects.org/policies
// Copyright (c) 2019-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE.md file distributed with the sources of this project regarding your
// rights to use or distribute this software.

package image

import (
	"io"
	"os"
	"os/exec"
	"testing"
)

// createSquashfs creates a small but valid squashfs file that can be used
// with an image.
func createSquashfs(t *testing.T) string {
	sqshFile, fileErr := os.CreateTemp("", "")
	if fileErr != nil {
		t.Fatalf("impossible to create temporary file: %s\n", fileErr)
	}
	defer sqshFile.Close()

	sqshFilePath := sqshFile.Name()
	// close and delete the temp file since we will be used with the
	// mksquashfs command. We still use TempFile to have a clean way
	// to get a valid path for a temporary file
	sqshFile.Close()
	os.Remove(sqshFilePath)

	cmdBin, lookErr := exec.LookPath("mksquashfs")
	if lookErr != nil {
		t.Skipf("%s is not  available, skipping the test...", cmdBin)
	}

	cmd := exec.Command(cmdBin, t.TempDir(), sqshFilePath)
	cmdErr := cmd.Run()
	if cmdErr != nil {
		t.Fatalf("cannot create squashfs volume: %s\n", cmdErr)
	}

	return sqshFilePath
}

func TestCheckSquashfsHeader(t *testing.T) {
	sqshFilePath := createSquashfs(t)
	defer os.Remove(sqshFilePath)

	img, imgErr := os.Open(sqshFilePath)
	if imgErr != nil {
		t.Fatalf("cannot open file: %s\n", imgErr)
	}
	b := make([]byte, bufferSize)
	n, readErr := img.Read(b)
	if readErr != nil || n != bufferSize {
		t.Fatalf("cannot read the first %d bytes of the image file\n", bufferSize)
	}

	_, err := CheckSquashfsHeader(b)
	if err != nil {
		t.Fatalf("cannot check squashfs header of a valid image")
	}
}

func TestSquashfsInitializer(t *testing.T) {
	// Valid image test
	sqshFilePath := createSquashfs(t)
	defer os.Remove(sqshFilePath)

	var squashfsfmt squashfsFormat
	var err error
	mode := squashfsfmt.openMode(true)

	img := &Image{
		Path: sqshFilePath,
		Name: "test",
	}
	img.Writable = true
	img.File, err = os.OpenFile(sqshFilePath, mode, 0)
	if err != nil {
		t.Fatalf("cannot open image's file: %s\n", err)
	}
	fileinfo, err := img.File.Stat()
	if err != nil {
		img.File.Close()
		t.Fatalf("cannot stat the image file: %s\n", err)
	}

	// initializer must fail if writable is true
	err = squashfsfmt.initializer(img, fileinfo)
	if err == nil {
		t.Fatalf("unexpected success for squashfs initializer\n")
	}
	// reset cursor for header parsing
	img.File.Seek(0, io.SeekStart)
	// initialized must succeed if writable is false
	img.Writable = false
	err = squashfsfmt.initializer(img, fileinfo)
	if err != nil {
		t.Fatalf("unexpected error for squashfs initializer: %s\n", err)
	}
	img.File.Close()

	// Invalid image
	invalidPath := t.TempDir()
	img.File, err = os.Open(invalidPath)
	if err != nil {
		t.Fatalf("open() failed: %s\n", err)
	}
	defer img.File.Close()
	fileinfo, err = img.File.Stat()
	if err != nil {
		t.Fatalf("cannot stat file pointer: %s\n", err)
	}

	err = squashfsfmt.initializer(img, fileinfo)
	if err == nil {
		t.Fatal("squashfs succeeded with a directory while expected to fail")
	}
}

func TestSFSOpenMode(t *testing.T) {
	var squashfsfmt squashfsFormat

	// Yes, openMode() for squashfs always returns os.O_RDONLY
	if squashfsfmt.openMode(true) != os.O_RDONLY {
		t.Fatal("openMode(true) returned the wrong value")
	}
	if squashfsfmt.openMode(false) != os.O_RDONLY {
		t.Fatal("openMode(false) returned the wrong value")
	}
}