github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/internal/licenses/find_licenses_test.go (about)

     1  package licenses
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"github.com/anchore/syft/internal/licenses"
    10  	"github.com/anchore/syft/syft/file"
    11  	"github.com/anchore/syft/syft/internal/fileresolver"
    12  	"github.com/anchore/syft/syft/pkg"
    13  )
    14  
    15  // scanner is used by all tests
    16  var scanner = getScanner()
    17  
    18  func Test_FindRelativeLicenses(t *testing.T) {
    19  	resolver := fileresolver.NewFromUnindexedDirectory("testdata")
    20  	sourceTxtResolved, err := resolver.FilesByPath("source.txt")
    21  	require.NoError(t, err)
    22  
    23  	sourceTxt := file.NewLocationSet(sourceTxtResolved[0].WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation))
    24  
    25  	tests := []struct {
    26  		name     string
    27  		resolver file.Resolver
    28  		p        pkg.Package
    29  		expected pkg.LicenseSet
    30  	}{
    31  		{
    32  			name:     "existing license",
    33  			resolver: resolver,
    34  			p: pkg.Package{
    35  				Locations: sourceTxt,
    36  				Licenses:  pkg.NewLicenseSet(pkg.NewLicense("GPL-2.0")),
    37  			},
    38  			expected: pkg.NewLicenseSet(pkg.NewLicense("GPL-2.0")),
    39  		},
    40  		{
    41  			name:     "no licenses",
    42  			resolver: fileresolver.Empty{},
    43  			p: pkg.Package{
    44  				Locations: sourceTxt,
    45  			},
    46  			expected: pkg.NewLicenseSet(),
    47  		},
    48  		{
    49  			name:     "found relative license",
    50  			resolver: resolver,
    51  			p: pkg.Package{
    52  				Locations: sourceTxt,
    53  			},
    54  			expected: pkg.NewLicenseSet(pkg.NewLicense("MIT")),
    55  		},
    56  	}
    57  
    58  	ctx := context.TODO()
    59  	ctx = licenses.SetContextLicenseScanner(ctx, scanner)
    60  
    61  	for _, tt := range tests {
    62  		t.Run(tt.name, func(t *testing.T) {
    63  			got := RelativeToPackage(ctx, tt.resolver, tt.p)
    64  			require.Equal(t, licenseNames(tt.expected.ToSlice()), licenseNames(got.Licenses.ToSlice()))
    65  		})
    66  	}
    67  }
    68  
    69  func Test_Finders(t *testing.T) {
    70  	resolver := fileresolver.NewFromUnindexedDirectory("testdata")
    71  
    72  	// prepare context with license scanner
    73  	ctx := context.TODO()
    74  	ctx = licenses.SetContextLicenseScanner(ctx, scanner)
    75  
    76  	// resolve known files
    77  	licenseLocs, err := resolver.FilesByPath("LICENSE")
    78  	require.NoError(t, err)
    79  	require.NotEmpty(t, licenseLocs)
    80  	licenseLoc := licenseLocs[0]
    81  
    82  	sourceLocs, err := resolver.FilesByPath("source.txt")
    83  	require.NoError(t, err)
    84  	require.NotEmpty(t, sourceLocs)
    85  	sourceLoc := sourceLocs[0]
    86  
    87  	tests := []struct {
    88  		name     string
    89  		finder   func(t *testing.T) []pkg.License
    90  		expected []string
    91  	}{
    92  		{
    93  			name: "FindAtLocations finds LICENSE content",
    94  			finder: func(t *testing.T) []pkg.License {
    95  				return FindAtLocations(ctx, resolver, licenseLoc)
    96  			},
    97  			expected: []string{"MIT"},
    98  		},
    99  		{
   100  			name: "FindAtLocations with empty resolver returns none",
   101  			finder: func(t *testing.T) []pkg.License {
   102  				return FindAtLocations(ctx, fileresolver.Empty{}, licenseLoc)
   103  			},
   104  		},
   105  		{
   106  			name: "FindAtPaths finds LICENSE by path",
   107  			finder: func(t *testing.T) []pkg.License {
   108  				return FindAtPaths(ctx, resolver, "LICENSE")
   109  			},
   110  			expected: []string{"MIT"},
   111  		},
   112  		{
   113  			name: "FindInDirs finds LICENSE in directory",
   114  			finder: func(t *testing.T) []pkg.License {
   115  				return FindInDirs(ctx, resolver, ".")
   116  			},
   117  			expected: []string{"MIT"},
   118  		},
   119  		{
   120  			name: "FindRelativeToLocations finds LICENSE relative to source.txt",
   121  			finder: func(t *testing.T) []pkg.License {
   122  				return FindRelativeToLocations(ctx, resolver, sourceLoc)
   123  			},
   124  			expected: []string{"MIT"},
   125  		},
   126  		{
   127  			name: "FindByGlob finds LICENSE with glob",
   128  			finder: func(t *testing.T) []pkg.License {
   129  				return FindByGlob(ctx, resolver, "*")
   130  			},
   131  			expected: []string{"MIT"},
   132  		},
   133  		{
   134  			name: "FindByGlob finds LICENSE with recursive glob",
   135  			finder: func(t *testing.T) []pkg.License {
   136  				return FindByGlob(ctx, resolver, "**/*")
   137  			},
   138  			expected: []string{"MIT"},
   139  		},
   140  		{
   141  			name: "NewFromValues with locations returns license values",
   142  			finder: func(t *testing.T) []pkg.License {
   143  				return NewFromValues(ctx, []file.Location{licenseLoc}, "MIT")
   144  			},
   145  			expected: []string{"MIT"},
   146  		},
   147  	}
   148  
   149  	for _, tt := range tests {
   150  		t.Run(tt.name, func(t *testing.T) {
   151  			got := tt.finder(t)
   152  			require.Equal(t, tt.expected, licenseNames(got))
   153  		})
   154  	}
   155  }
   156  
   157  func licenseNames(slice []pkg.License) []string {
   158  	var out []string
   159  	for _, l := range slice {
   160  		out = append(out, l.SPDXExpression)
   161  	}
   162  	return out
   163  }
   164  
   165  func getScanner() licenses.Scanner {
   166  	s, err := licenses.NewDefaultScanner()
   167  	if err != nil {
   168  		panic(err)
   169  	}
   170  	return s
   171  }