github.com/anchore/syft@v1.38.2/internal/file/squashfs_test.go (about)

     1  package file
     2  
     3  import (
     4  	"io/fs"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/diskfs/go-diskfs/backend/file"
    10  	"github.com/diskfs/go-diskfs/filesystem"
    11  	"github.com/diskfs/go-diskfs/filesystem/squashfs"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func createTestFS(t *testing.T) filesystem.FileSystem {
    17  	dir := t.TempDir()
    18  
    19  	filename := "test.squashfs"
    20  	f, err := os.Create(filepath.Join(dir, filename))
    21  	require.NoError(t, err)
    22  
    23  	b := file.New(f, false)
    24  	fsys, err := squashfs.Create(b, 0, 0, 4096)
    25  	require.NoError(t, err)
    26  
    27  	testFiles := []struct {
    28  		path    string
    29  		content string
    30  		isDir   bool
    31  	}{
    32  		{"/file1.txt", "content of file1", false},
    33  		{"/file2.txt", "content of file2", false},
    34  		{"/dir1", "", true},
    35  		{"/dir1/subfile1.txt", "content of subfile1", false},
    36  		{"/dir1/subfile2.txt", "content of subfile2", false},
    37  		{"/dir1/subdir1", "", true},
    38  		{"/dir1/subdir1/deepfile.txt", "deep content", false},
    39  		{"/dir2", "", true},
    40  		{"/dir2/anotherfile.txt", "another content", false},
    41  		{"/emptydir", "", true},
    42  	}
    43  
    44  	for _, tf := range testFiles {
    45  		if tf.isDir {
    46  			err := fsys.Mkdir(tf.path)
    47  			require.NoError(t, err)
    48  		} else {
    49  			f, err := fsys.OpenFile(tf.path, os.O_CREATE|os.O_RDWR)
    50  			require.NoError(t, err)
    51  			_, err = f.Write([]byte(tf.content))
    52  			require.NoError(t, err)
    53  			f.Close()
    54  		}
    55  	}
    56  
    57  	return fsys
    58  }
    59  
    60  func TestWalkDiskDir_CompleteTraversal(t *testing.T) {
    61  	fsys := createTestFS(t)
    62  
    63  	var visitedPaths []string
    64  	err := WalkDiskDir(fsys, "/", func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error {
    65  		require.NoError(t, err)
    66  		visitedPaths = append(visitedPaths, path)
    67  		return nil
    68  	})
    69  
    70  	require.NoError(t, err)
    71  
    72  	expectedPaths := []string{
    73  		"/file1.txt",
    74  		"/file2.txt",
    75  		"/dir1",
    76  		"/dir1/subfile1.txt",
    77  		"/dir1/subfile2.txt",
    78  		"/dir1/subdir1",
    79  		"/dir1/subdir1/deepfile.txt",
    80  		"/dir2",
    81  		"/dir2/anotherfile.txt",
    82  		"/emptydir",
    83  	}
    84  
    85  	assert.ElementsMatch(t, expectedPaths, visitedPaths)
    86  }
    87  
    88  func TestWalkDiskDir_FileInfoCorrect(t *testing.T) {
    89  	fsys := createTestFS(t)
    90  
    91  	var fileInfos []struct {
    92  		path  string
    93  		isDir bool
    94  		name  string
    95  	}
    96  
    97  	err := WalkDiskDir(fsys, "/", func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error {
    98  		require.NoError(t, err)
    99  		require.NotNil(t, d)
   100  		fileInfos = append(fileInfos, struct {
   101  			path  string
   102  			isDir bool
   103  			name  string
   104  		}{
   105  			path:  path,
   106  			isDir: d.IsDir(),
   107  			name:  d.Name(),
   108  		})
   109  		return nil
   110  	})
   111  
   112  	require.NoError(t, err)
   113  
   114  	for _, fi := range fileInfos {
   115  		expectedName := filepath.Base(fi.path)
   116  		assert.Equal(t, expectedName, fi.name)
   117  
   118  		if fi.path == "/dir1" || fi.path == "/dir2" || fi.path == "/emptydir" || fi.path == "/dir1/subdir1" {
   119  			assert.True(t, fi.isDir, "Expected %s to be directory", fi.path)
   120  		} else {
   121  			assert.False(t, fi.isDir, "Expected %s to be file", fi.path)
   122  		}
   123  	}
   124  }
   125  
   126  func TestWalkDiskDir_SkipDir(t *testing.T) {
   127  	fsys := createTestFS(t)
   128  
   129  	var visitedPaths []string
   130  	err := WalkDiskDir(fsys, "/", func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error {
   131  		require.NoError(t, err)
   132  		visitedPaths = append(visitedPaths, path)
   133  		if path == "/dir1" {
   134  			return fs.SkipDir
   135  		}
   136  		return nil
   137  	})
   138  
   139  	require.NoError(t, err)
   140  
   141  	assert.Contains(t, visitedPaths, "/dir1")
   142  	assert.NotContains(t, visitedPaths, "/dir1/subfile1.txt")
   143  	assert.NotContains(t, visitedPaths, "/dir1/subfile2.txt")
   144  	assert.NotContains(t, visitedPaths, "/dir1/subdir1")
   145  	assert.NotContains(t, visitedPaths, "/dir1/subdir1/deepfile.txt")
   146  
   147  	assert.Contains(t, visitedPaths, "/dir2")
   148  	assert.Contains(t, visitedPaths, "/dir2/anotherfile.txt")
   149  }
   150  
   151  func TestWalkDiskDir_SkipAll(t *testing.T) {
   152  	fsys := createTestFS(t)
   153  
   154  	var visitedPaths []string
   155  	err := WalkDiskDir(fsys, "/", func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error {
   156  		require.NoError(t, err)
   157  		visitedPaths = append(visitedPaths, path)
   158  		if path == "/dir1" {
   159  			return fs.SkipAll
   160  		}
   161  		return nil
   162  	})
   163  
   164  	require.NoError(t, err)
   165  
   166  	assert.Contains(t, visitedPaths, "/dir1")
   167  
   168  	assert.NotContains(t, visitedPaths, "/file1.txt")
   169  	assert.NotContains(t, visitedPaths, "/file2.txt")
   170  	assert.NotContains(t, visitedPaths, "/dir1/subfile1.txt")
   171  	assert.NotContains(t, visitedPaths, "/dir2")
   172  	assert.NotContains(t, visitedPaths, "/dir2/anotherfile.txt")
   173  	assert.NotContains(t, visitedPaths, "/emptydir")
   174  }
   175  
   176  func TestWalkDiskDir_EmptyDirectory(t *testing.T) {
   177  	fs := createTestFS(t)
   178  
   179  	var visitedPaths []string
   180  	err := WalkDiskDir(fs, "/emptydir", func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error {
   181  		require.NoError(t, err)
   182  		visitedPaths = append(visitedPaths, path)
   183  		return nil
   184  	})
   185  
   186  	require.NoError(t, err)
   187  	assert.Empty(t, visitedPaths)
   188  }
   189  
   190  func TestWalkDiskDir_NonexistentPath(t *testing.T) {
   191  	fs := createTestFS(t)
   192  
   193  	err := WalkDiskDir(fs, "/nonexistent", func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error {
   194  		return nil
   195  	})
   196  
   197  	assert.Error(t, err)
   198  }
   199  
   200  func TestWalkDiskDir_WalkFunctionError(t *testing.T) {
   201  	fs := createTestFS(t)
   202  
   203  	customErr := assert.AnError
   204  	err := WalkDiskDir(fs, "/", func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error {
   205  		if path == "/file1.txt" {
   206  			return customErr
   207  		}
   208  		return nil
   209  	})
   210  
   211  	assert.Error(t, err)
   212  	assert.Equal(t, customErr, err)
   213  }
   214  
   215  func TestWalkDiskDir_SubdirectoryTraversal(t *testing.T) {
   216  	fs := createTestFS(t)
   217  
   218  	var visitedPaths []string
   219  	err := WalkDiskDir(fs, "/dir1", func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error {
   220  		require.NoError(t, err)
   221  		visitedPaths = append(visitedPaths, path)
   222  		return nil
   223  	})
   224  
   225  	require.NoError(t, err)
   226  
   227  	expectedPaths := []string{
   228  		"/dir1/subfile1.txt",
   229  		"/dir1/subfile2.txt",
   230  		"/dir1/subdir1",
   231  		"/dir1/subdir1/deepfile.txt",
   232  	}
   233  
   234  	assert.ElementsMatch(t, expectedPaths, visitedPaths)
   235  }
   236  
   237  func TestWalkDiskDir_SingleFile(t *testing.T) {
   238  	fs := createTestFS(t)
   239  
   240  	var visitedPaths []string
   241  	err := WalkDiskDir(fs, "/file1.txt", func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error {
   242  		require.NoError(t, err)
   243  		visitedPaths = append(visitedPaths, path)
   244  		return nil
   245  	})
   246  
   247  	// we are providing a file path, not a directory
   248  	require.Error(t, err)
   249  	assert.Empty(t, visitedPaths)
   250  }