github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/scanner/scan_test.go (about) 1 package scanner 2 3 import ( 4 "context" 5 "errors" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 12 "github.com/devseccon/trivy/pkg/clock" 13 "github.com/devseccon/trivy/pkg/fanal/artifact" 14 ftypes "github.com/devseccon/trivy/pkg/fanal/types" 15 "github.com/devseccon/trivy/pkg/types" 16 ) 17 18 func TestScanner_ScanArtifact(t *testing.T) { 19 type args struct { 20 options types.ScanOptions 21 } 22 clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC)) 23 tests := []struct { 24 name string 25 args args 26 inspectExpectation artifact.ArtifactInspectExpectation 27 scanExpectation DriverScanExpectation 28 want types.Report 29 wantErr string 30 }{ 31 { 32 name: "happy path", 33 args: args{ 34 options: types.ScanOptions{VulnType: []string{"os"}}, 35 }, 36 inspectExpectation: artifact.ArtifactInspectExpectation{ 37 Args: artifact.ArtifactInspectArgs{ 38 CtxAnything: true, 39 }, 40 Returns: artifact.ArtifactInspectReturns{ 41 Reference: ftypes.ArtifactReference{ 42 Name: "alpine:3.11", 43 Type: ftypes.ArtifactContainerImage, 44 ID: "sha256:e7d92cdc71feacf90708cb59182d0df1b911f8ae022d29e8e95d75ca6a99776a", 45 BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, 46 ImageMetadata: ftypes.ImageMetadata{ 47 ID: "sha256:e389ae58922402a7ded319e79f06ac428d05698d8e61ecbe88d2cf850e42651d", 48 DiffIDs: []string{"sha256:9a5d14f9f5503e55088666beef7e85a8d9625d4fa7418e2fe269e9c54bcb853c"}, 49 RepoTags: []string{"alpine:3.11"}, 50 RepoDigests: []string{"alpine@sha256:0bd0e9e03a022c3b0226667621da84fc9bf562a9056130424b5bfbd8bcb0397f"}, 51 }, 52 }, 53 }, 54 }, 55 scanExpectation: DriverScanExpectation{ 56 Args: DriverScanArgs{ 57 CtxAnything: true, 58 Target: "alpine:3.11", 59 ImageID: "sha256:e7d92cdc71feacf90708cb59182d0df1b911f8ae022d29e8e95d75ca6a99776a", 60 LayerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, 61 Options: types.ScanOptions{VulnType: []string{"os"}}, 62 }, 63 Returns: DriverScanReturns{ 64 Results: types.Results{ 65 { 66 Target: "alpine:3.11", 67 Vulnerabilities: []types.DetectedVulnerability{ 68 { 69 VulnerabilityID: "CVE-2019-9999", 70 PkgName: "vim", 71 InstalledVersion: "1.2.3", 72 FixedVersion: "1.2.4", 73 Layer: ftypes.Layer{ 74 Digest: "sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10", 75 DiffID: "sha256:b2a1a2d80bf0c747a4f6b0ca6af5eef23f043fcdb1ed4f3a3e750aef2dc68079", 76 }, 77 }, 78 }, 79 }, 80 { 81 Target: "node-app/package-lock.json", 82 Vulnerabilities: []types.DetectedVulnerability{ 83 { 84 VulnerabilityID: "CVE-2019-11358", 85 PkgName: "jquery", 86 InstalledVersion: "3.3.9", 87 FixedVersion: ">=3.4.0", 88 }, 89 }, 90 Type: "npm", 91 }, 92 }, 93 OsFound: ftypes.OS{ 94 Family: "alpine", 95 Name: "3.10", 96 Eosl: true, 97 }, 98 }, 99 }, 100 want: types.Report{ 101 SchemaVersion: 2, 102 CreatedAt: time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC), 103 ArtifactName: "alpine:3.11", 104 ArtifactType: ftypes.ArtifactContainerImage, 105 Metadata: types.Metadata{ 106 OS: &ftypes.OS{ 107 Family: "alpine", 108 Name: "3.10", 109 Eosl: true, 110 }, 111 ImageID: "sha256:e389ae58922402a7ded319e79f06ac428d05698d8e61ecbe88d2cf850e42651d", 112 DiffIDs: []string{"sha256:9a5d14f9f5503e55088666beef7e85a8d9625d4fa7418e2fe269e9c54bcb853c"}, 113 RepoTags: []string{"alpine:3.11"}, 114 RepoDigests: []string{"alpine@sha256:0bd0e9e03a022c3b0226667621da84fc9bf562a9056130424b5bfbd8bcb0397f"}, 115 }, 116 Results: types.Results{ 117 { 118 Target: "alpine:3.11", 119 Vulnerabilities: []types.DetectedVulnerability{ 120 { 121 VulnerabilityID: "CVE-2019-9999", 122 PkgName: "vim", 123 InstalledVersion: "1.2.3", 124 FixedVersion: "1.2.4", 125 Layer: ftypes.Layer{ 126 Digest: "sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10", 127 DiffID: "sha256:b2a1a2d80bf0c747a4f6b0ca6af5eef23f043fcdb1ed4f3a3e750aef2dc68079", 128 }, 129 }, 130 }, 131 }, 132 { 133 Target: "node-app/package-lock.json", 134 Vulnerabilities: []types.DetectedVulnerability{ 135 { 136 VulnerabilityID: "CVE-2019-11358", 137 PkgName: "jquery", 138 InstalledVersion: "3.3.9", 139 FixedVersion: ">=3.4.0", 140 }, 141 }, 142 Type: "npm", 143 }, 144 }, 145 }, 146 }, 147 { 148 name: "sad path: AnalyzerAnalyze returns an error", 149 args: args{ 150 options: types.ScanOptions{VulnType: []string{"os"}}, 151 }, 152 inspectExpectation: artifact.ArtifactInspectExpectation{ 153 Args: artifact.ArtifactInspectArgs{ 154 CtxAnything: true, 155 }, 156 Returns: artifact.ArtifactInspectReturns{ 157 Err: errors.New("error"), 158 }, 159 }, 160 wantErr: "failed analysis", 161 }, 162 { 163 name: "sad path: Scan returns an error", 164 args: args{ 165 options: types.ScanOptions{VulnType: []string{"os"}}, 166 }, 167 inspectExpectation: artifact.ArtifactInspectExpectation{ 168 Args: artifact.ArtifactInspectArgs{ 169 CtxAnything: true, 170 }, 171 Returns: artifact.ArtifactInspectReturns{ 172 Reference: ftypes.ArtifactReference{ 173 Name: "alpine:3.11", 174 ID: "sha256:e7d92cdc71feacf90708cb59182d0df1b911f8ae022d29e8e95d75ca6a99776a", 175 BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, 176 }, 177 }, 178 }, 179 scanExpectation: DriverScanExpectation{ 180 Args: DriverScanArgs{ 181 CtxAnything: true, 182 Target: "alpine:3.11", 183 ImageID: "sha256:e7d92cdc71feacf90708cb59182d0df1b911f8ae022d29e8e95d75ca6a99776a", 184 LayerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, 185 Options: types.ScanOptions{VulnType: []string{"os"}}, 186 }, 187 Returns: DriverScanReturns{ 188 Err: errors.New("error"), 189 }, 190 }, 191 wantErr: "scan failed", 192 }, 193 } 194 for _, tt := range tests { 195 t.Run(tt.name, func(t *testing.T) { 196 d := new(MockDriver) 197 d.ApplyScanExpectation(tt.scanExpectation) 198 199 mockArtifact := new(artifact.MockArtifact) 200 mockArtifact.ApplyInspectExpectation(tt.inspectExpectation) 201 202 s := NewScanner(d, mockArtifact) 203 got, err := s.ScanArtifact(context.Background(), tt.args.options) 204 if tt.wantErr != "" { 205 require.NotNil(t, err, tt.name) 206 require.Contains(t, err.Error(), tt.wantErr, tt.name) 207 return 208 } else { 209 require.NoError(t, err, tt.name) 210 } 211 212 assert.Equal(t, tt.want, got, tt.name) 213 }) 214 } 215 }