github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/analyzer/language/golang/mod/mod_test.go (about)

     1  package mod
     2  
     3  import (
     4  	"context"
     5  	"path/filepath"
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/devseccon/trivy/pkg/fanal/analyzer"
    13  	"github.com/devseccon/trivy/pkg/fanal/types"
    14  	"github.com/devseccon/trivy/pkg/mapfs"
    15  )
    16  
    17  func Test_gomodAnalyzer_Analyze(t *testing.T) {
    18  	tests := []struct {
    19  		name  string
    20  		files []string
    21  		want  *analyzer.AnalysisResult
    22  	}{
    23  		{
    24  			name: "happy",
    25  			files: []string{
    26  				"testdata/happy/mod",
    27  				"testdata/happy/sum",
    28  			},
    29  			want: &analyzer.AnalysisResult{
    30  				Applications: []types.Application{
    31  					{
    32  						Type:     types.GoModule,
    33  						FilePath: "go.mod",
    34  						Libraries: types.Packages{
    35  							{
    36  								ID:      "github.com/aquasecurity/go-dep-parser@v0.0.0-20220406074731-71021a481237",
    37  								Name:    "github.com/aquasecurity/go-dep-parser",
    38  								Version: "0.0.0-20220406074731-71021a481237",
    39  								Licenses: []string{
    40  									"MIT",
    41  								},
    42  								DependsOn: []string{
    43  									"golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
    44  								},
    45  							},
    46  							{
    47  								ID:       "golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
    48  								Name:     "golang.org/x/xerrors",
    49  								Version:  "0.0.0-20200804184101-5ec99f83aff1",
    50  								Indirect: true,
    51  							},
    52  						},
    53  					},
    54  				},
    55  			},
    56  		},
    57  		{
    58  			name: "wrong go.mod from `pkg`",
    59  			files: []string{
    60  				"testdata/wrong-gomod-in-pkg/mod",
    61  			},
    62  			want: &analyzer.AnalysisResult{
    63  				Applications: []types.Application{
    64  					{
    65  						Type:     types.GoModule,
    66  						FilePath: "go.mod",
    67  						Libraries: types.Packages{
    68  							{
    69  								ID:      "github.com/sad/sad@v0.0.1",
    70  								Name:    "github.com/sad/sad",
    71  								Version: "0.0.1",
    72  							},
    73  						},
    74  					},
    75  				},
    76  			},
    77  		},
    78  		{
    79  			name: "less than 1.17",
    80  			files: []string{
    81  				"testdata/merge/mod",
    82  				"testdata/merge/sum",
    83  			},
    84  			want: &analyzer.AnalysisResult{
    85  				Applications: []types.Application{
    86  					{
    87  						Type:     types.GoModule,
    88  						FilePath: "go.mod",
    89  						Libraries: types.Packages{
    90  							{
    91  								ID:      "github.com/aquasecurity/go-dep-parser@v0.0.0-20230219131432-590b1dfb6edd",
    92  								Name:    "github.com/aquasecurity/go-dep-parser",
    93  								Version: "0.0.0-20230219131432-590b1dfb6edd",
    94  								DependsOn: []string{
    95  									"github.com/BurntSushi/toml@v0.3.1",
    96  								},
    97  							},
    98  							{
    99  								ID:       "github.com/BurntSushi/toml@v0.3.1",
   100  								Name:     "github.com/BurntSushi/toml",
   101  								Version:  "0.3.1",
   102  								Indirect: true,
   103  								Licenses: []string{
   104  									"MIT",
   105  								},
   106  							},
   107  						},
   108  					},
   109  				},
   110  			},
   111  		},
   112  		{
   113  			name: "no go.sum",
   114  			files: []string{
   115  				"testdata/merge/mod",
   116  			},
   117  			want: &analyzer.AnalysisResult{
   118  				Applications: []types.Application{
   119  					{
   120  						Type:     types.GoModule,
   121  						FilePath: "go.mod",
   122  						Libraries: types.Packages{
   123  							{
   124  								ID:        "github.com/aquasecurity/go-dep-parser@v0.0.0-20230219131432-590b1dfb6edd",
   125  								Name:      "github.com/aquasecurity/go-dep-parser",
   126  								Version:   "0.0.0-20230219131432-590b1dfb6edd",
   127  								DependsOn: []string{},
   128  							},
   129  						},
   130  					},
   131  				},
   132  			},
   133  		},
   134  		{
   135  			name: "sad go.mod",
   136  			files: []string{
   137  				"testdata/sad/mod",
   138  			},
   139  			want: &analyzer.AnalysisResult{},
   140  		},
   141  	}
   142  	for _, tt := range tests {
   143  		t.Setenv("GOPATH", "testdata")
   144  		t.Run(tt.name, func(t *testing.T) {
   145  			a, err := newGoModAnalyzer(analyzer.AnalyzerOptions{})
   146  			require.NoError(t, err)
   147  
   148  			mfs := mapfs.New()
   149  			for _, file := range tt.files {
   150  				// Since broken go.mod files bothers IDE, we should use other file names than "go.mod" and "go.sum".
   151  				if filepath.Base(file) == "mod" {
   152  					require.NoError(t, mfs.WriteFile("go.mod", file))
   153  				} else if filepath.Base(file) == "sum" {
   154  					require.NoError(t, mfs.WriteFile("go.sum", file))
   155  				}
   156  			}
   157  
   158  			ctx := context.Background()
   159  			got, err := a.PostAnalyze(ctx, analyzer.PostAnalysisInput{
   160  				FS: mfs,
   161  			})
   162  			assert.NoError(t, err)
   163  
   164  			if len(got.Applications) > 0 {
   165  				sort.Sort(got.Applications[0].Libraries)
   166  				sort.Sort(tt.want.Applications[0].Libraries)
   167  			}
   168  			assert.NoError(t, err)
   169  			assert.Equal(t, tt.want, got)
   170  		})
   171  	}
   172  }
   173  
   174  func Test_gomodAnalyzer_Required(t *testing.T) {
   175  	tests := []struct {
   176  		name     string
   177  		filePath string
   178  		want     bool
   179  	}{
   180  		{
   181  			name:     "go.mod",
   182  			filePath: "test/go.mod",
   183  			want:     true,
   184  		},
   185  		{
   186  			name:     "go.sum",
   187  			filePath: "test/foo/go.sum",
   188  			want:     true,
   189  		},
   190  		{
   191  			name:     "sad",
   192  			filePath: "a/b/c/d/test.sum",
   193  			want:     false,
   194  		},
   195  	}
   196  	for _, tt := range tests {
   197  		t.Run(tt.name, func(t *testing.T) {
   198  			a := gomodAnalyzer{}
   199  			got := a.Required(tt.filePath, nil)
   200  			assert.Equal(t, tt.want, got)
   201  		})
   202  	}
   203  }