diff --git a/src/com/sap/piper/DebugReport.groovy b/src/com/sap/piper/DebugReport.groovy index 9bd193f86..aea9609ab 100644 --- a/src/com/sap/piper/DebugReport.groovy +++ b/src/com/sap/piper/DebugReport.groovy @@ -42,6 +42,9 @@ class DebugReport implements Serializable { String dockerImage = EnvironmentUtils.getDockerFile(serverConfigContents) environment.put('docker_image', dockerImage) } + else if(Boolean.valueOf(env.ON_K8S)){ + DebugReport.instance.environment.put("environment", "Kubernetes") + } } private static String getServerConfigContents(String... possibleFileLocations) { diff --git a/test/groovy/DockerExecuteOnKubernetesTest.groovy b/test/groovy/DockerExecuteOnKubernetesTest.groovy index a4b3df9a3..1f6b920f9 100644 --- a/test/groovy/DockerExecuteOnKubernetesTest.groovy +++ b/test/groovy/DockerExecuteOnKubernetesTest.groovy @@ -75,8 +75,11 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { containerCommands = [] bodyExecuted = false JenkinsUtils.metaClass.static.isPluginActive = { def s -> new PluginMock(s).isActive() } - helper.registerAllowedMethod('sh', [Map.class], {return whichDockerReturnValue}) - helper.registerAllowedMethod('container', [Map.class, Closure.class], { Map config, Closure body -> container(config){body()} + helper.registerAllowedMethod('sh', [Map.class], { return whichDockerReturnValue }) + helper.registerAllowedMethod('container', [Map.class, Closure.class], { Map config, Closure body -> + container(config) { + body() + } }) helper.registerAllowedMethod('merge', [], { return 'merge' @@ -96,7 +99,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { containersList.add(container.name) imageList.add(container.image.toString()) envList.add(container.env) - if(container.ports) { + if (container.ports) { portList.add(container.ports) } if (container.command) { @@ -106,7 +109,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { } body() }) - helper.registerAllowedMethod('stash', [Map.class], {m -> + helper.registerAllowedMethod('stash', [Map.class], { m -> stashList.add(m) }) @@ -121,7 +124,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { dockerOptions: '-it', dockerVolumeBind: ['my_vol': '/my_vol'], dockerEnvVars: ['http_proxy': 'http://proxy:8000'], dockerWorkspace: '/home/piper' - ){ + ) { bodyExecuted = true } assertThat(containersList, hasItem('container-exec')) @@ -133,6 +136,18 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { assertThat(containerCommands.size(), is(1)) } + @Test + void testDockerExecuteOnKubernetesEmptyContainerMapNoDockerImage() throws Exception { + stepRule.step.dockerExecuteOnKubernetes( + script: nullScript, + juStabUtils: utils, + containerMap: [:], + dockerEnvVars: ['customEnvKey': 'customEnvValue']) { + bodyExecuted = true + } + assertTrue(bodyExecuted) + } + @Test void testDockerExecuteOnKubernetesWithCustomContainerMap() throws Exception { stepRule.step.dockerExecuteOnKubernetes(script: nullScript, @@ -238,25 +253,10 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { assertTrue(bodyExecuted) } - @Test - void testDockerExecuteOnKubernetesEmptyContainerMapNoDockerImage() throws Exception { - exception.expect(IllegalArgumentException.class) - stepRule.step.dockerExecuteOnKubernetes( - script: nullScript, - juStabUtils: utils, - containerMap: [:], - dockerEnvVars: ['customEnvKey': 'customEnvValue']) { - container(name: 'jnlp') { - bodyExecuted = true - } - } - assertFalse(bodyExecuted) - } - @Test void testSidecarDefaultWithContainerMap() { List portMapping = [] - helper.registerAllowedMethod('portMapping', [Map.class], {m -> + helper.registerAllowedMethod('portMapping', [Map.class], { m -> portMapping.add(m) return m }) @@ -268,7 +268,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { 'selenium/standalone-chrome': ['customEnvKey': 'customEnvValue'] ], containerMap: [ - 'maven:3.5-jdk-8-alpine': 'mavenexecute', + 'maven:3.5-jdk-8-alpine' : 'mavenexecute', 'selenium/standalone-chrome': 'selenium' ], containerName: 'mavenexecute', @@ -296,13 +296,13 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { )) assertThat(portList, hasItem([[name: 'selenium0', containerPort: 4444]])) assertThat(containerCommands.size(), is(1)) - assertThat(envList, hasItem(hasItem(allOf(hasEntry('name', 'customEnvKey'), hasEntry ('value','customEnvValue'))))) + assertThat(envList, hasItem(hasItem(allOf(hasEntry('name', 'customEnvKey'), hasEntry('value', 'customEnvValue'))))) } @Test void testSidecarDefaultWithParameters() { List portMapping = [] - helper.registerAllowedMethod('portMapping', [Map.class], {m -> + helper.registerAllowedMethod('portMapping', [Map.class], { m -> portMapping.add(m) return m }) @@ -329,8 +329,8 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { assertThat(containersList, allOf(hasItem('postgres'), hasItem('mavenexecute'))) assertThat(imageList, allOf(hasItem('maven:3.5-jdk-8-alpine'), hasItem('postgres'))) - assertThat(envList, hasItem(hasItem(allOf(hasEntry('name', 'testEnv'), hasEntry ('value','testVal'))))) - assertThat(envList, hasItem(hasItem(allOf(hasEntry('name', 'HOME'), hasEntry ('value','/home/piper/sidecar'))))) + assertThat(envList, hasItem(hasItem(allOf(hasEntry('name', 'testEnv'), hasEntry('value', 'testVal'))))) + assertThat(envList, hasItem(hasItem(allOf(hasEntry('name', 'HOME'), hasEntry('value', '/home/piper/sidecar'))))) } @Test @@ -384,7 +384,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { 'selenium/standalone-chrome': ['customEnvKey': 'customEnvValue'] ], containerMap: [ - 'maven:3.5-jdk-8-alpine': 'mavenexecute', + 'maven:3.5-jdk-8-alpine' : 'mavenexecute', 'selenium/standalone-chrome': 'selenium' ], containerName: 'mavenexecute', @@ -392,7 +392,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { 'selenium/standalone-chrome': '' ], containerPullImageFlags: [ - 'maven:3.5-jdk-8-alpine': true, + 'maven:3.5-jdk-8-alpine' : true, 'selenium/standalone-chrome': false ], dockerWorkspace: '/home/piper' @@ -410,25 +410,25 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { nullScript.commonPipelineEnvironment.configuration = [general: [jenkinsKubernetes: [namespace: expectedNamespace]]] stepRule.step.dockerExecuteOnKubernetes( - script: nullScript, - juStabUtils: utils, - dockerImage: 'maven:3.5-jdk-8-alpine', - ) { bodyExecuted = true } + script: nullScript, + juStabUtils: utils, + dockerImage: 'maven:3.5-jdk-8-alpine', + ) { bodyExecuted = true } assertTrue(bodyExecuted) assertThat(namespace, is(equalTo(expectedNamespace))) } @Test void testDockerExecuteOnKubernetesWithSecurityContext() { - def expectedSecurityContext = [ runAsUser: 1000, fsGroup: 1000 ] + def expectedSecurityContext = [runAsUser: 1000, fsGroup: 1000] nullScript.commonPipelineEnvironment.configuration = [general: [jenkinsKubernetes: [ - securityContext: expectedSecurityContext]]] + securityContext: expectedSecurityContext]]] stepRule.step.dockerExecuteOnKubernetes( - script: nullScript, - juStabUtils: utils, - dockerImage: 'maven:3.5-jdk-8-alpine', - ) { bodyExecuted = true } + script: nullScript, + juStabUtils: utils, + dockerImage: 'maven:3.5-jdk-8-alpine', + ) { bodyExecuted = true } assertTrue(bodyExecuted) assertThat(securityContext, is(equalTo(expectedSecurityContext))) } @@ -536,12 +536,12 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest { } assertThat(stashList, hasItem(allOf( not(hasEntry('allowEmpty', true)), - hasEntry('includes','workspace/include.test'), - hasEntry('excludes','workspace/exclude.test')))) + hasEntry('includes', 'workspace/include.test'), + hasEntry('excludes', 'workspace/exclude.test')))) assertThat(stashList, hasItem(allOf( not(hasEntry('allowEmpty', true)), - hasEntry('includes','container/include.test'), - hasEntry('excludes','container/exclude.test')))) + hasEntry('includes', 'container/include.test'), + hasEntry('excludes', 'container/exclude.test')))) } diff --git a/test/groovy/PiperStageWrapperTest.groovy b/test/groovy/PiperStageWrapperTest.groovy index 1f1ac4538..9755cf84a 100644 --- a/test/groovy/PiperStageWrapperTest.groovy +++ b/test/groovy/PiperStageWrapperTest.groovy @@ -6,12 +6,14 @@ import org.junit.Test import org.junit.rules.ExpectedException import org.junit.rules.RuleChain import util.BasePiperTest +import util.JenkinsEnvironmentRule import util.JenkinsLoggingRule import util.JenkinsReadYamlRule import util.JenkinsStepRule import util.Rules import static org.hamcrest.CoreMatchers.containsString +import static org.hamcrest.Matchers.contains import static org.hamcrest.Matchers.is import static org.hamcrest.Matchers.not import static org.junit.Assert.assertThat @@ -26,6 +28,8 @@ class PiperStageWrapperTest extends BasePiperTest { private Map lockMap = [:] private int countNodeUsage = 0 private String nodeLabel = '' + private boolean executedOnKubernetes = false + private List customEnv = [] @Rule public RuleChain rules = Rules @@ -53,6 +57,18 @@ class PiperStageWrapperTest extends BasePiperTest { body() }) + + helper.registerAllowedMethod('dockerExecuteOnKubernetes', [Map.class, Closure.class], {params, body -> + executedOnKubernetes = true + body() + }) + + helper.registerAllowedMethod('withEnv', [List.class, Closure.class], {env, body -> + customEnv = env + body() + }) + + helper.registerAllowedMethod('fileExists', [String.class], {s -> return false }) @@ -71,6 +87,7 @@ class PiperStageWrapperTest extends BasePiperTest { executed = true } assertThat(executed, is(true)) + assertThat(executedOnKubernetes, is(false)) assertThat(lockMap.size(), is(2)) assertThat(countNodeUsage, is(1)) } @@ -95,6 +112,26 @@ class PiperStageWrapperTest extends BasePiperTest { assertThat(nodeLabel, is('testLabel')) } + @Test + void testExecuteStageOnKubernetes() { + def executed = false + + binding.variables.env.ON_K8S = true + nullScript.commonPipelineEnvironment.configuration = [general: [runStageInPod: true]] + + stepRule.step.piperStageWrapper( + script: nullScript, + juStabUtils: utils, + stageName: 'test', + ordinal: 10 + ) { + executed = true + } + assertThat(executed, is(true)) + assertThat(executedOnKubernetes, is(true)) + assertThat(customEnv[0].toString(), is("POD_NAME=test")) + } + @Test void testStageExit() { helper.registerAllowedMethod('fileExists', [String.class], {s -> diff --git a/test/groovy/com/sap/piper/DebugReportTest.groovy b/test/groovy/com/sap/piper/DebugReportTest.groovy index 14e95d1ca..202f629a1 100644 --- a/test/groovy/com/sap/piper/DebugReportTest.groovy +++ b/test/groovy/com/sap/piper/DebugReportTest.groovy @@ -20,7 +20,7 @@ class DebugReportTest extends BasePiperTest { DebugReport.instance.initFromEnvironment(env) Assert.assertTrue(DebugReport.instance.environment.containsKey('build_details')) - Assert.assertEquals('custom', DebugReport.instance.environment.get('environment')) + Assert.assertEquals('Kubernetes', DebugReport.instance.environment.get('environment')) Set buildDetails = DebugReport.instance.environment.build_details as Set Assert.assertTrue(buildDetails.size() > 0) @@ -48,7 +48,7 @@ class DebugReportTest extends BasePiperTest { Assert.assertTrue(debugReport.contains('## Pipeline Environment')) Assert.assertTrue(debugReport.contains('## Local Extensions')) Assert.assertTrue(debugReport.contains('#### Environment\n' + - '`custom`')) + '`Kubernetes`')) Assert.assertFalse(debugReport.contains('Repository | Branch')) Assert.assertFalse(debugReport.contains('some-branch')) } @@ -63,7 +63,7 @@ class DebugReportTest extends BasePiperTest { Assert.assertTrue(debugReport.contains('## Pipeline Environment')) Assert.assertTrue(debugReport.contains('## Local Extensions')) Assert.assertTrue(debugReport.contains('#### Environment\n' + - '`custom`')) + '`Kubernetes`')) Assert.assertTrue(debugReport.contains('Repository | Branch')) Assert.assertTrue(debugReport.contains('some-branch')) } diff --git a/vars/dockerExecuteOnKubernetes.groovy b/vars/dockerExecuteOnKubernetes.groovy index 54b39c3ef..4fa7f6c74 100644 --- a/vars/dockerExecuteOnKubernetes.groovy +++ b/vars/dockerExecuteOnKubernetes.groovy @@ -83,7 +83,7 @@ import hudson.AbortException */ 'dockerEnvVars', /** - * Name of the docker image that should be used. If empty, Docker is not used. + * Optional name of the docker image that should be used. If no docker image is provided, the closure will be executed in the jnlp agent container. */ 'dockerImage', /** @@ -198,8 +198,7 @@ void call(Map parameters = [:], body) { stepParam1 : parameters?.script == null ], config) - if (!config.containerMap) { - configHelper.withMandatoryProperty('dockerImage') + if (!config.containerMap && config.dockerImage) { config.containerName = 'container-exec' config.containerMap = [(config.get('dockerImage')): config.containerName] config.containerCommands = config.containerCommand ? [(config.get('dockerImage')): config.containerCommand] : null diff --git a/vars/piperStageWrapper.groovy b/vars/piperStageWrapper.groovy index 91a6baaa5..b9e7408b1 100644 --- a/vars/piperStageWrapper.groovy +++ b/vars/piperStageWrapper.groovy @@ -30,8 +30,7 @@ void call(Map parameters = [:], body) { stageLocking(config) { def containerMap = ContainerMap.instance.getMap().get(stageName) ?: [:] - if (Boolean.valueOf(env.ON_K8S) && containerMap.size() > 0) { - DebugReport.instance.environment.put("environment", "Kubernetes") + if (Boolean.valueOf(env.ON_K8S) && (containerMap.size() > 0 || config.runStageInPod)) { withEnv(["POD_NAME=${stageName}"]) { dockerExecuteOnKubernetes(script: script, containerMap: containerMap, stageName: stageName) { executeStage(script, body, stageName, config, utils, parameters.telemetryDisabled)