github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/file/cataloger/filemetadata/cataloger_test.go (about) 1 package filemetadata 2 3 import ( 4 "os" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 10 stereoscopeFile "github.com/anchore/stereoscope/pkg/file" 11 "github.com/anchore/stereoscope/pkg/imagetest" 12 "github.com/anchore/syft/syft/file" 13 "github.com/anchore/syft/syft/source" 14 ) 15 16 func TestFileMetadataCataloger(t *testing.T) { 17 testImage := "image-file-type-mix" 18 19 img := imagetest.GetFixtureImage(t, "docker-archive", testImage) 20 21 c := NewCataloger() 22 23 src, err := source.NewFromStereoscopeImageObject(img, testImage, nil) 24 require.NoError(t, err) 25 26 resolver, err := src.FileResolver(source.SquashedScope) 27 require.NoError(t, err) 28 29 actual, err := c.Catalog(resolver) 30 require.NoError(t, err) 31 32 tests := []struct { 33 path string 34 exists bool 35 expected file.Metadata 36 err bool 37 }{ 38 // note: it is difficult to add a hardlink-based test in a cross-platform way and is already covered well in stereoscope 39 { 40 path: "/file-1.txt", 41 exists: true, 42 expected: file.Metadata{ 43 FileInfo: stereoscopeFile.ManualInfo{ 44 NameValue: "file-1.txt", 45 ModeValue: 0644, 46 SizeValue: 7, 47 }, 48 Path: "/file-1.txt", 49 Type: stereoscopeFile.TypeRegular, 50 UserID: 1, 51 GroupID: 2, 52 MIMEType: "text/plain", 53 }, 54 }, 55 { 56 path: "/symlink-1", 57 exists: true, 58 expected: file.Metadata{ 59 Path: "/symlink-1", 60 FileInfo: stereoscopeFile.ManualInfo{ 61 NameValue: "symlink-1", 62 ModeValue: 0777 | os.ModeSymlink, 63 }, 64 Type: stereoscopeFile.TypeSymLink, 65 LinkDestination: "file-1.txt", 66 UserID: 0, 67 GroupID: 0, 68 MIMEType: "", 69 }, 70 }, 71 { 72 path: "/char-device-1", 73 exists: true, 74 expected: file.Metadata{ 75 Path: "/char-device-1", 76 FileInfo: stereoscopeFile.ManualInfo{ 77 NameValue: "char-device-1", 78 ModeValue: 0644 | os.ModeDevice | os.ModeCharDevice, 79 }, 80 Type: stereoscopeFile.TypeCharacterDevice, 81 UserID: 0, 82 GroupID: 0, 83 MIMEType: "", 84 }, 85 }, 86 { 87 path: "/block-device-1", 88 exists: true, 89 expected: file.Metadata{ 90 Path: "/block-device-1", 91 FileInfo: stereoscopeFile.ManualInfo{ 92 NameValue: "block-device-1", 93 ModeValue: 0644 | os.ModeDevice, 94 }, 95 Type: stereoscopeFile.TypeBlockDevice, 96 UserID: 0, 97 GroupID: 0, 98 MIMEType: "", 99 }, 100 }, 101 { 102 path: "/fifo-1", 103 exists: true, 104 expected: file.Metadata{ 105 Path: "/fifo-1", 106 FileInfo: stereoscopeFile.ManualInfo{ 107 NameValue: "fifo-1", 108 ModeValue: 0644 | os.ModeNamedPipe, 109 }, 110 Type: stereoscopeFile.TypeFIFO, 111 UserID: 0, 112 GroupID: 0, 113 MIMEType: "", 114 }, 115 }, 116 { 117 path: "/bin", 118 exists: true, 119 expected: file.Metadata{ 120 Path: "/bin", 121 FileInfo: stereoscopeFile.ManualInfo{ 122 NameValue: "bin", 123 ModeValue: 0755 | os.ModeDir, 124 }, 125 Type: stereoscopeFile.TypeDirectory, 126 UserID: 0, 127 GroupID: 0, 128 MIMEType: "", 129 }, 130 }, 131 } 132 133 for _, test := range tests { 134 t.Run(test.path, func(t *testing.T) { 135 _, ref, err := img.SquashedTree().File(stereoscopeFile.Path(test.path)) 136 require.NoError(t, err) 137 138 l := file.NewLocationFromImage(test.path, *ref.Reference, img) 139 140 if _, ok := actual[l.Coordinates]; ok { 141 // we're not interested in keeping the test fixtures up to date with the latest file modification times 142 // thus ModTime is not under test 143 fi := test.expected.FileInfo.(stereoscopeFile.ManualInfo) 144 fi.ModTimeValue = actual[l.Coordinates].ModTime() 145 test.expected.FileInfo = fi 146 } 147 148 assert.True(t, test.expected.Equal(actual[l.Coordinates])) 149 }) 150 } 151 152 } 153 154 func TestFileMetadataCataloger_GivenCoordinates(t *testing.T) { 155 testImage := "image-file-type-mix" 156 157 img := imagetest.GetFixtureImage(t, "docker-archive", testImage) 158 159 c := NewCataloger() 160 161 src, err := source.NewFromStereoscopeImageObject(img, testImage, nil) 162 require.NoError(t, err) 163 164 resolver, err := src.FileResolver(source.SquashedScope) 165 require.NoError(t, err) 166 167 tests := []struct { 168 path string 169 exists bool 170 expected file.Metadata 171 err bool 172 }{ 173 { 174 path: "/file-1.txt", 175 exists: true, 176 expected: file.Metadata{ 177 FileInfo: stereoscopeFile.ManualInfo{ 178 NameValue: "file-1.txt", 179 ModeValue: 0644, 180 SizeValue: 7, 181 }, 182 Path: "/file-1.txt", 183 Type: stereoscopeFile.TypeRegular, 184 UserID: 1, 185 GroupID: 2, 186 MIMEType: "text/plain", 187 }, 188 }, 189 } 190 191 for _, test := range tests { 192 t.Run(test.path, func(t *testing.T) { 193 _, ref, err := img.SquashedTree().File(stereoscopeFile.Path(test.path)) 194 require.NoError(t, err) 195 196 l := file.NewLocationFromImage(test.path, *ref.Reference, img) 197 198 // note: an important difference between this test and the previous is that this test is using a list 199 // of specific coordinates to catalog 200 actual, err := c.Catalog(resolver, l.Coordinates) 201 require.NoError(t, err) 202 require.Len(t, actual, 1) 203 204 if _, ok := actual[l.Coordinates]; ok { 205 // we're not interested in keeping the test fixtures up to date with the latest file modification times 206 // thus ModTime is not under test 207 fi := test.expected.FileInfo.(stereoscopeFile.ManualInfo) 208 fi.ModTimeValue = actual[l.Coordinates].ModTime() 209 test.expected.FileInfo = fi 210 } 211 212 assert.True(t, test.expected.Equal(actual[l.Coordinates])) 213 }) 214 } 215 216 }