2023-05-03 18:02:11 +02:00
//go:build unit
// +build unit
2022-03-17 16:32:48 +02:00
package blackduck
import (
"fmt"
"path/filepath"
"testing"
"github.com/SAP/jenkins-library/pkg/format"
"github.com/SAP/jenkins-library/pkg/mock"
"github.com/SAP/jenkins-library/pkg/piperutils"
"github.com/SAP/jenkins-library/pkg/reporting"
"github.com/stretchr/testify/assert"
)
func TestCreateSarifResultFile ( t * testing . T ) {
2022-10-10 10:06:20 +02:00
vulnerabilities := [ ] string { "CVE-1" , "CVE-2" , "CVE-3" , "CVE-4" }
affectedComponent := Component { Name : "test1" , Version : "1.2.3" , ComponentOriginName : "Maven" , PrimaryLanguage : "Java" }
otherAffectedComponent := Component { Name : "test2" , Version : "1.2.8" , ComponentOriginName : "Maven" , PrimaryLanguage : "Java" }
2022-03-17 16:32:48 +02:00
alerts := [ ] Vulnerability {
2023-02-07 18:02:28 +02:00
{
Name : "test1" ,
Version : "1.2.3" ,
Component : & affectedComponent ,
VulnerabilityWithRemediation : VulnerabilityWithRemediation {
CweID : "CWE-45456543" ,
VulnerabilityName : "CVE-1" ,
Severity : "CRITICAL" ,
Description : "Some vulnerability that can be exploited by peeling the glue off." ,
BaseScore : 9.8 , OverallScore : 10 ,
RemediationStatus : "IGNORED" ,
RemediationComment : "CWE-45456543 Auto-remediated: CWE-45456543 is related to CVE-1, but the CWE team has determined that this component version is not affected." ,
2023-10-17 11:48:52 +02:00
RemidiatedBy : "technical_user" ,
2023-02-07 18:02:28 +02:00
} ,
} ,
{
Name : "test1" ,
Version : "1.2.3" ,
Component : & affectedComponent ,
VulnerabilityWithRemediation : VulnerabilityWithRemediation {
CweID : "CWE-45456542" ,
VulnerabilityName : "CVE-2" ,
Severity : "CRITICAL" ,
Description : "Some other vulnerability that can be exploited by filling the glass." ,
BaseScore : 9 ,
OverallScore : 9 ,
RemediationStatus : "NEW" ,
RemediationComment : "" ,
} ,
} ,
{
Name : "test1" ,
Version : "1.2.3" ,
Component : & affectedComponent ,
VulnerabilityWithRemediation : VulnerabilityWithRemediation {
CweID : "CWE-45456541" ,
VulnerabilityName : "CVE-3" ,
Severity : "HIGH" ,
Description : "Some vulnerability that can be exploited by turning it upside down." ,
BaseScore : 6.5 ,
OverallScore : 7 ,
2023-10-17 11:48:52 +02:00
RemediationStatus : "IGNORED" ,
2023-02-07 18:02:28 +02:00
} ,
} ,
{
Name : "test2" ,
Version : "1.2.8" ,
Component : & otherAffectedComponent ,
VulnerabilityWithRemediation : VulnerabilityWithRemediation {
CweID : "CWE-45789754" ,
VulnerabilityName : "CVE-4" ,
Severity : "HIGH" ,
Description : "Some vulnerability that can be exploited by turning it upside down." ,
BaseScore : 6.5 ,
OverallScore : 7 ,
} ,
} ,
{
Name : "test2" ,
Version : "1.2.8" ,
Component : & otherAffectedComponent ,
VulnerabilityWithRemediation : VulnerabilityWithRemediation {
CweID : "CWE-45456541" ,
VulnerabilityName : "CVE-3" ,
Severity : "HIGH" ,
Description : "Some vulnerability that can be exploited by turning it upside down." ,
BaseScore : 6.5 ,
OverallScore : 7 ,
} ,
} ,
2022-03-17 16:32:48 +02:00
}
vulns := Vulnerabilities {
Items : alerts ,
}
2022-12-01 10:47:53 +02:00
projectName := "theProjectName"
projectVersion := "theProjectVersion"
projectLink := "theProjectLink"
2022-03-17 16:32:48 +02:00
2022-12-01 10:47:53 +02:00
sarif := CreateSarifResultFile ( & vulns , projectName , projectVersion , projectLink )
2022-03-17 16:32:48 +02:00
2022-03-22 15:47:19 +02:00
assert . Equal ( t , "https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json" , sarif . Schema )
2022-03-17 16:32:48 +02:00
assert . Equal ( t , "2.1.0" , sarif . Version )
assert . Equal ( t , 1 , len ( sarif . Runs ) )
2022-12-01 10:47:53 +02:00
assert . Equal ( t , "Black Duck" , sarif . Runs [ 0 ] . Tool . Driver . Name )
2022-03-17 16:32:48 +02:00
assert . Equal ( t , "unknown" , sarif . Runs [ 0 ] . Tool . Driver . Version )
2022-10-10 10:06:20 +02:00
assert . Equal ( t , 4 , len ( sarif . Runs [ 0 ] . Tool . Driver . Rules ) )
assert . Equal ( t , 5 , len ( sarif . Runs [ 0 ] . Results ) )
2023-02-07 18:02:28 +02:00
assert . Equal ( t , "CRITICAL" , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . ToolSeverity )
// Test correctness of audit information
assert . Equal ( t , true , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . Audited )
assert . Equal ( t , "IGNORED" , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . ToolState )
2023-10-17 11:48:52 +02:00
assert . Equal ( t , alerts [ 0 ] . BaseScore , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . UnifiedCriticality )
assert . Equal ( t , "critical" , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . UnifiedSeverity )
assert . Equal ( t , "new" , sarif . Runs [ 0 ] . Results [ 1 ] . Properties . UnifiedAuditState )
assert . Equal ( t , "notRelevant" , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . UnifiedAuditState )
assert . Equal ( t , "technical_user" , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . UnifiedAuditUser )
assert . Equal ( t , format . AUDIT_REQUIREMENT_GROUP_1_DESC , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . AuditRequirement )
assert . Equal ( t , format . AUDIT_REQUIREMENT_GROUP_1_INDEX , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . AuditRequirementIndex )
2023-02-07 18:02:28 +02:00
assert . Equal ( t ,
"CWE-45456543 Auto-remediated: CWE-45456543 is related to CVE-1, but the CWE team has determined that this component version is not affected." ,
sarif . Runs [ 0 ] . Results [ 0 ] . Properties . ToolAuditMessage ,
)
assert . Equal ( t , 4 , sarif . Runs [ 0 ] . Results [ 0 ] . Properties . ToolSeverityIndex )
assert . Equal ( t , 3 , sarif . Runs [ 0 ] . Results [ 2 ] . Properties . ToolSeverityIndex )
assert . Equal ( t , false , sarif . Runs [ 0 ] . Results [ 1 ] . Properties . Audited )
assert . Equal ( t , "NEW" , sarif . Runs [ 0 ] . Results [ 1 ] . Properties . ToolState )
assert . Equal ( t , "" , sarif . Runs [ 0 ] . Results [ 1 ] . Properties . ToolAuditMessage )
2022-10-10 10:06:20 +02:00
collectedRules := [ ] string { }
for _ , rule := range sarif . Runs [ 0 ] . Tool . Driver . Rules {
piperutils . ContainsString ( vulnerabilities , rule . ID )
collectedRules = append ( collectedRules , rule . ID )
}
collectedResults := [ ] string { }
for _ , result := range sarif . Runs [ 0 ] . Results {
piperutils . ContainsString ( vulnerabilities , result . RuleID )
collectedResults = append ( collectedResults , result . RuleID )
}
assert . Equal ( t , 4 , len ( collectedRules ) )
assert . Equal ( t , 5 , len ( collectedResults ) )
assert . Equal ( t , vulnerabilities , collectedRules )
2022-03-17 16:32:48 +02:00
}
func TestWriteCustomVulnerabilityReports ( t * testing . T ) {
t . Run ( "success" , func ( t * testing . T ) {
scanReport := reporting . ScanReport { }
utilsMock := & mock . FilesMock { }
reportPaths , err := WriteVulnerabilityReports ( scanReport , utilsMock )
assert . NoError ( t , err )
assert . Equal ( t , 1 , len ( reportPaths ) )
exists , err := utilsMock . FileExists ( reportPaths [ 0 ] . Target )
assert . NoError ( t , err )
assert . True ( t , exists )
exists , err = utilsMock . FileExists ( filepath . Join ( reporting . StepReportDirectory , "detectExecuteScan_oss_20220102-150405.json" ) )
assert . NoError ( t , err )
assert . True ( t , exists )
} )
t . Run ( "failed to write json report" , func ( t * testing . T ) {
scanReport := reporting . ScanReport { }
utilsMock := & mock . FilesMock { }
utilsMock . FileWriteErrors = map [ string ] error {
filepath . Join ( reporting . StepReportDirectory , "detectExecuteScan_oss_20220102-150405.json" ) : fmt . Errorf ( "write error" ) ,
}
_ , err := WriteVulnerabilityReports ( scanReport , utilsMock )
assert . Contains ( t , fmt . Sprint ( err ) , "failed to write json report" )
} )
}
func TestWriteSarifFile ( t * testing . T ) {
t . Run ( "success" , func ( t * testing . T ) {
sarif := format . SARIF { }
var utilsMock piperutils . FileUtils
utilsMock = & mock . FilesMock { }
reportPaths , err := WriteSarifFile ( & sarif , utilsMock )
assert . NoError ( t , err )
assert . Equal ( t , 1 , len ( reportPaths ) )
exists , err := utilsMock . FileExists ( reportPaths [ 0 ] . Target )
assert . NoError ( t , err )
assert . True ( t , exists )
exists , err = utilsMock . FileExists ( filepath . Join ( ReportsDirectory , "piper_detect_vulnerability.sarif" ) )
assert . NoError ( t , err )
assert . True ( t , exists )
} )
t . Run ( "failed to write HTML report" , func ( t * testing . T ) {
sarif := format . SARIF { }
utilsMock := & mock . FilesMock { }
utilsMock . FileWriteErrors = map [ string ] error {
filepath . Join ( ReportsDirectory , "piper_detect_vulnerability.sarif" ) : fmt . Errorf ( "write error" ) ,
}
_ , err := WriteSarifFile ( & sarif , utilsMock )
assert . Contains ( t , fmt . Sprint ( err ) , "failed to write SARIF file" )
} )
}