From 500c42860f1abc9f154683c6f6f44528943b7313 Mon Sep 17 00:00:00 2001 From: Alexander Link <33052602+alxsap@users.noreply.github.com> Date: Fri, 7 Jul 2023 14:35:14 +0200 Subject: [PATCH] Stash via Utils.stash (#4380) We should use Utils.stash instead of native steps.stash calls (Jenkins) since important logging is missing. The default Jenkins stash step does not log any metadata like stash name, patterns, etc. --- src/com/sap/piper/GitUtils.groovy | 2 +- src/com/sap/piper/Utils.groovy | 32 ++-- .../DockerExecuteOnKubernetesTest.groovy | 74 ++++----- .../FioriOnCloudPlatformPipelineTest.groovy | 23 +-- .../SetupCommonPipelineEnvironmentTest.groovy | 42 ++--- test/groovy/com/sap/piper/UtilsTest.groovy | 151 ++++++++++++++++++ vars/dockerExecute.groovy | 2 +- vars/dockerExecuteOnKubernetes.groovy | 20 +-- vars/fioriOnCloudPlatformPipeline.groovy | 1 + vars/neoDeploy.groovy | 1 + vars/piperExecuteBin.groovy | 2 +- vars/setupCommonPipelineEnvironment.groovy | 5 +- 12 files changed, 260 insertions(+), 95 deletions(-) diff --git a/src/com/sap/piper/GitUtils.groovy b/src/com/sap/piper/GitUtils.groovy index ee1fb7e55..0abeeeec1 100644 --- a/src/com/sap/piper/GitUtils.groovy +++ b/src/com/sap/piper/GitUtils.groovy @@ -90,7 +90,7 @@ static String handleTestRepository(Script steps, Map config){ // checkout test repository steps.git options // stash test content - steps.stash stashName + steps.stash stashName //TODO: should use new Utils().stash // return stash name return stashName } diff --git a/src/com/sap/piper/Utils.groovy b/src/com/sap/piper/Utils.groovy index 59c9ef4cd..bd11749ad 100644 --- a/src/com/sap/piper/Utils.groovy +++ b/src/com/sap/piper/Utils.groovy @@ -7,39 +7,51 @@ import groovy.text.GStringTemplateEngine import java.nio.charset.StandardCharsets import java.security.MessageDigest +def stash(Map params) { + if(params.includes == null) params.includes = '**/*.*' + if(params.excludes == null) params.excludes = '' + if(params.useDefaultExcludes == null) params.useDefaultExcludes = true + if(params.allowEmpty == null) params.allowEmpty = false + return stash(params.name, params.includes, params.excludes, params.useDefaultExcludes, params.allowEmpty) +} -def stash(name, include = '**/*.*', exclude = '', useDefaultExcludes = true) { - echo "Stash content: ${name} (include: ${include}, exclude: ${exclude}, useDefaultExcludes: ${useDefaultExcludes})" +def stash(String name, String includes = '**/*.*', String excludes = '', boolean useDefaultExcludes = true, boolean allowEmpty = false) { + if(!name) throw new IllegalArgumentException("name must not be '$name'") + echo "Stash content: ${name} (includes: ${includes}, excludes: ${excludes}, useDefaultExcludes: ${useDefaultExcludes}, allowEmpty: ${allowEmpty})" Map stashParams = [ name : name, - includes: include, - excludes: exclude + includes: includes, + excludes: excludes ] //only set the optional parameter if default excludes should not be applied if (!useDefaultExcludes) { stashParams.useDefaultExcludes = useDefaultExcludes } + //only set the optional parameter if allow empty should be applied + if (allowEmpty) { + stashParams.allowEmpty = allowEmpty + } steps.stash stashParams } def stashList(script, List stashes) { for (def stash : stashes) { def name = stash.name - def include = stash.includes - def exclude = stash.excludes + def includes = stash.includes + def excludes = stash.excludes if (stash?.merge == true) { String lockingResourceGroup = script.commonPipelineEnvironment.projectName?:env.JOB_NAME String lockName = "${lockingResourceGroup}/${stash.name}" lock(lockName) { unstash stash.name - echo "Stash content: ${name} (include: ${include}, exclude: ${exclude})" - steps.stash name: name, includes: include, excludes: exclude, allowEmpty: true + echo "Stash content: ${name} (includes: ${includes}, excludes: ${excludes})" + steps.stash name: name, includes: includes, excludes: excludes, allowEmpty: true } } else { - echo "Stash content: ${name} (include: ${include}, exclude: ${exclude})" - steps.stash name: name, includes: include, excludes: exclude, allowEmpty: true + echo "Stash content: ${name} (includes: ${includes}, excludes: ${excludes})" + steps.stash name: name, includes: includes, excludes: excludes, allowEmpty: true } } } diff --git a/test/groovy/DockerExecuteOnKubernetesTest.groovy b/test/groovy/DockerExecuteOnKubernetesTest.groovy index ec19551b6..846c0d5d7 100644 --- a/test/groovy/DockerExecuteOnKubernetesTest.groovy +++ b/test/groovy/DockerExecuteOnKubernetesTest.groovy @@ -74,6 +74,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { Utils newUtilsMock() { def utilsMock = new Utils() utilsMock.steps = [ + stash : { m -> stashList.add(m) }, unstash : { m -> unstashList.add(m) } ] utilsMock.echo = { def m -> } @@ -126,23 +127,13 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { } body() }) - helper.registerAllowedMethod('stash', [Map.class], { m -> - stashList.add(m) - }) - - Utils.metaClass.echo = { def m -> } - } - - @After - public void tearDown() { - Utils.metaClass = null } @Test void testRunOnPodNoContainerMapOnlyDockerImage() throws Exception { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', dockerOptions: '-it', dockerVolumeBind: ['my_vol': '/my_vol'], @@ -163,7 +154,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { void testDockerExecuteOnKubernetesEmptyContainerMapNoDockerImage() throws Exception { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, containerMap: [:], dockerEnvVars: ['customEnvKey': 'customEnvValue']) { bodyExecuted = true @@ -173,7 +164,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { @Test void testDockerExecuteOnKubernetesWithCustomContainerMap() throws Exception { - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute']) { container(name: 'mavenexecute') { bodyExecuted = true @@ -189,7 +180,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { @Test void testInheritFromPodTemplate() throws Exception { nullScript.commonPipelineEnvironment.configuration = ['general': ['jenkinsKubernetes': ['inheritFrom': 'default']]] - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute']) { container(name: 'mavenexecute') { bodyExecuted = true @@ -203,7 +194,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { @Test void testDockerExecuteOnKubernetesWithCustomJnlpWithContainerMap() throws Exception { nullScript.commonPipelineEnvironment.configuration = ['general': ['jenkinsKubernetes': ['jnlpAgent': 'myJnalpAgent']]] - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute']) { container(name: 'mavenexecute') { bodyExecuted = true @@ -223,7 +214,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = ['general': ['jenkinsKubernetes': ['jnlpAgent': 'myJnalpAgent']]] stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine') { bodyExecuted = true } @@ -237,7 +228,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { @Test void testDockerExecuteOnKubernetesWithCustomWorkspace() throws Exception { - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], dockerWorkspace: '/home/piper') { container(name: 'mavenexecute') { @@ -250,7 +241,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { @Test void testDockerExecuteOnKubernetesWithCustomEnv() throws Exception { - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], dockerEnvVars: ['customEnvKey': 'customEnvValue']) { container(name: 'mavenexecute') { @@ -281,7 +272,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { ] ] ]] - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], { bodyExecuted = true }) @@ -307,7 +298,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { ] ] ]]] - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], { bodyExecuted = true }) @@ -336,7 +327,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { ] ] ]]] - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], resources: [ mavenexecute: [ @@ -406,7 +397,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { ] ] ]] - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], sidecarImage: 'ubuntu', sidecarName: 'mysidecar') { @@ -421,7 +412,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { @Test void testDockerExecuteOnKubernetesUpperCaseContainerName() throws Exception { - stepRule.step.dockerExecuteOnKubernetes(script: nullScript, + stepRule.step.dockerExecuteOnKubernetes(script: nullScript, juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'MAVENEXECUTE'], dockerEnvVars: ['customEnvKey': 'customEnvValue']) { container(name: 'mavenexecute') { @@ -443,7 +434,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { }) stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, containerCommands: ['selenium/standalone-chrome': ''], containerEnvVars: [ 'selenium/standalone-chrome': ['customEnvKey': 'customEnvValue'] @@ -489,7 +480,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { }) stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], containerName: 'mavenexecute', dockerOptions: '-it', @@ -518,7 +509,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { void testDockerExecuteOnKubernetesWithCustomShell() { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', containerShell: '/busybox/sh' ) { @@ -531,7 +522,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { void testDockerExecuteOnKubernetesWithCustomContainerCommand() { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', containerCommand: '/busybox/tail -f /dev/null' ) { @@ -544,6 +535,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { void testSkipDockerImagePull() throws Exception { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, + juStabUtils: utilsMock, dockerPullImage: false, containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'] ) { @@ -559,7 +551,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { void testSkipSidecarImagePull() throws Exception { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, containerCommands: ['selenium/standalone-chrome': ''], containerEnvVars: [ 'selenium/standalone-chrome': ['customEnvKey': 'customEnvValue'] @@ -592,7 +584,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', ) { bodyExecuted = true } assertTrue(bodyExecuted) @@ -624,7 +616,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', ) { bodyExecuted = true } assertTrue(bodyExecuted) @@ -666,7 +658,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', ) { bodyExecuted = true } assertTrue(bodyExecuted) @@ -689,7 +681,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { securityContext: expectedSecurityContext]]] stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', ) { bodyExecuted = true } assertTrue(bodyExecuted) @@ -701,7 +693,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', nodeSelector: 'size:big' ) { bodyExecuted = true } @@ -718,7 +710,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { binding.variables.env.JENKINS_JNLP_IMAGE = 'env/jnlp:latest' stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', ) { bodyExecuted = true } assertTrue(bodyExecuted) @@ -742,7 +734,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { //binding.variables.env.JENKINS_JNLP_IMAGE = 'config/jnlp:latest' stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', ) { bodyExecuted = true } assertTrue(bodyExecuted) @@ -769,7 +761,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { //binding.variables.env.JENKINS_JNLP_IMAGE = 'config/jnlp:latest' stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', ) { throw new AbortException('Execution failed.') } } @@ -778,7 +770,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { void testDockerExecuteOnKubernetesAnnotations(){ stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, annotations: ['testAnnotation':'testValue'] ) { @@ -805,7 +797,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { ] stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, dockerImage: 'maven:3.5-jdk-8-alpine', ) { bodyExecuted = true @@ -836,7 +828,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { void testDockerExecuteWithVolumeProperties() { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, containerName: 'mycontainer', initContainerImage: 'ppiper/cf-cli', dockerImage: 'maven:3.5-jdk-8-alpine', @@ -866,7 +858,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { void testInitContainerDefaultWithParameters() { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, containerName: 'mycontainer', initContainerImage: 'ppiper/cf-cli@sha256:latest', initContainerCommand: 'cp /usr/local/bin/cf7 /opt/bin/cf', @@ -885,7 +877,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { void testInitContainerWithoutContainerCommand() { stepRule.step.dockerExecuteOnKubernetes( script: nullScript, - juStabUtils: utils, + juStabUtils: utilsMock, containerName: 'mycontainer', initContainerImage: 'ppiper/cf-cli@sha256:latest', dockerImage: 'maven:3.5-jdk-8-alpine', diff --git a/test/groovy/FioriOnCloudPlatformPipelineTest.groovy b/test/groovy/FioriOnCloudPlatformPipelineTest.groovy index f6223e727..8f603f7b4 100644 --- a/test/groovy/FioriOnCloudPlatformPipelineTest.groovy +++ b/test/groovy/FioriOnCloudPlatformPipelineTest.groovy @@ -75,6 +75,7 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest { .withCredentials('CI_CREDENTIALS_ID', 'foo', 'terceSpot')) private writeInfluxMap = [:] + def utilsMock class JenkinsUtilsMock extends JenkinsUtils { def isJobStartedByUser() { @@ -108,21 +109,27 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest { m -> m.script.commonPipelineEnvironment.mtarFilePath = 'test.mtar' }) - Utils.metaClass.echo = { def m -> } - helper.registerAllowedMethod('influxWriteData', [Map.class], { m -> writeInfluxMap = m }) + utilsMock = newUtilsMock() + UUID.metaClass.static.randomUUID = { -> 1 } } @After public void tearDown() { - Utils.metaClass = null UUID.metaClass = null } + Utils newUtilsMock() { + def utilsMock = new Utils() + utilsMock.steps = [ stash : { } ] + utilsMock.echo = { def m -> } + return utilsMock + } + @Test void straightForwardTestNeo() { @@ -142,7 +149,7 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest { ] ] - stepRule.step.fioriOnCloudPlatformPipeline(script: nullScript) + stepRule.step.fioriOnCloudPlatformPipeline(script: nullScript, utils: utilsMock) // // the deployable is exchanged between the involved steps via this property: @@ -192,9 +199,7 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest { ] ] - stepRule.step.fioriOnCloudPlatformPipeline( - script: nullScript, - ) + stepRule.step.fioriOnCloudPlatformPipeline(script: nullScript, utils: utilsMock) assertThat(calledStep, is('cloudFoundryDeploy')) } @@ -217,7 +222,7 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest { thrown.expect(Exception) thrown.expectMessage('Deployment failed: no valid deployment target defined') - stepRule.step.fioriOnCloudPlatformPipeline(script: nullScript) + stepRule.step.fioriOnCloudPlatformPipeline(script: nullScript, utils: utilsMock) } @@ -237,6 +242,6 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest { thrown.expect(Exception) thrown.expectMessage('Deployment failed: no valid deployment target defined') - stepRule.step.fioriOnCloudPlatformPipeline(script: nullScript) + stepRule.step.fioriOnCloudPlatformPipeline(script: nullScript, utils: utilsMock) } } diff --git a/test/groovy/SetupCommonPipelineEnvironmentTest.groovy b/test/groovy/SetupCommonPipelineEnvironmentTest.groovy index f0c656c2c..8ea739051 100644 --- a/test/groovy/SetupCommonPipelineEnvironmentTest.groovy +++ b/test/groovy/SetupCommonPipelineEnvironmentTest.groovy @@ -26,6 +26,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { def usedConfigFile def pipelineAndTestStashIncludes + def utilsMock private JenkinsStepRule stepRule = new JenkinsStepRule(this) private JenkinsWriteFileRule writeFileRule = new JenkinsWriteFileRule(this) @@ -44,7 +45,6 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { .around(readFileRule) .around(loggingRule) - @Before void init() { @@ -87,18 +87,17 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { usedConfigFile = parameters.file return yamlParser.load(examplePipelineConfig) }) - - helper.registerAllowedMethod("stash", [Map], { Map params -> - pipelineAndTestStashIncludes = params.includes - }) - - Utils.metaClass.echo = { def m -> } + utilsMock = newUtilsMock() } - - @After - public void tearDown() { - Utils.metaClass = null + Utils newUtilsMock() { + def utilsMock = new Utils() + utilsMock.steps = [ + stash : { Map params -> pipelineAndTestStashIncludes = params.includes }, + unstash: { } + ] + utilsMock.echo = { def m -> } + return utilsMock } @Test @@ -108,7 +107,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { return path.endsWith('.pipeline/config.yml') }) - stepRule.step.setupCommonPipelineEnvironment(script: nullScript) + stepRule.step.setupCommonPipelineEnvironment(script: nullScript, utils: utilsMock) assertEquals('.pipeline/config.yml', usedConfigFile) assertNotNull(nullScript.commonPipelineEnvironment.configuration) @@ -124,7 +123,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { return path.endsWith('.pipeline/config.yaml') }) - stepRule.step.setupCommonPipelineEnvironment(script: nullScript) + stepRule.step.setupCommonPipelineEnvironment(script: nullScript, utils: utilsMock) assertEquals('.pipeline/config.yaml', usedConfigFile) assertNotNull(nullScript.commonPipelineEnvironment.configuration) @@ -140,7 +139,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { return path.endsWith('pipeline_config.yml') }) - stepRule.step.setupCommonPipelineEnvironment(script: nullScript, configFile: 'pipeline_config.yml') + stepRule.step.setupCommonPipelineEnvironment(script: nullScript, utils: utilsMock, configFile: 'pipeline_config.yml') assertEquals('pipeline_config.yml', usedConfigFile) assertNotNull(nullScript.commonPipelineEnvironment.configuration) @@ -172,6 +171,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { stepRule.step.setupCommonPipelineEnvironment( script: nullScript, + utils: utilsMock, customDefaults: 'notFound.yml' ) } @@ -205,6 +205,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { stepRule.step.setupCommonPipelineEnvironment( script: nullScript, + utils: utilsMock, configFile: '.pipeline/config-with-custom-defaults.yml' ) @@ -252,6 +253,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { stepRule.step.setupCommonPipelineEnvironment( script: nullScript, + utils: utilsMock, customDefaults: 'custom.yml', configFile: '.pipeline/config-with-custom-defaults.yml', ) @@ -311,7 +313,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { def dummyScmInfo = [GIT_COMMIT: 'dummy_git_commit_id', GIT_URL: 'https://github.com/testOrg/testRepo.git'] - stepRule.step.setupCommonPipelineEnvironment(script: nullScript, scmInfo: dummyScmInfo, gitUtils: gitUtils) + stepRule.step.setupCommonPipelineEnvironment(script: nullScript, utils: utilsMock, scmInfo: dummyScmInfo, gitUtils: gitUtils) assertThat(nullScript.commonPipelineEnvironment.gitCommitId, is('dummy_git_commit_id')) } @@ -330,7 +332,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { def dummyScmInfo = [GIT_COMMIT: 'dummy_git_commit_id', GIT_BRANCH: 'origin/testbranch'] - stepRule.step.setupCommonPipelineEnvironment(script: nullScript, scmInfo: dummyScmInfo, gitUtils: gitUtils) + stepRule.step.setupCommonPipelineEnvironment(script: nullScript, utils: utilsMock, scmInfo: dummyScmInfo, gitUtils: gitUtils) assertThat(nullScript.commonPipelineEnvironment.gitRef, is('refs/heads/testbranch')) } @@ -353,7 +355,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { def dummyScmInfo = [GIT_COMMIT: 'dummy_git_commit_id', GIT_BRANCH: 'PR-42'] - stepRule.step.setupCommonPipelineEnvironment(script: nullScript, scmInfo: dummyScmInfo, gitUtils: gitUtils) + stepRule.step.setupCommonPipelineEnvironment(script: nullScript, utils: utilsMock, scmInfo: dummyScmInfo, gitUtils: gitUtils) assertThat(nullScript.commonPipelineEnvironment.gitRef, is('refs/pull/42/head')) assertThat(nullScript.commonPipelineEnvironment.gitRemoteCommitId, is('dummy_git_commit_id')) } @@ -377,7 +379,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { def dummyScmInfo = [GIT_COMMIT: 'dummy_git_commit_id', GIT_BRANCH: 'PR-42'] - stepRule.step.setupCommonPipelineEnvironment(script: nullScript, scmInfo: dummyScmInfo, gitUtils: gitUtils) + stepRule.step.setupCommonPipelineEnvironment(script: nullScript, utils: utilsMock, scmInfo: dummyScmInfo, gitUtils: gitUtils) assertThat(nullScript.commonPipelineEnvironment.gitRef, is('refs/pull/42/merge')) assertThat(nullScript.commonPipelineEnvironment.gitRemoteCommitId, is('dummy_merge_git_commit_id')) } @@ -401,7 +403,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { def dummyScmInfo = [GIT_COMMIT: 'dummy_git_commit_id', GIT_BRANCH: 'PR-42'] - stepRule.step.setupCommonPipelineEnvironment(script: nullScript, scmInfo: dummyScmInfo, gitUtils: gitUtils) + stepRule.step.setupCommonPipelineEnvironment(script: nullScript, utils: utilsMock, scmInfo: dummyScmInfo, gitUtils: gitUtils) assertThat(nullScript.commonPipelineEnvironment.gitRef, is('refs/pull/42/merge')) assertThat(nullScript.commonPipelineEnvironment.gitRemoteCommitId, is('NA')) } @@ -412,7 +414,7 @@ class SetupCommonPipelineEnvironmentTest extends BasePiperTest { return path.endsWith('.pipeline/config.yml') }) - stepRule.step.setupCommonPipelineEnvironment(script: nullScript) + stepRule.step.setupCommonPipelineEnvironment(script: nullScript, utils: utilsMock) assertNull(nullScript.commonPipelineEnvironment.gitCommitId) assertNull(nullScript.commonPipelineEnvironment.getGitSshUrl()) assertNull(nullScript.commonPipelineEnvironment.getGitHttpsUrl()) diff --git a/test/groovy/com/sap/piper/UtilsTest.groovy b/test/groovy/com/sap/piper/UtilsTest.groovy index ce46d6ff7..5c34863aa 100644 --- a/test/groovy/com/sap/piper/UtilsTest.groovy +++ b/test/groovy/com/sap/piper/UtilsTest.groovy @@ -237,6 +237,17 @@ class UtilsTest extends BasePiperTest { return examinee } + private def newExamineeRememberingLastStashProperties() { + Map stashProperties = [:] + Utils examinee = newExaminee( + stashClosure: { Map stashProps -> + stashProperties.clear() + stashProperties << stashProps + } + ) + return [examinee, stashProperties] + } + @Test void testAppendNonExistingParameterToStringList() { Map parameters = [:] @@ -264,4 +275,144 @@ class UtilsTest extends BasePiperTest { List result = Utils.appendParameterToStringList(['string'], parameters, 'param') assertEquals(['string'], result) } + + @Test + void testStash_noParentheses() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + + examinee.stash 'test' + + assertEquals([name: 'test', includes: '**/*.*', excludes: ''], stashProperties) + } + + @Test + void testStashAndLog_noParentheses() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + + examinee.stash name: 'test' + + assertEquals([name: 'test', includes: '**/*.*', excludes: ''], stashProperties) + } + + @Test + void testStash_simpleSignature1Param() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + Map expected = [name: 'test', includes: '**/*.*', excludes: ''] + + examinee.stash('test') + assertEquals(expected, stashProperties) + + examinee.stash(name: 'test') + assertEquals(expected, stashProperties) + } + + @Test + void testStash_simpleSignature2Params() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + Map expected = [name: 'test', includes: 'includesX', excludes: ''] + + examinee.stash('test', 'includesX') + assertEquals(expected, stashProperties) + + examinee.stash(name: 'test', includes: 'includesX') + assertEquals(expected, stashProperties) + } + + @Test + void testStash_simpleSignature3Params() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + Map expected = [name: 'test', includes: 'includesX', excludes: 'excludesX'] + + examinee.stash('test', 'includesX', 'excludesX') + assertEquals(expected, stashProperties) + + examinee.stash(name: 'test', includes: 'includesX', excludes: 'excludesX') + assertEquals(expected, stashProperties) + } + + @Test + void testStash_simpleSignature4Params() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + Map expected = [name: 'test', includes: 'includesX', excludes: 'excludesX', useDefaultExcludes: false] + + examinee.stash('test', 'includesX', 'excludesX', false) + assertEquals(expected, stashProperties) + + examinee.stash(name: 'test', includes: 'includesX', excludes: 'excludesX', useDefaultExcludes: false) + assertEquals(expected, stashProperties) + } + + @Test + void testStash_simpleSignature5Params() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + Map expected = [name: 'test', includes: 'includesX', excludes: 'excludesX', useDefaultExcludes: false, allowEmpty: true] + + examinee.stash('test', 'includesX', 'excludesX', false, true) + assertEquals(expected, stashProperties) + + examinee.stash(name: 'test', includes: 'includesX', excludes: 'excludesX', useDefaultExcludes: false, allowEmpty: true) + assertEquals(expected, stashProperties) + } + + @Test + void testStash_explicitDefaults() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + Map expected = [name: 'test', includes: 'includesX', excludes: 'excludesX'] + + examinee.stash('test', 'includesX', 'excludesX', true, false) + assertEquals(expected, stashProperties) + + examinee.stash(name: 'test', includes: 'includesX', excludes: 'excludesX', useDefaultExcludes: true, allowEmpty: false) + assertEquals(expected, stashProperties) + } + + @Test(expected = IllegalArgumentException.class) + void testStashAndLog_noName_fails() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + + examinee.stash([:]) + + assertEquals([includes: 'includesX'], stashProperties) + } + + @Test + void testStashAndLog_includes() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + + examinee.stash(name: 'test', includes: 'includesX') + + assertEquals([name: 'test', includes: 'includesX', excludes: ''], stashProperties) + } + + @Test + void testStashAndLog_excludes() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + + examinee.stash(name: 'test', excludes: 'excludesX') + + assertEquals([name: 'test', includes: '**/*.*', excludes: 'excludesX'], stashProperties) + } + + @Test + void testStashAndLog_useDefaultExcludes() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + + examinee.stash(name: 'test', useDefaultExcludes: true) + assertEquals([name: 'test', includes: '**/*.*', excludes: ''], stashProperties) + + examinee.stash(name: 'test', useDefaultExcludes: false) + assertEquals([name: 'test', includes: '**/*.*', excludes: '', useDefaultExcludes: false], stashProperties) + } + + @Test + void testStashAndLog_allowEmpty() { + final def (Utils examinee, Map stashProperties) = newExamineeRememberingLastStashProperties() + + examinee.stash(name: 'test', allowEmpty: true) + assertEquals([name: 'test', includes: '**/*.*', excludes: '', allowEmpty: true], stashProperties) + + examinee.stash(name: 'test', allowEmpty: false) + assertEquals([name: 'test', includes: '**/*.*', excludes: ''], stashProperties) + } + } diff --git a/vars/dockerExecute.groovy b/vars/dockerExecute.groovy index cf858112c..0ccafce93 100644 --- a/vars/dockerExecute.groovy +++ b/vars/dockerExecute.groovy @@ -166,7 +166,7 @@ void call(Map parameters = [:], body) { SidecarUtils sidecarUtils = new SidecarUtils(script) - new Utils().pushToSWA([ + utils.pushToSWA([ step: STEP_NAME, stepParamKey1: 'scriptMissing', stepParam1: parameters?.script == null, diff --git a/vars/dockerExecuteOnKubernetes.groovy b/vars/dockerExecuteOnKubernetes.groovy index dbf17a537..6aecd7b40 100644 --- a/vars/dockerExecuteOnKubernetes.groovy +++ b/vars/dockerExecuteOnKubernetes.groovy @@ -307,7 +307,7 @@ void executeOnPod(Map config, utils, Closure body, Script script) { def stashContent = config.stashContent boolean defaultStashCreated = false if (config.containerName && stashContent.isEmpty()) { - stashContent = [stashWorkspace(config, 'workspace')] + stashContent = [stashWorkspace(config, utils, 'workspace')] defaultStashCreated = true } podTemplate(getOptions(config)) { @@ -328,7 +328,7 @@ void executeOnPod(Map config, utils, Closure body, Script script) { lsDir('Directory content before body execution') } if (defaultStashCreated) { - invalidateStash(config, 'workspace') + invalidateStash(config, 'workspace', utils) } def result = body() if (config.verbose) { @@ -336,7 +336,7 @@ void executeOnPod(Map config, utils, Closure body, Script script) { } return result } finally { - stashWorkspace(config, 'container', true, true) + stashWorkspace(config, utils, 'container', true, true) } } } else { @@ -386,7 +386,7 @@ private String generatePodSpec(Map config) { return new JsonUtils().groovyObjectToPrettyJsonString(podSpec) } -private String stashWorkspace(config, prefix, boolean chown = false, boolean stashBack = false) { +private String stashWorkspace(config, utils, prefix, boolean chown = false, boolean stashBack = false) { def stashName = "${prefix}-${config.uniqueId}" try { if (chown) { @@ -417,7 +417,7 @@ chown -R ${runAsUser}:${fsGroup} .""" echo "stash effective (excludes): ${excludes}" } - stash( + utils.stash( name: stashName, includes: includes, excludes: excludes, @@ -463,7 +463,7 @@ private void unstashWorkspace(config, utils, prefix) { echo "Unstash workspace failed with throwable ${e.getMessage()}" throw e } finally { - invalidateStash(config, prefix) + invalidateStash(config, prefix, utils) } } @@ -639,8 +639,8 @@ private List getContainerEnvs(config, imageName, defaultEnvVars, defaultConfig) return containerEnv } -private void invalidateStash(def config, String prefix) { - String name = "${prefix}-${config.uniqueId}" - echo "invalidate stash ${name}" - stash name: name, excludes: '**/*', allowEmpty: true +private void invalidateStash(def config, String prefix, def utils) { + String name = "${prefix}-${config.uniqueId}" + echo "invalidate stash ${name}" + utils.stash name: name, excludes: '**/*', allowEmpty: true } diff --git a/vars/fioriOnCloudPlatformPipeline.groovy b/vars/fioriOnCloudPlatformPipeline.groovy index 00e56cda7..ef0ef6fb8 100644 --- a/vars/fioriOnCloudPlatformPipeline.groovy +++ b/vars/fioriOnCloudPlatformPipeline.groovy @@ -22,6 +22,7 @@ import groovy.transform.Field void call(parameters = [:]) { checkScript(this, parameters) + if(parameters.utils != null) parameters.juStabUtils = parameters.utils //named differently in steps node(parameters.label) { diff --git a/vars/neoDeploy.groovy b/vars/neoDeploy.groovy index 0906cf812..82867c7f1 100644 --- a/vars/neoDeploy.groovy +++ b/vars/neoDeploy.groovy @@ -227,6 +227,7 @@ void call(parameters = [:]) { dockerExecute( script: script, + juStabUtils: parameters.utils ?: null, dockerImage: configuration.dockerImage, dockerEnvVars: configuration.dockerEnvVars, dockerOptions: configuration.dockerOptions diff --git a/vars/piperExecuteBin.groovy b/vars/piperExecuteBin.groovy index f9ae3b1d9..87eec381a 100644 --- a/vars/piperExecuteBin.groovy +++ b/vars/piperExecuteBin.groovy @@ -87,7 +87,7 @@ void call(Map parameters = [:], String stepName, String metadataFile, List crede } } finally { InfluxData.readFromDisk(script) - stash name: 'pipelineStepReports', includes: '.pipeline/stepReports/**', allowEmpty: true + utils.stash name: 'pipelineStepReports', includes: '.pipeline/stepReports/**', allowEmpty: true } } } diff --git a/vars/setupCommonPipelineEnvironment.groovy b/vars/setupCommonPipelineEnvironment.groovy index 429e1d8e3..f3f90c0b1 100644 --- a/vars/setupCommonPipelineEnvironment.groovy +++ b/vars/setupCommonPipelineEnvironment.groovy @@ -57,6 +57,7 @@ void call(Map parameters = [:]) { handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters) { def script = checkScript(this, parameters) + def utils = parameters.utils ?: new Utils() String configFile = parameters.get('configFile') loadConfigurationFromFile(script, configFile) @@ -97,7 +98,7 @@ void call(Map parameters = [:]) { if (configFile && !configFile.startsWith('.pipeline/')) { stashIncludes += ", $configFile" } - stash name: 'pipelineConfigAndTests', includes: stashIncludes, allowEmpty: true + utils.stash name: 'pipelineConfigAndTests', includes: stashIncludes, allowEmpty: true Map config = ConfigurationHelper.newInstance(this) .loadStepDefaults() @@ -106,7 +107,7 @@ void call(Map parameters = [:]) { inferBuildTool(script, config) - (parameters.utils ?: new Utils()).pushToSWA([ + utils.pushToSWA([ step: STEP_NAME, stepParamKey4: 'customDefaults', stepParam4: parameters.customDefaults?'true':'false'