github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/cataloger/binary/classifier_test.go (about)

     1  package binary
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"github.com/anchore/packageurl-go"
    10  	"github.com/anchore/syft/syft/cpe"
    11  	"github.com/anchore/syft/syft/file"
    12  )
    13  
    14  func Test_ClassifierCPEs(t *testing.T) {
    15  	tests := []struct {
    16  		name       string
    17  		fixture    string
    18  		classifier Classifier
    19  		cpes       []string
    20  	}{
    21  		{
    22  			name:    "no CPEs",
    23  			fixture: "test-fixtures/version.txt",
    24  			classifier: Classifier{
    25  				Package:         "some-app",
    26  				FileGlob:        "**/version.txt",
    27  				EvidenceMatcher: FileContentsVersionMatcher(`(?m)my-verison:(?P<version>[0-9.]+)`),
    28  				CPEs:            []cpe.CPE{},
    29  			},
    30  			cpes: nil,
    31  		},
    32  		{
    33  			name:    "one Attributes",
    34  			fixture: "test-fixtures/version.txt",
    35  			classifier: Classifier{
    36  				Package:         "some-app",
    37  				FileGlob:        "**/version.txt",
    38  				EvidenceMatcher: FileContentsVersionMatcher(`(?m)my-verison:(?P<version>[0-9.]+)`),
    39  				CPEs: []cpe.CPE{
    40  					cpe.Must("cpe:2.3:a:some:app:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
    41  				},
    42  			},
    43  			cpes: []string{
    44  				"cpe:2.3:a:some:app:1.8:*:*:*:*:*:*:*",
    45  			},
    46  		},
    47  		{
    48  			name:    "multiple CPEs",
    49  			fixture: "test-fixtures/version.txt",
    50  			classifier: Classifier{
    51  				Package:         "some-app",
    52  				FileGlob:        "**/version.txt",
    53  				EvidenceMatcher: FileContentsVersionMatcher(`(?m)my-verison:(?P<version>[0-9.]+)`),
    54  				CPEs: []cpe.CPE{
    55  					cpe.Must("cpe:2.3:a:some:app:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
    56  					cpe.Must("cpe:2.3:a:some:apps:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
    57  				},
    58  			},
    59  			cpes: []string{
    60  				"cpe:2.3:a:some:app:1.8:*:*:*:*:*:*:*",
    61  				"cpe:2.3:a:some:apps:1.8:*:*:*:*:*:*:*",
    62  			},
    63  		},
    64  	}
    65  
    66  	for _, test := range tests {
    67  		t.Run(test.name, func(t *testing.T) {
    68  			resolver := file.NewMockResolverForPaths(test.fixture)
    69  			ls, err := resolver.FilesByPath(test.fixture)
    70  			require.NoError(t, err)
    71  			require.Len(t, ls, 1)
    72  
    73  			pkgs, err := test.classifier.EvidenceMatcher(resolver, test.classifier, ls[0])
    74  			require.NoError(t, err)
    75  
    76  			require.Len(t, pkgs, 1)
    77  
    78  			p := pkgs[0]
    79  
    80  			var cpes []string
    81  			for _, c := range p.CPEs {
    82  				cpes = append(cpes, c.Attributes.String())
    83  			}
    84  			require.Equal(t, test.cpes, cpes)
    85  		})
    86  	}
    87  }
    88  
    89  func TestClassifier_MarshalJSON(t *testing.T) {
    90  
    91  	tests := []struct {
    92  		name       string
    93  		classifier Classifier
    94  		want       string
    95  		wantErr    assert.ErrorAssertionFunc
    96  	}{
    97  		{
    98  			name: "go case",
    99  			classifier: Classifier{
   100  				Class:           "class",
   101  				FileGlob:        "glob",
   102  				EvidenceMatcher: FileContentsVersionMatcher(".thing"),
   103  				Package:         "pkg",
   104  				PURL: packageurl.PackageURL{
   105  					Type:       "type",
   106  					Namespace:  "namespace",
   107  					Name:       "name",
   108  					Version:    "version",
   109  					Qualifiers: nil,
   110  					Subpath:    "subpath",
   111  				},
   112  				CPEs: []cpe.CPE{cpe.Must("cpe:2.3:a:some:app:*:*:*:*:*:*:*:*", cpe.GeneratedSource)},
   113  			},
   114  			want: `{"class":"class","fileGlob":"glob","package":"pkg","purl":"pkg:type/namespace/name@version#subpath","cpes":["cpe:2.3:a:some:app:*:*:*:*:*:*:*:*"]}`,
   115  		},
   116  	}
   117  	for _, tt := range tests {
   118  		t.Run(tt.name, func(t *testing.T) {
   119  			if tt.wantErr == nil {
   120  				tt.wantErr = assert.NoError
   121  			}
   122  			cfg := tt.classifier
   123  			got, err := cfg.MarshalJSON()
   124  			if !tt.wantErr(t, err) {
   125  				return
   126  			}
   127  			assert.Equal(t, tt.want, string(got))
   128  		})
   129  	}
   130  }