github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/pkg/cataloger/generic/cataloger_test.go (about) 1 package generic 2 3 import ( 4 "fmt" 5 "io" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 11 "github.com/anchore/syft/syft/artifact" 12 "github.com/anchore/syft/syft/file" 13 "github.com/anchore/syft/syft/pkg" 14 ) 15 16 func Test_WithParserByGlobColocation(t *testing.T) { 17 matchedFilesPaths := make(map[string]bool) 18 parser := func(resolver file.Resolver, env *Environment, readers []file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 19 var packages []pkg.Package 20 var relationships []artifact.Relationship 21 22 for _, reader := range readers { 23 matchedFilesPaths[reader.AccessPath()] = true 24 } 25 return packages, relationships, nil 26 } 27 28 upstream := "colocation-cataloger" 29 expectedCollocatedPaths := []string{ 30 "test-fixtures/pkg-json/package.json", 31 "test-fixtures/pkg-json/package-lock.json", 32 } 33 34 resolver := file.NewMockResolverForPaths(expectedCollocatedPaths...) 35 36 cataloger := NewGroupedCataloger(upstream). 37 WithParserByGlobColocation(parser, "**/package-lock.json", []string{"**/package.json", "**/package-lock.json"}) 38 39 _, _, err := cataloger.Catalog(resolver) 40 assert.NoError(t, err) 41 42 for path := range matchedFilesPaths { 43 t.Logf("Matched file path: %s", path) // Log each matched file 44 } 45 46 // Assert that the expected files were matched 47 require.True(t, matchedFilesPaths["test-fixtures/pkg-json/package.json"]) 48 require.True(t, matchedFilesPaths["test-fixtures/pkg-json/package-lock.json"]) 49 } 50 51 func Test_Cataloger(t *testing.T) { 52 allParsedPaths := make(map[string]bool) 53 parser := func(resolver file.Resolver, env *Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 54 allParsedPaths[reader.AccessPath()] = true 55 contents, err := io.ReadAll(reader) 56 require.NoError(t, err) 57 58 if len(contents) == 0 { 59 return nil, nil, nil 60 } 61 62 p := pkg.Package{ 63 Name: string(contents), 64 Locations: file.NewLocationSet(reader.Location), 65 } 66 r := artifact.Relationship{ 67 From: p, 68 To: p, 69 Type: artifact.ContainsRelationship, 70 } 71 72 return []pkg.Package{p}, []artifact.Relationship{r}, nil 73 } 74 75 upstream := "some-other-cataloger" 76 77 expectedSelection := []string{"test-fixtures/last/path.txt", "test-fixtures/another-path.txt", "test-fixtures/a-path.txt", "test-fixtures/empty.txt"} 78 resolver := file.NewMockResolverForPaths(expectedSelection...) 79 cataloger := NewCataloger(upstream). 80 WithParserByPath(parser, "test-fixtures/another-path.txt", "test-fixtures/last/path.txt"). 81 WithParserByGlobs(parser, "**/a-path.txt", "**/empty.txt") 82 83 actualPkgs, relationships, err := cataloger.Catalog(resolver) 84 assert.NoError(t, err) 85 86 expectedPkgs := make(map[string]pkg.Package) 87 for _, path := range expectedSelection { 88 require.True(t, allParsedPaths[path]) 89 if path == "test-fixtures/empty.txt" { 90 continue // note: empty.txt won't become a package 91 } 92 expectedPkgs[path] = pkg.Package{ 93 FoundBy: upstream, 94 Name: fmt.Sprintf("%s file contents!", path), 95 } 96 } 97 98 assert.Len(t, allParsedPaths, len(expectedSelection)) 99 assert.Len(t, actualPkgs, len(expectedPkgs)) 100 assert.Len(t, relationships, len(actualPkgs)) 101 102 for _, p := range actualPkgs { 103 ls := p.Locations.ToSlice() 104 require.NotEmpty(t, ls) 105 ref := ls[0] 106 exP, ok := expectedPkgs[ref.RealPath] 107 if !ok { 108 t.Errorf("missing expected pkg: ref=%+v", ref) 109 continue 110 } 111 112 // assigned by the generic cataloger 113 if p.FoundBy != exP.FoundBy { 114 t.Errorf("bad upstream: %s", p.FoundBy) 115 } 116 117 // assigned by the parser 118 if exP.Name != p.Name { 119 t.Errorf("bad contents mapping: %+v", p.Locations) 120 } 121 } 122 }