mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-14 11:03:09 +02:00
1b202f879a
* Provide flag for skipping docker image pulls Usefull for testing while developing images. Without pulling images it is possible to use images available in the local registry only.
318 lines
12 KiB
Groovy
318 lines
12 KiB
Groovy
import com.sap.piper.k8s.ContainerMap
|
|
import com.sap.piper.JenkinsUtils
|
|
|
|
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.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)
|
|
|
|
@Rule
|
|
public RuleChain ruleChain = Rules
|
|
.getCommonRules(this)
|
|
.around(new JenkinsReadYamlRule(this))
|
|
.around(loggingRule)
|
|
.around(stepRule)
|
|
|
|
int dockerPsReturnValue = 0
|
|
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)
|
|
helper.registerAllowedMethod('sh', [Map.class], {return dockerPsReturnValue})
|
|
}
|
|
|
|
@Test
|
|
void testExecuteInsideContainerOfExistingPod() throws Exception {
|
|
helper.registerAllowedMethod('container', [String.class, Closure.class], { String container, Closure body ->
|
|
containerName = container
|
|
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)
|
|
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 {
|
|
dockerPsReturnValue = 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 testSidecarKubernetes(){
|
|
boolean dockerExecuteOnKubernetesCalled = false
|
|
binding.setVariable('env', [ON_K8S: 'true'])
|
|
helper.registerAllowedMethod('dockerExecuteOnKubernetes', [Map.class, Closure.class], { params, body ->
|
|
dockerExecuteOnKubernetesCalled = true
|
|
assertThat(params.containerCommands['selenium/standalone-chrome'], is(''))
|
|
assertThat(params.containerEnvVars, allOf(hasEntry('selenium/standalone-chrome', ['testEnv': 'testVal']),hasEntry('maven:3.5-jdk-8-alpine', null)))
|
|
assertThat(params.containerMap, allOf(hasEntry('maven:3.5-jdk-8-alpine', 'maven'), hasEntry('selenium/standalone-chrome', 'selenium')))
|
|
assertThat(params.containerName, is('maven'))
|
|
assertThat(params.containerPortMappings['selenium/standalone-chrome'], hasItem(allOf(hasEntry('containerPort', 4444), hasEntry('hostPort', 4444))))
|
|
assertThat(params.containerWorkspaces['maven:3.5-jdk-8-alpine'], is('/home/piper'))
|
|
assertThat(params.containerWorkspaces['selenium/standalone-chrome'], is(''))
|
|
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))
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
}
|