github.com/xgoffin/jenkins-library@v1.154.0/cmd/detectExecuteScan_test.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "net/http" 9 "os" 10 "path/filepath" 11 "testing" 12 13 bd "github.com/SAP/jenkins-library/pkg/blackduck" 14 piperGithub "github.com/SAP/jenkins-library/pkg/github" 15 piperhttp "github.com/SAP/jenkins-library/pkg/http" 16 "github.com/SAP/jenkins-library/pkg/mock" 17 18 "github.com/stretchr/testify/assert" 19 ) 20 21 type detectTestUtilsBundle struct { 22 expectedError error 23 downloadedFiles map[string]string // src, dest 24 *mock.ShellMockRunner 25 *mock.FilesMock 26 customEnv []string 27 } 28 29 type httpMockClient struct { 30 responseBodyForURL map[string]string 31 errorMessageForURL map[string]string 32 header map[string]http.Header 33 } 34 35 func (c *httpMockClient) SetOptions(opts piperhttp.ClientOptions) {} 36 func (c *httpMockClient) SendRequest(method, url string, body io.Reader, header http.Header, cookies []*http.Cookie) (*http.Response, error) { 37 c.header[url] = header 38 response := http.Response{ 39 StatusCode: 200, 40 Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), 41 } 42 43 if c.errorMessageForURL[url] != "" { 44 response.StatusCode = 400 45 return &response, fmt.Errorf(c.errorMessageForURL[url]) 46 } 47 48 if c.responseBodyForURL[url] != "" { 49 response.Body = ioutil.NopCloser(bytes.NewReader([]byte(c.responseBodyForURL[url]))) 50 return &response, nil 51 } 52 53 return &response, nil 54 } 55 56 func newBlackduckMockSystem(config detectExecuteScanOptions) blackduckSystem { 57 myTestClient := httpMockClient{ 58 responseBodyForURL: map[string]string{ 59 "https://my.blackduck.system/api/tokens/authenticate": authContent, 60 "https://my.blackduck.system/api/projects?q=name%3ASHC-PiperTest": projectContent, 61 "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions": projectVersionContent, 62 "https://my.blackduck.system/api/projects/5ca86e11/versions/a6c94786/components?limit=999&offset=0": componentsContent, 63 "https://my.blackduck.system/api/projects/5ca86e11/versions/a6c94786/vunlerable-bom-components?limit=999&offset=0": vulnerabilitiesContent, 64 "https://my.blackduck.system/api/projects/5ca86e11/versions/a6c94786/components?filter=policyCategory%3Alicense&limit=999&offset=0": componentsContent, 65 "https://my.blackduck.system/api/projects/5ca86e11/versions/a6c94786/policy-status": policyStatusContent, 66 }, 67 header: map[string]http.Header{}, 68 } 69 sys := blackduckSystem{ 70 Client: bd.NewClient(config.Token, config.ServerURL, &myTestClient), 71 } 72 return sys 73 } 74 75 const ( 76 authContent = `{ 77 "bearerToken":"bearerTestToken", 78 "expiresInMilliseconds":7199997 79 }` 80 projectContent = `{ 81 "totalCount": 1, 82 "items": [ 83 { 84 "name": "SHC-PiperTest", 85 "_meta": { 86 "href": "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf", 87 "links": [ 88 { 89 "rel": "versions", 90 "href": "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions" 91 } 92 ] 93 } 94 } 95 ] 96 }` 97 projectVersionContent = `{ 98 "totalCount": 1, 99 "items": [ 100 { 101 "versionName": "1.0", 102 "_meta": { 103 "href": "https://my.blackduck.system/api/projects/5ca86e11-1983-4e7b-97d4-eb1a0aeffbbf/versions/a6c94786-0ee6-414f-9054-90d549c69c36", 104 "links": [ 105 { 106 "rel": "components", 107 "href": "https://my.blackduck.system/api/projects/5ca86e11/versions/a6c94786/components" 108 }, 109 { 110 "rel": "vulnerable-components", 111 "href": "https://my.blackduck.system/api/projects/5ca86e11/versions/a6c94786/vunlerable-bom-components" 112 }, 113 { 114 "rel": "policy-status", 115 "href": "https://my.blackduck.system/api/projects/5ca86e11/versions/a6c94786/policy-status" 116 } 117 ] 118 } 119 } 120 ] 121 }` 122 componentsContent = `{ 123 "totalCount": 2, 124 "items" : [ 125 { 126 "componentName": "Spring Framework", 127 "componentVersionName": "5.3.9", 128 "policyStatus": "IN_VIOLATION" 129 }, { 130 "componentName": "Apache Tomcat", 131 "componentVersionName": "9.0.52", 132 "policyStatus": "IN_VIOLATION" 133 } 134 ] 135 }` 136 vulnerabilitiesContent = `{ 137 "totalCount": 1, 138 "items": [ 139 { 140 "componentName": "Spring Framework", 141 "componentVersionName": "5.3.2", 142 "vulnerabilityWithRemediation" : { 143 "vulnerabilityName" : "BDSA-2019-2021", 144 "baseScore" : 7.5, 145 "overallScore" : 7.5, 146 "severity" : "HIGH", 147 "remediationStatus" : "IGNORED", 148 "description" : "description" 149 } 150 } 151 ] 152 }` 153 policyStatusContent = `{ 154 "overallStatus": "IN_VIOLATION", 155 "componentVersionPolicyViolationDetails": { 156 "name": "IN_VIOLATION", 157 "severityLevels": [{"name":"BLOCKER", "value": 1}, {"name": "CRITICAL", "value": 1}] 158 } 159 }` 160 ) 161 162 func (c *detectTestUtilsBundle) RunExecutable(string, ...string) error { 163 panic("not expected to be called in test") 164 } 165 166 func (c *detectTestUtilsBundle) SetOptions(piperhttp.ClientOptions) { 167 168 } 169 170 func (c *detectTestUtilsBundle) GetOsEnv() []string { 171 return c.customEnv 172 } 173 174 func (c *detectTestUtilsBundle) DownloadFile(url, filename string, _ http.Header, _ []*http.Cookie) error { 175 176 if c.expectedError != nil { 177 return c.expectedError 178 } 179 180 if c.downloadedFiles == nil { 181 c.downloadedFiles = make(map[string]string) 182 } 183 c.downloadedFiles[url] = filename 184 return nil 185 } 186 187 func (w *detectTestUtilsBundle) CreateIssue(ghCreateIssueOptions *piperGithub.CreateIssueOptions) error { 188 return nil 189 } 190 191 func newDetectTestUtilsBundle() *detectTestUtilsBundle { 192 utilsBundle := detectTestUtilsBundle{ 193 ShellMockRunner: &mock.ShellMockRunner{}, 194 FilesMock: &mock.FilesMock{}, 195 } 196 return &utilsBundle 197 } 198 199 func TestRunDetect(t *testing.T) { 200 t.Parallel() 201 t.Run("success case", func(t *testing.T) { 202 t.Parallel() 203 utilsMock := newDetectTestUtilsBundle() 204 utilsMock.AddFile("detect.sh", []byte("")) 205 err := runDetect(detectExecuteScanOptions{}, utilsMock, &detectExecuteScanInflux{}) 206 207 assert.Equal(t, utilsMock.downloadedFiles["https://detect.synopsys.com/detect7.sh"], "detect.sh") 208 assert.True(t, utilsMock.HasRemovedFile("detect.sh")) 209 assert.NoError(t, err) 210 assert.Equal(t, ".", utilsMock.Dir, "Wrong execution directory used") 211 assert.Equal(t, "/bin/bash", utilsMock.Shell[0], "Bash shell expected") 212 expectedScript := "./detect.sh --blackduck.url= --blackduck.api.token= \"--detect.project.name=''\" \"--detect.project.version.name=''\" \"--detect.code.location.name=''\" --detect.source.path='.'" 213 assert.Equal(t, expectedScript, utilsMock.Calls[0]) 214 }) 215 216 t.Run("success case detect 6", func(t *testing.T) { 217 t.Parallel() 218 utilsMock := newDetectTestUtilsBundle() 219 utilsMock.AddFile("detect.sh", []byte("")) 220 options := detectExecuteScanOptions{ 221 CustomEnvironmentVariables: []string{"DETECT_LATEST_RELEASE_VERSION=6.8.0"}, 222 } 223 err := runDetect(options, utilsMock, &detectExecuteScanInflux{}) 224 225 assert.Equal(t, utilsMock.downloadedFiles["https://detect.synopsys.com/detect.sh"], "detect.sh") 226 assert.True(t, utilsMock.HasRemovedFile("detect.sh")) 227 assert.NoError(t, err) 228 assert.Equal(t, ".", utilsMock.Dir, "Wrong execution directory used") 229 assert.Equal(t, "/bin/bash", utilsMock.Shell[0], "Bash shell expected") 230 expectedScript := "./detect.sh --blackduck.url= --blackduck.api.token= \"--detect.project.name=''\" \"--detect.project.version.name=''\" \"--detect.code.location.name=''\" --detect.source.path='.'" 231 assert.Equal(t, expectedScript, utilsMock.Calls[0]) 232 }) 233 234 t.Run("success case detect 6 from OS env", func(t *testing.T) { 235 t.Parallel() 236 utilsMock := newDetectTestUtilsBundle() 237 utilsMock.AddFile("detect.sh", []byte("")) 238 utilsMock.customEnv = []string{"DETECT_LATEST_RELEASE_VERSION=6.8.0"} 239 err := runDetect(detectExecuteScanOptions{}, utilsMock, &detectExecuteScanInflux{}) 240 241 assert.Equal(t, utilsMock.downloadedFiles["https://detect.synopsys.com/detect.sh"], "detect.sh") 242 assert.True(t, utilsMock.HasRemovedFile("detect.sh")) 243 assert.NoError(t, err) 244 assert.Equal(t, ".", utilsMock.Dir, "Wrong execution directory used") 245 assert.Equal(t, "/bin/bash", utilsMock.Shell[0], "Bash shell expected") 246 expectedScript := "./detect.sh --blackduck.url= --blackduck.api.token= \"--detect.project.name=''\" \"--detect.project.version.name=''\" \"--detect.code.location.name=''\" --detect.source.path='.'" 247 assert.Equal(t, expectedScript, utilsMock.Calls[0]) 248 }) 249 250 t.Run("failure case", func(t *testing.T) { 251 t.Parallel() 252 utilsMock := newDetectTestUtilsBundle() 253 utilsMock.ShouldFailOnCommand = map[string]error{"./detect.sh --blackduck.url= --blackduck.api.token= \"--detect.project.name=''\" \"--detect.project.version.name=''\" \"--detect.code.location.name=''\" --detect.source.path='.'": fmt.Errorf("")} 254 utilsMock.ExitCode = 3 255 utilsMock.AddFile("detect.sh", []byte("")) 256 err := runDetect(detectExecuteScanOptions{}, utilsMock, &detectExecuteScanInflux{}) 257 assert.Equal(t, utilsMock.ExitCode, 3) 258 assert.Contains(t, err.Error(), "FAILURE_POLICY_VIOLATION => Detect found policy violations.") 259 assert.True(t, utilsMock.HasRemovedFile("detect.sh")) 260 }) 261 262 t.Run("maven parameters", func(t *testing.T) { 263 t.Parallel() 264 utilsMock := newDetectTestUtilsBundle() 265 utilsMock.CurrentDir = "root_folder" 266 utilsMock.AddFile("detect.sh", []byte("")) 267 err := runDetect(detectExecuteScanOptions{ 268 M2Path: ".pipeline/local_repo", 269 ProjectSettingsFile: "project-settings.xml", 270 GlobalSettingsFile: "global-settings.xml", 271 }, utilsMock, &detectExecuteScanInflux{}) 272 273 assert.NoError(t, err) 274 assert.Equal(t, ".", utilsMock.Dir, "Wrong execution directory used") 275 assert.Equal(t, "/bin/bash", utilsMock.Shell[0], "Bash shell expected") 276 absoluteLocalPath := string(os.PathSeparator) + filepath.Join("root_folder", ".pipeline", "local_repo") 277 278 expectedParam := "\"--detect.maven.build.command='--global-settings global-settings.xml --settings project-settings.xml -Dmaven.repo.local=" + absoluteLocalPath + "'\"" 279 assert.Contains(t, utilsMock.Calls[0], expectedParam) 280 }) 281 } 282 283 func TestAddDetectArgs(t *testing.T) { 284 t.Parallel() 285 testData := []struct { 286 args []string 287 options detectExecuteScanOptions 288 expected []string 289 }{ 290 { 291 args: []string{"--testProp1=1"}, 292 options: detectExecuteScanOptions{ 293 ScanProperties: []string{"--scan1=1", "--scan2=2"}, 294 ServerURL: "https://server.url", 295 Token: "apiToken", 296 ProjectName: "testName", 297 Version: "1.0", 298 VersioningModel: "major-minor", 299 CodeLocation: "", 300 Scanners: []string{"signature"}, 301 ScanPaths: []string{"path1", "path2"}, 302 }, 303 expected: []string{ 304 "--testProp1=1", 305 "--scan1=1", 306 "--scan2=2", 307 "--blackduck.url=https://server.url", 308 "--blackduck.api.token=apiToken", 309 "\"--detect.project.name='testName'\"", 310 "\"--detect.project.version.name='1.0'\"", 311 "\"--detect.code.location.name='testName/1.0'\"", 312 "--detect.blackduck.signature.scanner.paths=path1,path2", 313 "--detect.source.path='.'", 314 }, 315 }, 316 { 317 args: []string{"--testProp1=1"}, 318 options: detectExecuteScanOptions{ 319 ServerURL: "https://server.url", 320 Token: "apiToken", 321 ProjectName: "testName", 322 Version: "1.0", 323 VersioningModel: "major-minor", 324 CodeLocation: "testLocation", 325 FailOn: []string{"BLOCKER", "MAJOR"}, 326 Scanners: []string{"source"}, 327 ScanPaths: []string{"path1", "path2"}, 328 Groups: []string{"testGroup"}, 329 }, 330 expected: []string{ 331 "--testProp1=1", 332 "--blackduck.url=https://server.url", 333 "--blackduck.api.token=apiToken", 334 "\"--detect.project.name='testName'\"", 335 "\"--detect.project.version.name='1.0'\"", 336 "\"--detect.project.user.groups='testGroup'\"", 337 "--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", 338 "\"--detect.code.location.name='testLocation'\"", 339 "--detect.blackduck.signature.scanner.paths=path1,path2", 340 "--detect.source.path='.'", 341 }, 342 }, 343 { 344 args: []string{"--testProp1=1"}, 345 options: detectExecuteScanOptions{ 346 ServerURL: "https://server.url", 347 Token: "apiToken", 348 ProjectName: "testName", 349 CodeLocation: "testLocation", 350 FailOn: []string{"BLOCKER", "MAJOR"}, 351 Scanners: []string{"source"}, 352 ScanPaths: []string{"path1", "path2"}, 353 Groups: []string{"testGroup", "testGroup2"}, 354 Version: "1.0", 355 VersioningModel: "major-minor", 356 }, 357 expected: []string{ 358 "--testProp1=1", 359 "--blackduck.url=https://server.url", 360 "--blackduck.api.token=apiToken", 361 "\"--detect.project.name='testName'\"", 362 "\"--detect.project.version.name='1.0'\"", 363 "\"--detect.project.user.groups='testGroup,testGroup2'\"", 364 "--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", 365 "\"--detect.code.location.name='testLocation'\"", 366 "--detect.blackduck.signature.scanner.paths=path1,path2", 367 "--detect.source.path='.'", 368 }, 369 }, 370 { 371 args: []string{"--testProp1=1"}, 372 options: detectExecuteScanOptions{ 373 ServerURL: "https://server.url", 374 Token: "apiToken", 375 ProjectName: "testName", 376 CodeLocation: "testLocation", 377 FailOn: []string{"BLOCKER", "MAJOR"}, 378 Scanners: []string{"source"}, 379 ScanPaths: []string{"path1", "path2"}, 380 Groups: []string{"testGroup", "testGroup2"}, 381 Version: "1.0", 382 VersioningModel: "major-minor", 383 DependencyPath: "pathx", 384 }, 385 expected: []string{ 386 "--testProp1=1", 387 "--blackduck.url=https://server.url", 388 "--blackduck.api.token=apiToken", 389 "\"--detect.project.name='testName'\"", 390 "\"--detect.project.version.name='1.0'\"", 391 "\"--detect.project.user.groups='testGroup,testGroup2'\"", 392 "--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", 393 "\"--detect.code.location.name='testLocation'\"", 394 "--detect.blackduck.signature.scanner.paths=path1,path2", 395 "--detect.source.path=pathx", 396 }, 397 }, 398 { 399 args: []string{"--testProp1=1"}, 400 options: detectExecuteScanOptions{ 401 ServerURL: "https://server.url", 402 Token: "apiToken", 403 ProjectName: "testName", 404 CodeLocation: "testLocation", 405 FailOn: []string{"BLOCKER", "MAJOR"}, 406 Scanners: []string{"source"}, 407 ScanPaths: []string{"path1", "path2"}, 408 Groups: []string{"testGroup", "testGroup2"}, 409 Version: "1.0", 410 VersioningModel: "major-minor", 411 DependencyPath: "pathx", 412 Unmap: true, 413 }, 414 expected: []string{ 415 "--testProp1=1", 416 "--detect.project.codelocation.unmap=true", 417 "--blackduck.url=https://server.url", 418 "--blackduck.api.token=apiToken", 419 "\"--detect.project.name='testName'\"", 420 "\"--detect.project.version.name='1.0'\"", 421 "\"--detect.project.user.groups='testGroup,testGroup2'\"", 422 "--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", 423 "\"--detect.code.location.name='testLocation'\"", 424 "--detect.blackduck.signature.scanner.paths=path1,path2", 425 "--detect.source.path=pathx", 426 }, 427 }, 428 { 429 args: []string{"--testProp1=1"}, 430 options: detectExecuteScanOptions{ 431 ServerURL: "https://server.url", 432 Token: "apiToken", 433 ProjectName: "testName", 434 CodeLocation: "testLocation", 435 FailOn: []string{"BLOCKER", "MAJOR"}, 436 Scanners: []string{"source"}, 437 ScanPaths: []string{"path1", "path2"}, 438 Groups: []string{"testGroup", "testGroup2"}, 439 Version: "1.0", 440 VersioningModel: "major-minor", 441 DependencyPath: "pathx", 442 Unmap: true, 443 IncludedPackageManagers: []string{"maven", "GRADLE"}, 444 ExcludedPackageManagers: []string{"npm", "NUGET"}, 445 MavenExcludedScopes: []string{"TEST", "compile"}, 446 DetectTools: []string{"DETECTOR"}, 447 }, 448 expected: []string{ 449 "--testProp1=1", 450 "--detect.project.codelocation.unmap=true", 451 "--blackduck.url=https://server.url", 452 "--blackduck.api.token=apiToken", 453 "\"--detect.project.name='testName'\"", 454 "\"--detect.project.version.name='1.0'\"", 455 "\"--detect.project.user.groups='testGroup,testGroup2'\"", 456 "--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", 457 "\"--detect.code.location.name='testLocation'\"", 458 "--detect.blackduck.signature.scanner.paths=path1,path2", 459 "--detect.source.path=pathx", 460 "--detect.included.detector.types=MAVEN,GRADLE", 461 "--detect.excluded.detector.types=NPM,NUGET", 462 "--detect.maven.excluded.scopes=test,compile", 463 "--detect.tools=DETECTOR", 464 }, 465 }, 466 { 467 args: []string{"--testProp1=1"}, 468 options: detectExecuteScanOptions{ 469 ServerURL: "https://server.url", 470 Token: "apiToken", 471 ProjectName: "testName", 472 CodeLocation: "testLocation", 473 FailOn: []string{"BLOCKER", "MAJOR"}, 474 Scanners: []string{"source"}, 475 ScanPaths: []string{"path1", "path2"}, 476 Groups: []string{"testGroup", "testGroup2"}, 477 Version: "1.0", 478 VersioningModel: "major-minor", 479 DependencyPath: "pathx", 480 Unmap: true, 481 IncludedPackageManagers: []string{"maven", "GRADLE"}, 482 ExcludedPackageManagers: []string{"npm", "NUGET"}, 483 MavenExcludedScopes: []string{"TEST", "compile"}, 484 DetectTools: []string{"DETECTOR"}, 485 ScanOnChanges: true, 486 }, 487 expected: []string{ 488 "--testProp1=1", 489 "--report", 490 "--blackduck.url=https://server.url", 491 "--blackduck.api.token=apiToken", 492 "\"--detect.project.name='testName'\"", 493 "\"--detect.project.version.name='1.0'\"", 494 "\"--detect.project.user.groups='testGroup,testGroup2'\"", 495 "--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", 496 "\"--detect.code.location.name='testLocation'\"", 497 "--detect.blackduck.signature.scanner.paths=path1,path2", 498 "--detect.source.path=pathx", 499 "--detect.included.detector.types=MAVEN,GRADLE", 500 "--detect.excluded.detector.types=NPM,NUGET", 501 "--detect.maven.excluded.scopes=test,compile", 502 "--detect.tools=DETECTOR", 503 }, 504 }, 505 { 506 args: []string{"--testProp1=1"}, 507 options: detectExecuteScanOptions{ 508 ServerURL: "https://server.url", 509 Token: "apiToken", 510 ProjectName: "testName", 511 CodeLocation: "testLocation", 512 FailOn: []string{"BLOCKER", "MAJOR"}, 513 Scanners: []string{"source"}, 514 ScanPaths: []string{"path1", "path2"}, 515 Groups: []string{"testGroup", "testGroup2"}, 516 Version: "1.0", 517 VersioningModel: "major-minor", 518 DependencyPath: "pathx", 519 Unmap: true, 520 IncludedPackageManagers: []string{"maven", "GRADLE"}, 521 ExcludedPackageManagers: []string{"npm", "NUGET"}, 522 MavenExcludedScopes: []string{"TEST", "compile"}, 523 DetectTools: []string{"DETECTOR"}, 524 ScanOnChanges: true, 525 }, 526 expected: []string{ 527 "--testProp1=1", 528 "--report", 529 "--blackduck.url=https://server.url", 530 "--blackduck.api.token=apiToken", 531 "\"--detect.project.name='testName'\"", 532 "\"--detect.project.version.name='1.0'\"", 533 "\"--detect.project.user.groups='testGroup,testGroup2'\"", 534 "--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", 535 "\"--detect.code.location.name='testLocation'\"", 536 "--detect.blackduck.signature.scanner.paths=path1,path2", 537 "--detect.source.path=pathx", 538 "--detect.included.detector.types=MAVEN,GRADLE", 539 "--detect.excluded.detector.types=NPM,NUGET", 540 "--detect.maven.excluded.scopes=test,compile", 541 "--detect.tools=DETECTOR", 542 }, 543 }, 544 { 545 args: []string{"--testProp1=1"}, 546 options: detectExecuteScanOptions{ 547 ScanProperties: []string{"--scan=1", "--detect.project.codelocation.unmap=true"}, 548 ServerURL: "https://server.url", 549 Token: "apiToken", 550 ProjectName: "testName", 551 CodeLocation: "testLocation", 552 FailOn: []string{"BLOCKER", "MAJOR"}, 553 Scanners: []string{"source"}, 554 ScanPaths: []string{"path1", "path2"}, 555 Groups: []string{"testGroup", "testGroup2"}, 556 Version: "1.0", 557 VersioningModel: "major-minor", 558 DependencyPath: "pathx", 559 Unmap: true, 560 IncludedPackageManagers: []string{"maven", "GRADLE"}, 561 ExcludedPackageManagers: []string{"npm", "NUGET"}, 562 MavenExcludedScopes: []string{"TEST", "compile"}, 563 DetectTools: []string{"DETECTOR"}, 564 ScanOnChanges: true, 565 }, 566 expected: []string{ 567 "--testProp1=1", 568 "--report", 569 "--scan=1", 570 "--blackduck.url=https://server.url", 571 "--blackduck.api.token=apiToken", 572 "\"--detect.project.name='testName'\"", 573 "\"--detect.project.version.name='1.0'\"", 574 "\"--detect.project.user.groups='testGroup,testGroup2'\"", 575 "--detect.policy.check.fail.on.severities=BLOCKER,MAJOR", 576 "\"--detect.code.location.name='testLocation'\"", 577 "--detect.blackduck.signature.scanner.paths=path1,path2", 578 "--detect.source.path=pathx", 579 "--detect.included.detector.types=MAVEN,GRADLE", 580 "--detect.excluded.detector.types=NPM,NUGET", 581 "--detect.maven.excluded.scopes=test,compile", 582 "--detect.tools=DETECTOR", 583 }, 584 }, 585 } 586 587 for k, v := range testData { 588 v := v 589 t.Run(fmt.Sprintf("run %v", k), func(t *testing.T) { 590 t.Parallel() 591 got, err := addDetectArgs(v.args, v.options, newDetectTestUtilsBundle()) 592 assert.NoError(t, err) 593 assert.Equal(t, v.expected, got) 594 }) 595 } 596 } 597 598 // Testing exit code mapping method 599 func TestExitCodeMapping(t *testing.T) { 600 601 cases := []struct { 602 exitCode int 603 expected string 604 }{ 605 {1, "FAILURE_BLACKDUCK_CONNECTIVITY"}, 606 {-1, "Not known exit code key"}, 607 {8, "Not known exit code key"}, 608 {100, "FAILURE_UNKNOWN_ERROR"}, 609 } 610 611 for _, c := range cases { 612 response := exitCodeMapping(c.exitCode) 613 assert.Contains(t, response, c.expected) 614 } 615 } 616 617 func TestPostScanChecksAndReporting(t *testing.T) { 618 t.Parallel() 619 t.Run("Reporting after scan", func(t *testing.T) { 620 config := detectExecuteScanOptions{Token: "token", ServerURL: "https://my.blackduck.system", ProjectName: "SHC-PiperTest", Version: "", CustomScanVersion: "1.0"} 621 utils := newDetectTestUtilsBundle() 622 sys := newBlackduckMockSystem(config) 623 err := postScanChecksAndReporting(config, &detectExecuteScanInflux{}, utils, &sys) 624 625 assert.EqualError(t, err, "License Policy Violations found") 626 content, err := utils.FileRead("blackduck-ip.json") 627 assert.NoError(t, err) 628 assert.Contains(t, string(content), `"policyViolations":2`) 629 }) 630 } 631 632 func TestIsMajorVulnerability(t *testing.T) { 633 t.Parallel() 634 t.Run("Case True", func(t *testing.T) { 635 vr := bd.VulnerabilityWithRemediation{ 636 OverallScore: 7.5, 637 Severity: "HIGH", 638 } 639 v := bd.Vulnerability{ 640 Name: "", 641 VulnerabilityWithRemediation: vr, 642 } 643 assert.True(t, isMajorVulnerability(v)) 644 }) 645 t.Run("Case False", func(t *testing.T) { 646 vr := bd.VulnerabilityWithRemediation{ 647 OverallScore: 7.5, 648 Severity: "MEDIUM", 649 } 650 v := bd.Vulnerability{ 651 Name: "", 652 VulnerabilityWithRemediation: vr, 653 } 654 assert.False(t, isMajorVulnerability(v)) 655 }) 656 } 657 658 func TestIsActiveVulnerability(t *testing.T) { 659 t.Parallel() 660 t.Run("Case true", func(t *testing.T) { 661 vr := bd.VulnerabilityWithRemediation{ 662 OverallScore: 7.5, 663 Severity: "HIGH", 664 RemediationStatus: "NEW", 665 } 666 v := bd.Vulnerability{ 667 Name: "", 668 VulnerabilityWithRemediation: vr, 669 } 670 assert.True(t, isActiveVulnerability(v)) 671 }) 672 t.Run("Case False", func(t *testing.T) { 673 vr := bd.VulnerabilityWithRemediation{ 674 OverallScore: 7.5, 675 Severity: "HIGH", 676 RemediationStatus: "IGNORED", 677 } 678 v := bd.Vulnerability{ 679 Name: "", 680 VulnerabilityWithRemediation: vr, 681 } 682 assert.False(t, isActiveVulnerability(v)) 683 }) 684 } 685 686 func TestIsActivePolicyViolation(t *testing.T) { 687 t.Parallel() 688 t.Run("Case true", func(t *testing.T) { 689 assert.True(t, isActivePolicyViolation("IN_VIOLATION")) 690 }) 691 t.Run("Case False", func(t *testing.T) { 692 assert.False(t, isActivePolicyViolation("NOT_IN_VIOLATION")) 693 }) 694 } 695 696 func TestGetActivePolicyViolations(t *testing.T) { 697 t.Parallel() 698 t.Run("Case true", func(t *testing.T) { 699 config := detectExecuteScanOptions{Token: "token", ServerURL: "https://my.blackduck.system", ProjectName: "SHC-PiperTest", Version: "", CustomScanVersion: "1.0"} 700 sys := newBlackduckMockSystem(config) 701 702 components, err := sys.Client.GetComponents("SHC-PiperTest", "1.0") 703 assert.NoError(t, err) 704 assert.Equal(t, getActivePolicyViolations(components), 2) 705 }) 706 }