import static com.sap.piper.Prerequisites.checkScript import com.sap.piper.GenerateDocumentation import com.sap.piper.ConfigurationHelper import com.sap.piper.Utils import groovy.transform.Field @Field String STEP_NAME = getClass().getName() @Field Set GENERAL_CONFIG_KEYS = [ /** * Print more detailed information into the log. * @possibleValues `true`, `false` */ 'verbose' ] @Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([ /** * @see dockerExecute */ 'containerCommand', /** * @see dockerExecute */ 'containerShell', /** * @see dockerExecute */ 'dockerImage', /** * @see dockerExecute */ 'dockerOptions', /** * @see dockerExecute */ 'stashContent', /** * Defines the behavior, in case tests fail. * @possibleValues `true`, `false` */ 'failOnError', /** * Only relevant for testDriver 'docker'. * @possibleValues `true`, `false` */ 'pullImage', /** * Container structure test configuration in yml or json format. You can pass a pattern in order to execute multiple tests. */ 'testConfiguration', /** * Container structure test driver to be used for testing, please see https://github.com/GoogleContainerTools/container-structure-test for details. */ 'testDriver', /** * Image to be tested */ 'testImage', /** * Path and name of the test report which will be generated */ 'testReportFilePath', ]) @Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS /** * In this step [Container Structure Tests](https://github.com/GoogleContainerTools/container-structure-test) are executed. * * This testing framework allows you to execute different test types against a Docker container, for example: * * * Command tests (only if a Docker Deamon is available) * * File existence tests * * File content tests * * Metadata test */ @GenerateDocumentation void call(Map parameters = [:]) { handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) { def script = checkScript(this, parameters) ?: this def utils = parameters?.juStabUtils ?: new Utils() // load default & individual configuration Map config = ConfigurationHelper.newInstance(this) .loadStepDefaults() .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) .mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS) .mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS) .mixin(parameters, PARAMETER_KEYS) .addIfEmpty('testDriver', Boolean.valueOf(script.env.ON_K8S) ? 'tar' : 'docker') .addIfNull('pullImage', !Boolean.valueOf(script.env.ON_K8S)) .withMandatoryProperty('dockerImage') .use() utils.pushToSWA([step: STEP_NAME], config) config.stashContent = utils.unstashAll(config.stashContent) List testConfig = findFiles(glob: config.testConfiguration)?.toList() if (testConfig.isEmpty()) { error "[${STEP_NAME}] No test description found with pattern '${config.testConfiguration}'" } else { echo "[${STEP_NAME}] Found files ${testConfig}" } def testConfigArgs = '' testConfig.each {conf -> testConfigArgs += "--config ${conf} " } //workaround for non-working '--pull' option in version 1.7.0 of container-structure-tests, see https://github.com/GoogleContainerTools/container-structure-test/issues/193 if (config.pullImage) { if (config.verbose) echo "[${STEP_NAME}] Pulling image since configuration option pullImage is set to '${config.pullImage}'" sh "docker pull ${config.testImage}" } try { dockerExecute( script: script, containerCommand: config.containerCommand, containerShell: config.containerShell, dockerImage: config.dockerImage, dockerOptions: config.dockerOptions, stashContent: config.stashContent ) { sh """#!${config.containerShell?:'/bin/sh'} container-structure-test test ${testConfigArgs} --driver ${config.testDriver} --image ${config.testImage} --test-report ${config.testReportFilePath}${config.verbose ? ' --verbosity debug' : ''}""" } } catch (err) { echo "[${STEP_NAME}] Test execution failed" script.currentBuild.result = 'UNSTABLE' if (config.failOnError) throw err } finally { echo "${readFile(config.testReportFilePath)}" archiveArtifacts artifacts: config.testReportFilePath, allowEmptyArchive: true } } }