1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00
sap-jenkins-library/test/groovy/DockerExecuteTest.groovy

368 lines
14 KiB
Groovy

import com.sap.piper.k8s.ContainerMap
import com.sap.piper.JenkinsUtils
import com.sap.piper.SidecarUtils
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import util.BasePiperTest
import util.JenkinsLoggingRule
import util.JenkinsReadYamlRule
import util.JenkinsShellCallRule
import util.JenkinsStepRule
import util.PluginMock
import util.Rules
import static org.hamcrest.Matchers.*
import static org.junit.Assert.assertThat
import static org.junit.Assert.assertTrue
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertFalse
class DockerExecuteTest extends BasePiperTest {
private DockerMock docker
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
@Rule
public RuleChain ruleChain = Rules
.getCommonRules(this)
.around(new JenkinsReadYamlRule(this))
.around(loggingRule)
.around(stepRule)
.around(shellRule)
def bodyExecuted
def containerName
@Before
void init() {
bodyExecuted = false
docker = new DockerMock()
JenkinsUtils.metaClass.static.isPluginActive = { def s -> new PluginMock(s).isActive() }
binding.setVariable('docker', docker)
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, "docker .*", 0)
}
@Test
void testExecuteInsideContainerOfExistingPod() throws Exception {
List usedDockerEnvVars
helper.registerAllowedMethod('container', [String.class, Closure.class], { String container, Closure body ->
containerName = container
body()
})
helper.registerAllowedMethod('withEnv', [List.class, Closure.class], { List envVars, Closure body ->
usedDockerEnvVars = envVars
body()
})
binding.setVariable('env', [POD_NAME: 'testpod', ON_K8S: 'true'])
ContainerMap.instance.setMap(['testpod': ['maven:3.5-jdk-8-alpine': 'mavenexec']])
stepRule.step.dockerExecute(script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine',
dockerEnvVars: ['http_proxy': 'http://proxy:8000']) {
bodyExecuted = true
}
assertTrue(loggingRule.log.contains('Executing inside a Kubernetes Container'))
assertEquals('mavenexec', containerName)
assertEquals(usedDockerEnvVars[0].toString(), "http_proxy=http://proxy:8000")
assertTrue(bodyExecuted)
}
@Test
void testExecuteInsideNewlyCreatedPod() throws Exception {
helper.registerAllowedMethod('dockerExecuteOnKubernetes', [Map.class, Closure.class], { Map config, Closure body -> body() })
binding.setVariable('env', [ON_K8S: 'true'])
ContainerMap.instance.setMap(['testpod': ['maven:3.5-jdk-8-alpine': 'mavenexec']])
stepRule.step.dockerExecute(script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine',
dockerEnvVars: ['http_proxy': 'http://proxy:8000']) {
bodyExecuted = true
}
assertTrue(loggingRule.log.contains('Executing inside a Kubernetes Pod'))
assertTrue(bodyExecuted)
}
@Test
void testExecuteInsidePodWithEmptyContainerMap() throws Exception {
helper.registerAllowedMethod('dockerExecuteOnKubernetes', [Map.class, Closure.class], { Map config, Closure body -> body() })
binding.setVariable('env', [POD_NAME: 'testpod', ON_K8S: 'true'])
ContainerMap.instance.setMap([:])
stepRule.step.dockerExecute(script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine',
dockerEnvVars: ['http_proxy': 'http://proxy:8000']) {
bodyExecuted = true
}
assertTrue(loggingRule.log.contains('Executing inside a Kubernetes Pod'))
assertTrue(bodyExecuted)
}
@Test
void testExecuteInsidePodWithStageKeyEmptyValue() throws Exception {
helper.registerAllowedMethod('dockerExecuteOnKubernetes', [Map.class, Closure.class], { Map config, Closure body -> body() })
binding.setVariable('env', [POD_NAME: 'testpod', ON_K8S: 'true'])
ContainerMap.instance.setMap(['testpod': [:]])
stepRule.step.dockerExecute(script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine',
dockerEnvVars: ['http_proxy': 'http://proxy:8000']) {
bodyExecuted = true
}
assertTrue(loggingRule.log.contains('Executing inside a Kubernetes Pod'))
assertTrue(bodyExecuted)
}
@Test
void testExecuteInsidePodWithCustomCommandAndShell() throws Exception {
Map kubernetesConfig = [:]
helper.registerAllowedMethod('dockerExecuteOnKubernetes', [Map.class, Closure.class], { Map config, Closure body ->
kubernetesConfig = config
return body()
})
binding.setVariable('env', [ON_K8S: 'true'])
stepRule.step.dockerExecute(
script: nullScript,
containerCommand: '/busybox/tail -f /dev/null',
containerShell: '/busybox/sh',
dockerImage: 'maven:3.5-jdk-8-alpine'
) {
bodyExecuted = true
}
assertTrue(loggingRule.log.contains('Executing inside a Kubernetes Pod'))
assertThat(kubernetesConfig.containerCommand, is('/busybox/tail -f /dev/null'))
assertThat(kubernetesConfig.containerShell, is('/busybox/sh'))
assertTrue(bodyExecuted)
}
@Test
void testExecuteInsideDockerContainer() throws Exception {
stepRule.step.dockerExecute(script: nullScript, dockerImage: 'maven:3.5-jdk-8-alpine') {
bodyExecuted = true
}
assertEquals('maven:3.5-jdk-8-alpine', docker.getImageName())
assertTrue(docker.isImagePulled())
assertEquals('--env http_proxy --env https_proxy --env no_proxy --env HTTP_PROXY --env HTTPS_PROXY --env NO_PROXY', docker.getParameters().trim())
assertTrue(bodyExecuted)
}
@Test
void testSkipDockerImagePull() throws Exception {
nullScript.commonPipelineEnvironment.configuration = [steps: [dockerExecute: [dockerPullImage: false]]]
stepRule.step.dockerExecute(
script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine'
) {
bodyExecuted = true
}
assertThat(docker.imagePullCount, is(0))
assertThat(bodyExecuted, is(true))
}
@Test
void testSkipSidecarImagePull() throws Exception {
stepRule.step.dockerExecute(
script: nullScript,
dockerName: 'maven',
dockerImage: 'maven:3.5-jdk-8-alpine',
sidecarEnvVars: ['testEnv': 'testVal'],
sidecarImage: 'selenium/standalone-chrome',
sidecarVolumeBind: ['/dev/shm': '/dev/shm'],
sidecarName: 'testAlias',
sidecarPorts: ['4444': '4444', '1111': '1111'],
sidecarPullImage: false
) {
bodyExecuted = true
}
assertThat(docker.imagePullCount, is(1))
assertThat(bodyExecuted, is(true))
}
@Test
void testExecuteInsideDockerContainerWithParameters() throws Exception {
stepRule.step.dockerExecute(script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine',
dockerOptions: '-description=lorem ipsum',
dockerVolumeBind: ['my_vol': '/my_vol'],
dockerEnvVars: ['http_proxy': 'http://proxy:8000']) {
bodyExecuted = true
}
assertTrue(docker.getParameters().contains('--env https_proxy '))
assertTrue(docker.getParameters().contains('--env http_proxy=http://proxy:8000'))
assertTrue(docker.getParameters().contains('description=lorem\\ ipsum'))
assertTrue(docker.getParameters().contains('--volume my_vol:/my_vol'))
assertTrue(bodyExecuted)
}
@Test
void testExecuteInsideDockerContainerWithDockerOptionsList() throws Exception {
stepRule.step.dockerExecute(script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine',
dockerOptions: ['-it', '--network=my-network', 'description=lorem ipsum'],
dockerEnvVars: ['http_proxy': 'http://proxy:8000']) {
bodyExecuted = true
}
assertTrue(docker.getParameters().contains('--env http_proxy=http://proxy:8000'))
assertTrue(docker.getParameters().contains('-it'))
assertTrue(docker.getParameters().contains('--network=my-network'))
assertTrue(docker.getParameters().contains('description=lorem\\ ipsum'))
}
@Test
void testDockerNotInstalledResultsInLocalExecution() throws Exception {
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, "docker .*", 1)
stepRule.step.dockerExecute(script: nullScript,
dockerOptions: '-it') {
bodyExecuted = true
}
assertTrue(loggingRule.log.contains('Cannot connect to docker daemon'))
assertTrue(loggingRule.log.contains('Running on local environment'))
assertTrue(bodyExecuted)
assertFalse(docker.isImagePulled())
}
@Test
void testSidecarDefault() {
stepRule.step.dockerExecute(
script: nullScript,
dockerName: 'maven',
dockerImage: 'maven:3.5-jdk-8-alpine',
sidecarEnvVars: ['testEnv': 'testVal'],
sidecarImage: 'selenium/standalone-chrome',
sidecarVolumeBind: ['/dev/shm': '/dev/shm'],
sidecarName: 'testAlias',
sidecarPorts: ['4444': '4444', '1111': '1111']
) {
bodyExecuted = true
}
assertThat(bodyExecuted, is(true))
assertThat(docker.imagePullCount, is(2))
assertThat(docker.sidecarParameters, allOf(
containsString('--env testEnv=testVal'),
containsString('--volume /dev/shm:/dev/shm'),
containsString('--network sidecar-'),
containsString('--network-alias testAlias')
))
assertThat(docker.parameters, allOf(
containsString('--network sidecar-'),
containsString('--network-alias maven')
))
}
@Test
void testSidecarHealthCheck() {
stepRule.step.dockerExecute(
script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine',
sidecarImage: 'selenium/standalone-chrome',
sidecarName: 'testAlias',
sidecarReadyCommand: "isReady.sh"
) {}
assertThat(shellRule.shell, hasItem("docker exec uniqueId isReady.sh"))
}
@Test
void testSidecarKubernetes() {
boolean dockerExecuteOnKubernetesCalled = false
binding.setVariable('env', [ON_K8S: 'true'])
helper.registerAllowedMethod('dockerExecuteOnKubernetes', [Map.class, Closure.class], { params, body ->
dockerExecuteOnKubernetesCalled = true
assertThat(params.dockerImage, is('maven:3.5-jdk-8-alpine'))
assertThat(params.containerName, is('maven'))
assertThat(params.sidecarEnvVars, is(['testEnv': 'testVal']))
assertThat(params.sidecarName, is('selenium'))
assertThat(params.sidecarImage, is('selenium/standalone-chrome'))
assertThat(params.containerName, is('maven'))
assertThat(params.containerPortMappings['selenium/standalone-chrome'], hasItem(allOf(hasEntry('containerPort', 4444), hasEntry('hostPort', 4444))))
assertThat(params.dockerWorkspace, is('/home/piper'))
body()
})
stepRule.step.dockerExecute(
script: nullScript,
containerPortMappings: [
'selenium/standalone-chrome': [[name: 'selPort', containerPort: 4444, hostPort: 4444]]
],
dockerImage: 'maven:3.5-jdk-8-alpine',
dockerName: 'maven',
dockerWorkspace: '/home/piper',
sidecarEnvVars: ['testEnv': 'testVal'],
sidecarImage: 'selenium/standalone-chrome',
sidecarName: 'selenium',
sidecarVolumeBind: ['/dev/shm': '/dev/shm']
) {
bodyExecuted = true
}
assertThat(bodyExecuted, is(true))
assertThat(dockerExecuteOnKubernetesCalled, is(true))
}
@Test
void testSidecarKubernetesHealthCheck() {
binding.setVariable('env', [ON_K8S: 'true'])
helper.registerAllowedMethod('dockerExecuteOnKubernetes', [Map.class, Closure.class], { params, body ->
body()
SidecarUtils sidecarUtils = new SidecarUtils(nullScript)
sidecarUtils.waitForSidecarReadyOnKubernetes(params.sidecarName, params.sidecarReadyCommand)
})
def containerCalled = false
helper.registerAllowedMethod('container', [Map.class, Closure.class], { params, body ->
containerCalled = true
assertThat(params.name, is('testAlias'))
body()
})
stepRule.step.dockerExecute(
script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine',
sidecarImage: 'selenium/standalone-chrome',
sidecarName: 'testAlias',
sidecarReadyCommand: "isReady.sh"
) {}
assertThat(containerCalled, is(true))
assertThat(shellRule.shell, hasItem("isReady.sh"))
}
private class DockerMock {
private String imageName
private boolean imagePulled = false
private int imagePullCount = 0
private String parameters
private String sidecarParameters
DockerMock image(String imageName) {
this.imageName = imageName
return this
}
void pull() {
imagePullCount++
imagePulled = true
}
void inside(String parameters, body) {
this.parameters = parameters
body()
}
void withRun(String parameters, body) {
this.sidecarParameters = parameters
body([id: 'uniqueId'])
}
String getImageName() {
return imageName
}
boolean isImagePulled() {
return imagePulled
}
String getParameters() {
return parameters
}
}
}