2018-09-21 16:55:31 +02:00
|
|
|
import static com.sap.piper.Prerequisites.checkScript
|
|
|
|
|
2019-04-03 11:29:57 +02:00
|
|
|
import com.sap.piper.GenerateDocumentation
|
2018-04-05 09:27:32 +02:00
|
|
|
import com.sap.piper.ConfigurationHelper
|
2019-02-08 13:30:59 +02:00
|
|
|
import com.sap.piper.JenkinsUtils
|
2018-02-08 17:10:02 +02:00
|
|
|
import com.sap.piper.MapUtils
|
2018-08-09 11:35:33 +02:00
|
|
|
import com.sap.piper.Utils
|
2018-02-02 13:25:28 +02:00
|
|
|
import groovy.transform.Field
|
|
|
|
|
2018-02-19 11:26:50 +02:00
|
|
|
@Field List TOOLS = [
|
2019-04-03 11:29:57 +02:00
|
|
|
/**
|
|
|
|
* Publishes test results files in JUnit format with the [JUnit Plugin](https://plugins.jenkins.io/junit).
|
|
|
|
* @possibleValues `true`, `false`, `Map`
|
|
|
|
*/
|
|
|
|
'junit',
|
|
|
|
/**
|
|
|
|
* Publishes code coverage with the [JaCoCo plugin](https://plugins.jenkins.io/jacoco).
|
|
|
|
* @possibleValues `true`, `false`, `Map`
|
|
|
|
*/
|
|
|
|
'jacoco',
|
|
|
|
/**
|
|
|
|
* Publishes code coverage with the [Cobertura plugin](https://plugins.jenkins.io/cobertura).
|
|
|
|
* @possibleValues `true`, `false`, `Map`
|
|
|
|
*/
|
|
|
|
'cobertura',
|
|
|
|
/**
|
|
|
|
* Publishes performance test results with the [Performance plugin](https://plugins.jenkins.io/performance).
|
|
|
|
* @possibleValues `true`, `false`, `Map`
|
|
|
|
*/
|
2020-07-14 13:33:49 +02:00
|
|
|
'jmeter',
|
|
|
|
/**
|
|
|
|
* Publishes test results with the [Cucumber plugin](https://plugins.jenkins.io/cucumber-testresult-plugin/).
|
|
|
|
* @possibleValues `true`, `false`, `Map`
|
|
|
|
*/
|
2020-09-02 17:04:59 +02:00
|
|
|
'cucumber',
|
|
|
|
/**
|
|
|
|
* Publishes test results with the [HTML Publisher plugin](https://plugins.jenkins.io/htmlpublisher/).
|
|
|
|
* @possibleValues `true`, `false`, `Map`
|
|
|
|
*/
|
|
|
|
'htmlPublisher'
|
2018-02-19 11:26:50 +02:00
|
|
|
]
|
2018-04-05 09:27:32 +02:00
|
|
|
|
2018-11-29 10:54:05 +02:00
|
|
|
@Field def STEP_NAME = getClass().getName()
|
2019-04-03 11:29:57 +02:00
|
|
|
|
2018-10-25 15:03:29 +02:00
|
|
|
@Field Set GENERAL_CONFIG_KEYS = TOOLS
|
2019-04-03 11:29:57 +02:00
|
|
|
|
2019-02-08 13:30:59 +02:00
|
|
|
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
|
2019-04-03 11:29:57 +02:00
|
|
|
/**
|
|
|
|
* If it is set to `true` the step will fail the build if JUnit detected any failing tests.
|
|
|
|
* @possibleValues `true`, `false`
|
|
|
|
*/
|
2019-02-08 13:30:59 +02:00
|
|
|
'failOnError'
|
|
|
|
])
|
2019-04-03 11:29:57 +02:00
|
|
|
|
2018-04-05 09:27:32 +02:00
|
|
|
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
|
|
|
|
2018-02-02 13:25:28 +02:00
|
|
|
/**
|
2019-04-03 11:29:57 +02:00
|
|
|
* This step can publish test results from various sources.
|
2018-02-02 13:25:28 +02:00
|
|
|
*/
|
2019-04-03 11:29:57 +02:00
|
|
|
@GenerateDocumentation
|
2018-08-30 16:33:07 +02:00
|
|
|
void call(Map parameters = [:]) {
|
2018-02-02 13:25:28 +02:00
|
|
|
handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters) {
|
2019-02-08 13:30:59 +02:00
|
|
|
def script = checkScript(this, parameters) ?: this
|
2020-08-26 15:32:58 +02:00
|
|
|
String stageName = parameters.stageName ?: env.STAGE_NAME
|
2018-09-21 16:55:31 +02:00
|
|
|
|
2018-02-08 17:10:02 +02:00
|
|
|
prepare(parameters)
|
|
|
|
|
2018-04-05 09:27:32 +02:00
|
|
|
// load default & individual configuration
|
2018-10-17 11:05:20 +02:00
|
|
|
Map configuration = ConfigurationHelper.newInstance(this)
|
2020-08-26 15:32:58 +02:00
|
|
|
.loadStepDefaults([:], stageName)
|
2018-10-25 15:03:29 +02:00
|
|
|
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
2018-04-05 09:27:32 +02:00
|
|
|
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
2020-08-26 15:32:58 +02:00
|
|
|
.mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
|
2018-04-05 09:27:32 +02:00
|
|
|
.mixin(parameters, PARAMETER_KEYS)
|
|
|
|
.use()
|
2018-02-08 17:10:02 +02:00
|
|
|
|
2019-01-21 09:47:34 +02:00
|
|
|
new Utils().pushToSWA([
|
|
|
|
step: STEP_NAME,
|
|
|
|
stepParamKey1: 'scriptMissing',
|
|
|
|
stepParam1: parameters?.script == null
|
|
|
|
], configuration)
|
2018-08-09 11:35:33 +02:00
|
|
|
|
2018-02-02 13:25:28 +02:00
|
|
|
publishJUnitReport(configuration.get('junit'))
|
|
|
|
publishJacocoReport(configuration.get('jacoco'))
|
|
|
|
publishCoberturaReport(configuration.get('cobertura'))
|
|
|
|
publishJMeterReport(configuration.get('jmeter'))
|
2020-07-14 13:33:49 +02:00
|
|
|
publishCucumberReport(configuration.get('cucumber'))
|
2020-09-02 17:04:59 +02:00
|
|
|
publishHtmlReport(configuration.get('htmlPublisher'))
|
2019-02-08 13:30:59 +02:00
|
|
|
|
|
|
|
if (configuration.failOnError && JenkinsUtils.hasTestFailures(script.currentBuild)) {
|
|
|
|
script.currentBuild.result = 'FAILURE'
|
|
|
|
error "[${STEP_NAME}] Some tests failed!"
|
|
|
|
}
|
2018-02-02 13:25:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def publishJUnitReport(Map settings = [:]) {
|
2020-07-14 13:33:49 +02:00
|
|
|
if (settings.active) {
|
2018-02-02 13:25:28 +02:00
|
|
|
def pattern = settings.get('pattern')
|
|
|
|
def allowEmpty = settings.get('allowEmptyResults')
|
|
|
|
|
|
|
|
if (settings.get('updateResults'))
|
|
|
|
touchFiles(pattern)
|
|
|
|
junit(
|
|
|
|
testResults: pattern,
|
|
|
|
allowEmptyResults: allowEmpty,
|
|
|
|
healthScaleFactor: 100.0,
|
|
|
|
)
|
|
|
|
archiveResults(settings.get('archive'), pattern, allowEmpty)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def publishJacocoReport(Map settings = [:]) {
|
2020-07-14 13:33:49 +02:00
|
|
|
if (settings.active) {
|
2018-02-02 13:25:28 +02:00
|
|
|
def pattern = settings.get('pattern')
|
|
|
|
def allowEmpty = settings.get('allowEmptyResults')
|
|
|
|
|
|
|
|
jacoco(
|
|
|
|
execPattern: pattern,
|
2018-02-08 17:10:02 +02:00
|
|
|
inclusionPattern: settings.get('include', ''),
|
|
|
|
exclusionPattern: settings.get('exclude', '')
|
2018-02-02 13:25:28 +02:00
|
|
|
)
|
|
|
|
archiveResults(settings.get('archive'), pattern, allowEmpty)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def publishCoberturaReport(Map settings = [:]) {
|
2020-07-14 13:33:49 +02:00
|
|
|
if (settings.active) {
|
2018-02-02 13:25:28 +02:00
|
|
|
def pattern = settings.get('pattern')
|
|
|
|
def allowEmpty = settings.get('allowEmptyResults')
|
|
|
|
|
|
|
|
cobertura(
|
|
|
|
coberturaReportFile: pattern,
|
|
|
|
onlyStable: settings.get('onlyStableBuilds'),
|
|
|
|
failNoReports: !allowEmpty,
|
|
|
|
failUnstable: false,
|
|
|
|
failUnhealthy: false,
|
|
|
|
autoUpdateHealth: false,
|
|
|
|
autoUpdateStability: false,
|
|
|
|
maxNumberOfBuilds: 0
|
|
|
|
)
|
|
|
|
archiveResults(settings.get('archive'), pattern, allowEmpty)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// publish Performance Report using "Jenkins Performance Plugin" https://wiki.jenkins.io/display/JENKINS/Performance+Plugin
|
|
|
|
def publishJMeterReport(Map settings = [:]){
|
2020-07-14 13:33:49 +02:00
|
|
|
if (settings.active) {
|
2018-02-02 13:25:28 +02:00
|
|
|
def pattern = settings.get('pattern')
|
|
|
|
|
2018-02-19 11:11:12 +02:00
|
|
|
perfReport(
|
|
|
|
sourceDataFiles: pattern,
|
2018-02-02 13:25:28 +02:00
|
|
|
errorFailedThreshold: settings.get('errorFailedThreshold'),
|
|
|
|
errorUnstableThreshold: settings.get('errorUnstableThreshold'),
|
|
|
|
errorUnstableResponseTimeThreshold: settings.get('errorUnstableResponseTimeThreshold'),
|
|
|
|
relativeFailedThresholdPositive: settings.get('relativeFailedThresholdPositive'),
|
|
|
|
relativeFailedThresholdNegative: settings.get('relativeFailedThresholdNegative'),
|
|
|
|
relativeUnstableThresholdPositive: settings.get('relativeUnstableThresholdPositive'),
|
|
|
|
relativeUnstableThresholdNegative: settings.get('relativeUnstableThresholdNegative'),
|
|
|
|
modePerformancePerTestCase: false,
|
|
|
|
modeOfThreshold: settings.get('modeOfThreshold'),
|
|
|
|
modeThroughput: settings.get('modeThroughput'),
|
|
|
|
nthBuildNumber: settings.get('nthBuildNumber'),
|
|
|
|
configType: settings.get('configType'),
|
|
|
|
failBuildIfNoResultFile: settings.get('failBuildIfNoResultFile'),
|
2018-02-19 11:11:12 +02:00
|
|
|
compareBuildPrevious: settings.get('compareBuildPrevious')
|
|
|
|
)
|
2018-02-02 13:25:28 +02:00
|
|
|
archiveResults(settings.get('archive'), pattern, settings.get('allowEmptyResults'))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-14 13:33:49 +02:00
|
|
|
def publishCucumberReport(Map settings = [:]) {
|
|
|
|
if (settings.active) {
|
|
|
|
def pattern = settings.get('pattern')
|
|
|
|
def allowEmpty = settings.get('allowEmptyResults')
|
|
|
|
|
|
|
|
cucumber(
|
|
|
|
testResults: pattern
|
|
|
|
)
|
|
|
|
archiveResults(settings.get('archive'), pattern, allowEmpty)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-02 17:04:59 +02:00
|
|
|
def publishHtmlReport(Map settings = [:]) {
|
|
|
|
if (settings.active) {
|
|
|
|
publishHTML(target: [
|
|
|
|
allowMissing : settings.get('allowMissing'),
|
|
|
|
alwaysLinkToLastBuild: settings.get('alwaysLinkToLastBuild'),
|
|
|
|
keepAll : settings.get('keepAll'),
|
|
|
|
reportDir : settings.get('reportDir'),
|
|
|
|
reportFiles : settings.get('pattern'),
|
|
|
|
reportName : settings.get('reportName')
|
|
|
|
])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-10 12:05:41 +02:00
|
|
|
void touchFiles(pattern){
|
2018-02-02 13:25:28 +02:00
|
|
|
echo "[${STEP_NAME}] update test results"
|
|
|
|
def patternArray = pattern.split(',')
|
|
|
|
for(def i = 0; i < patternArray.length; i++){
|
|
|
|
sh "find . -wholename '${patternArray[i].trim()}' -exec touch {} \\;"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def archiveResults(archive, pattern, allowEmpty) {
|
|
|
|
if(archive){
|
2018-02-19 11:26:50 +02:00
|
|
|
echo "[${STEP_NAME}] archive ${pattern}"
|
2018-02-02 13:25:28 +02:00
|
|
|
archiveArtifacts artifacts: pattern, allowEmptyArchive: allowEmpty
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def prepare(parameters){
|
2018-02-08 17:10:02 +02:00
|
|
|
// ensure tool maps are initialized correctly
|
2018-02-19 11:26:50 +02:00
|
|
|
for(String tool : TOOLS){
|
2018-02-08 17:10:02 +02:00
|
|
|
parameters[tool] = toMap(parameters[tool])
|
|
|
|
}
|
2018-02-02 13:25:28 +02:00
|
|
|
return parameters
|
|
|
|
}
|
|
|
|
|
2018-02-08 17:10:02 +02:00
|
|
|
def toMap(parameters){
|
|
|
|
if(MapUtils.isMap(parameters))
|
|
|
|
parameters.put('active', parameters.active == null?true:parameters.active)
|
|
|
|
else if(Boolean.TRUE.equals(parameters))
|
|
|
|
parameters = [active: true]
|
|
|
|
else if(Boolean.FALSE.equals(parameters))
|
|
|
|
parameters = [active: false]
|
2018-02-02 13:25:28 +02:00
|
|
|
else
|
2018-02-08 17:10:02 +02:00
|
|
|
parameters = [:]
|
2018-02-19 11:26:50 +02:00
|
|
|
return parameters
|
2018-02-02 13:25:28 +02:00
|
|
|
}
|