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 }