github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/analyzer/language/python/packaging/packaging_test.go (about)

     1  package packaging
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/devseccon/trivy/pkg/fanal/analyzer"
    12  	"github.com/devseccon/trivy/pkg/fanal/types"
    13  )
    14  
    15  func Test_packagingAnalyzer_Analyze(t *testing.T) {
    16  	tests := []struct {
    17  		name            string
    18  		inputFile       string
    19  		includeChecksum bool
    20  		want            *analyzer.AnalysisResult
    21  		wantErr         string
    22  	}{
    23  		{
    24  			name:      "egg zip",
    25  			inputFile: "testdata/kitchen-1.2.6-py2.7.egg",
    26  			want: &analyzer.AnalysisResult{
    27  				Applications: []types.Application{
    28  					{
    29  						Type:     types.PythonPkg,
    30  						FilePath: "testdata/kitchen-1.2.6-py2.7.egg",
    31  						Libraries: types.Packages{
    32  							{
    33  								Name:     "kitchen",
    34  								Version:  "1.2.6",
    35  								Licenses: []string{"LGPLv2+"},
    36  								FilePath: "testdata/kitchen-1.2.6-py2.7.egg",
    37  							},
    38  						},
    39  					},
    40  				},
    41  			},
    42  		},
    43  		{
    44  			name:            "egg-info",
    45  			inputFile:       "testdata/happy.egg-info/PKG-INFO",
    46  			includeChecksum: true,
    47  			want: &analyzer.AnalysisResult{
    48  				Applications: []types.Application{
    49  					{
    50  						Type:     types.PythonPkg,
    51  						FilePath: "testdata/happy.egg-info/PKG-INFO",
    52  						Libraries: types.Packages{
    53  							{
    54  								Name:     "distlib",
    55  								Version:  "0.3.1",
    56  								Licenses: []string{"Python license"},
    57  								FilePath: "testdata/happy.egg-info/PKG-INFO",
    58  								Digest:   "sha1:d9d89d8ed3b2b683767c96814c9c5d3e57ef2e1b",
    59  							},
    60  						},
    61  					},
    62  				},
    63  			},
    64  		},
    65  		{
    66  			name:      "egg-info license classifiers",
    67  			inputFile: "testdata/classifier-license.egg-info/PKG-INFO",
    68  			want: &analyzer.AnalysisResult{
    69  				Applications: []types.Application{
    70  					{
    71  						Type:     types.PythonPkg,
    72  						FilePath: "testdata/classifier-license.egg-info/PKG-INFO",
    73  						Libraries: types.Packages{
    74  							{
    75  								Name:     "setuptools",
    76  								Version:  "51.3.3",
    77  								Licenses: []string{"MIT License"},
    78  								FilePath: "testdata/classifier-license.egg-info/PKG-INFO",
    79  							},
    80  						},
    81  					},
    82  				},
    83  			},
    84  		},
    85  		{
    86  			name:      "dist-info license classifiers",
    87  			inputFile: "testdata/classifier-license.dist-info/METADATA",
    88  			want: &analyzer.AnalysisResult{
    89  				Applications: []types.Application{
    90  					{
    91  						Type:     types.PythonPkg,
    92  						FilePath: "testdata/classifier-license.dist-info/METADATA",
    93  						Libraries: types.Packages{
    94  							{
    95  								Name:     "setuptools",
    96  								Version:  "51.3.3",
    97  								Licenses: []string{"MIT License"},
    98  								FilePath: "testdata/classifier-license.dist-info/METADATA",
    99  							},
   100  						},
   101  					},
   102  				},
   103  			},
   104  		},
   105  		{
   106  			name:      "wheel",
   107  			inputFile: "testdata/happy.dist-info/METADATA",
   108  			want: &analyzer.AnalysisResult{
   109  				Applications: []types.Application{
   110  					{
   111  						Type:     types.PythonPkg,
   112  						FilePath: "testdata/happy.dist-info/METADATA",
   113  						Libraries: types.Packages{
   114  							{
   115  								Name:     "distlib",
   116  								Version:  "0.3.1",
   117  								Licenses: []string{"Python license"},
   118  								FilePath: "testdata/happy.dist-info/METADATA",
   119  							},
   120  						},
   121  					},
   122  				},
   123  			},
   124  		},
   125  		{
   126  			name:      "egg zip doesn't contain required files",
   127  			inputFile: "testdata/no-required-files.egg",
   128  			want:      nil,
   129  		},
   130  	}
   131  	for _, tt := range tests {
   132  		t.Run(tt.name, func(t *testing.T) {
   133  			f, err := os.Open(tt.inputFile)
   134  			require.NoError(t, err)
   135  			defer f.Close()
   136  
   137  			stat, err := f.Stat()
   138  			require.NoError(t, err)
   139  
   140  			a := packagingAnalyzer{}
   141  			ctx := context.Background()
   142  			got, err := a.Analyze(ctx, analyzer.AnalysisInput{
   143  				FilePath: tt.inputFile,
   144  				Info:     stat,
   145  				Content:  f,
   146  				Options:  analyzer.AnalysisOptions{FileChecksum: tt.includeChecksum},
   147  			})
   148  
   149  			if tt.wantErr != "" {
   150  				require.NotNil(t, err)
   151  				assert.Contains(t, err.Error(), tt.wantErr)
   152  				return
   153  			}
   154  			assert.NoError(t, err)
   155  			assert.Equal(t, tt.want, got)
   156  		})
   157  	}
   158  
   159  }
   160  
   161  func Test_packagingAnalyzer_Required(t *testing.T) {
   162  	tests := []struct {
   163  		name     string
   164  		filePath string
   165  		want     bool
   166  	}{
   167  		{
   168  			name:     "egg",
   169  			filePath: "python2.7/site-packages/cssutils-1.0-py2.7.egg/EGG-INFO/PKG-INFO",
   170  			want:     true,
   171  		},
   172  		{
   173  			name:     "egg-info",
   174  			filePath: "python3.8/site-packages/wrapt-1.12.1.egg-info",
   175  			want:     true,
   176  		},
   177  		{
   178  			name:     "egg-info PKG-INFO",
   179  			filePath: "python3.8/site-packages/wrapt-1.12.1.egg-info/PKG-INFO",
   180  			want:     true,
   181  		},
   182  		{
   183  			name:     "wheel",
   184  			filePath: "python3.8/site-packages/wrapt-1.12.1.dist-info/METADATA",
   185  			want:     true,
   186  		},
   187  		{
   188  			name:     "sad",
   189  			filePath: "random/PKG-INFO",
   190  			want:     false,
   191  		},
   192  	}
   193  	for _, tt := range tests {
   194  		t.Run(tt.name, func(t *testing.T) {
   195  			a := packagingAnalyzer{}
   196  			got := a.Required(tt.filePath, nil)
   197  			assert.Equal(t, tt.want, got)
   198  		})
   199  	}
   200  }