Skip to content

Commit

Permalink
Merge pull request #42 from puzzle/feature/unitTest-openshiftApply
Browse files Browse the repository at this point in the history
Feature/unit test openshift apply
  • Loading branch information
chrira authored Nov 17, 2021
2 parents 2b64784 + 910636c commit 8fdf5dd
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 4 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
.idea/
.gradle
target
bin
.classpath
.settings
.project
jenkins-pipeline-shared-libraries.iml
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,7 @@ File: [src/com/puzzleitc/jenkins/DockerHub.groovy](src/com/puzzleitc/jenkins/Doc

Tests can be executed with `./gradlew clean test`

Documentation for the test framework can be found here: <https://github.com/ExpediaGroup/jenkins-spock>
Source: [src/com/puzzleitc/jenkins/DockerHub.groovy](src/com/puzzleitc/jenkins/DockerHub.groovy)
* Documentation for the spock test framework can be found here: <https://spockframework.org/>
* Documentation for the Jenkins test framework can be found here: <https://github.com/ExpediaGroup/jenkins-spock>
* [JenkinsPipelineSpecification](https://www.javadoc.io/doc/com.homeaway.devtools.jenkins/jenkins-spock/2.0.1/com/homeaway/devtools/jenkins/testing/JenkinsPipelineSpecification.html)
* Source: [src/com/puzzleitc/jenkins/DockerHub.groovy](src/com/puzzleitc/jenkins/DockerHub.groovy)
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ dependencies {
testImplementation "org.jenkins-ci.plugins.workflow:workflow-scm-step:2.11@jar" // provides checkout()
testImplementation "org.jenkins-ci.plugins:credentials-binding:1.20@jar" // provides withCredentials() step
testImplementation "org.jenkins-ci.plugins:script-security:1.68@jar"
testImplementation "com.openshift.jenkins.plugins:openshift-client:1.0.35@jar"
testImplementation "org.jenkins-ci.plugins:ansicolor:0.5.2@jar"
}

// this is needed for spock to find all the source code in the var directory
Expand Down
207 changes: 207 additions & 0 deletions test/groovy/vars/OpenshiftApplySpec.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
package groovy.vars

import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification
import groovy.json.JsonSlurper

class OpenshiftApplySpec extends JenkinsPipelineSpecification {

def openshiftApply = loadPipelineScriptForTest('vars/openshiftApply.groovy')

def setup() {
explicitlyMockPipelineStep('executable')
}

def 'it should fail when parameter is not set'(args) {

when:
openshiftApply.call(args)

then:
1 * getPipelineMock("echo").call({ it.contains("missing required step parameter: '${args.missing}'") })
1 * getPipelineMock("error").call('Build failed') >> { throw new RuntimeException() }
thrown(RuntimeException)

where:
args << [[project : "myproject",
appLabel: "label",
missing : "configuration"],
[configuration: "configuration",
appLabel : "label",
missing : "project"],
[project : "myproject",
configuration: "configuration",
missing : "appLabel"]]

}

def 'it calls install oc_3_11 tool and oc convert'(args) {

def output = '{ "operation": "describe", "actions": [ { "err": "", "verb": "describe", "cmd": "oc --server=https://openshift.openshift.com --insecure-skip-tls-verify --namespace=myproject --token=XXXXX", "out": "Name: test-app\\nNamespace: myproject\\nLabels: pp=label\\nSelector: app=label", "status": 0 } ], "status": 0}'
output = new JsonSlurper().parseText(output)

setup:
openshiftApply.getBinding().setVariable('env', [:])
openshiftApply.getBinding().setVariable('secretValue', 'dGVzdA==')

when:
openshiftApply.call(args)

then:
2 * getPipelineMock('sh').call({ ['script': 'command -v oc', 'returnStatus': 'true'] }) >> 1
1 * getPipelineMock('executable').call(['name': 'oc', 'toolName': 'oc_3_11']) >> '/path/bin'
1 * getPipelineMock('openshift.raw').call('whoami') >> [out: "jenkins"]
1 * getPipelineMock('openshift.raw').call(['convert', '-f', 'null/temp.yaml']) >> [actions: [[cmd: "oc --server=https://openshift.puzzle.ch --insecure-skip-tls-verify --namespace=pitc-jenkinscicd-prod --token=XXXXX convert -f /var/lib/jenkins/workspace/sgilgen/shared-library-test/1636550271093/temp.yaml"]]]
1 * getPipelineMock('openshift.apply').call([args.configuration, '-l', 'app=label', '--prune']) >> output

where:
args << [[configuration : "[ { apiVersion: 'extensions/v1beta1', kind: 'Deployment', spec: { template: { spec: { containers: [ { name: 'mycontainer', }, ], }, }, }, }, ]",
project : "myproject",
cluster : "oc4-test-cluster",
appLabel : "label",
waitForRollout: false]]

}

def 'it should not call oc validate for oc4'(args) {

def output = '{ "operation": "describe", "actions": [ { "err": "", "verb": "describe", "cmd": "oc --server=https://openshift.openshift.com --insecure-skip-tls-verify --namespace=myproject --token=XXXXX", "out": "Name: test-app\\nNamespace: myproject\\nLabels: pp=label\\nSelector: app=label", "status": 0 } ], "status": 0}'
output = new JsonSlurper().parseText(output)

setup:
openshiftApply.getBinding().setVariable('env', [:])
openshiftApply.getBinding().setVariable('secretValue', 'dGVzdA==')

when:
openshiftApply.call(args)

then:
1 * getPipelineMock('sh')({ [script: 'command -v oc', returnStatus: true] }) >> 0
1 * getPipelineMock('sh')(_) >> { _arguments ->
assert '#!/bin/sh -e\noc version -o json >/dev/null 2>&1' == _arguments[0]['script']
assert true == _arguments[0]['returnStatus']
return 0
}
1 * getPipelineMock('openshift.raw').call('whoami') >> [out: "jenkins"]
1 * getPipelineMock('openshift.raw')(_) >> { _arguments ->
assert 'apply' == _arguments[0][0]
assert '-f' == _arguments[0][1]
assert 'null/temp.yaml' == _arguments[0][2]
assert '--dry-run=server' == _arguments[0][3]
return [actions: [[cmd: "oc --server=https://openshift.openshift.com --insecure-skip-tls-verify --namespace=myproject --token=XXXXX apply -f /temp.yaml"]]]
}
1 * getPipelineMock('openshift.apply').call([args.configuration, '-l', 'app=label', '--prune']) >> output

where:
args << [[configuration : "[ { apiVersion: 'extensions/v1beta1', kind: 'Deployment', spec: { template: { spec: { containers: [ { name: 'mycontainer', }, ], }, }, }, }, ]",
project : "myproject",
cluster : "oc4-test-cluster",
appLabel : "label",
waitForRollout: false]]

}

def 'it should wait for rollout with default selector'(args) {

def output = '{ "operation": "describe", "actions": [ { "err": "", "verb": "describe", "cmd": "oc --server=https://openshift.openshift.com --insecure-skip-tls-verify --namespace=myproject --token=XXXXX", "out": "Name: test-app\\nNamespace: myproject\\nLabels: pp=label\\nSelector: app=label", "status": 0 } ], "status": 0}'
output = new JsonSlurper().parseText(output)

// mock RolloutManager
def myRollout = Mock(RolloutManager)
// mock Selector to return the RolloutManager mock and check the method is called once
def mySelector = Mock(Selector) {
1 * rollout() >> myRollout
}

setup:
openshiftApply.getBinding().setVariable('env', [:])
openshiftApply.getBinding().setVariable('secretValue', 'dGVzdA==')

when:
openshiftApply.call(args)

then:
1 * getPipelineMock('sh')({ [script: 'command -v oc', returnStatus: true] }) >> 0
1 * getPipelineMock('sh')(_) >> { _arguments ->
assert '#!/bin/sh -e\noc version -o json >/dev/null 2>&1' == _arguments[0]['script']
assert true == _arguments[0]['returnStatus']
return 0
}
1 * getPipelineMock('openshift.raw').call('whoami') >> [out: "jenkins"]
1 * getPipelineMock('openshift.raw').call(['apply', '-f', 'null/temp.yaml', '--dry-run=server']) >> [actions: [[cmd: "oc --server=https://openshift.openshift.com --insecure-skip-tls-verify --namespace=myproject --token=XXXXX apply -f /temp.yaml"]]]
1 * getPipelineMock('openshift.apply').call([args.configuration, '-l', 'app=label', '--prune']) >> output
1 * getPipelineMock('echo')("waiting for 'deployment' with selector 'label' to be rolled out")
1 * getPipelineMock('openshift.selector')(_) >> { _arguments ->
assert 'deployment' == _arguments[0][0]
assert 'label' == _arguments[0][1]
return mySelector // the Selector mock returning the RolloutManager mock on the rollout method
}

where:
args << [[configuration : "[ { apiVersion: 'extensions/v1beta1', kind: 'Deployment', spec: { template: { spec: { containers: [ { name: 'mycontainer', }, ], }, }, }, }, ]",
project : "myproject",
cluster : "oc4-test-cluster",
appLabel : "label",
rolloutKind : "deployment",
waitForRollout: true]]

}

def 'it should wait for rollout with rolloutSelector'(args) {

def output = '{ "operation": "describe", "actions": [ { "err": "", "verb": "describe", "cmd": "oc --server=https://openshift.openshift.com --insecure-skip-tls-verify --namespace=myproject --token=XXXXX", "out": "Name: test-app\\nNamespace: myproject\\nLabels: pp=label\\nSelector: app=label", "status": 0 } ], "status": 0}'
output = new JsonSlurper().parseText(output)

// mock RolloutManager
def myRollout = Mock(RolloutManager)
// mock Selector to return the RolloutManager mock and check the method is called once
def mySelector = Mock(Selector) {
1 * rollout() >> myRollout
}

setup:
openshiftApply.getBinding().setVariable('env', [:])
openshiftApply.getBinding().setVariable('secretValue', 'dGVzdA==')

when:
openshiftApply.call(args)

then:
1 * getPipelineMock('sh')({ [script: 'command -v oc', returnStatus: true] }) >> 0
1 * getPipelineMock('sh')(_) >> { _arguments ->
assert '#!/bin/sh -e\noc version -o json >/dev/null 2>&1' == _arguments[0]['script']
assert true == _arguments[0]['returnStatus']
return 0
}
1 * getPipelineMock('openshift.raw').call('whoami') >> [out: "jenkins"]
1 * getPipelineMock('openshift.raw').call(['apply', '-f', 'null/temp.yaml', '--dry-run=server']) >> [actions: [[cmd: "oc --server=https://openshift.openshift.com --insecure-skip-tls-verify --namespace=myproject --token=XXXXX apply -f /temp.yaml"]]]
1 * getPipelineMock('openshift.apply').call([args.configuration, '-l', 'app=label', '--prune']) >> output
1 * getPipelineMock('echo')("waiting for 'deployment' with selector [test:selector] to be rolled out")
1 * getPipelineMock('openshift.selector')(_) >> { _arguments ->
assert 'deployment' == _arguments[0][0]
assert [test: 'selector'] == _arguments[0][1]
return mySelector // the Selector mock returning the RolloutManager mock on the rollout method
}

where:
args << [[configuration : "[ { apiVersion: 'extensions/v1beta1', kind: 'Deployment', spec: { template: { spec: { containers: [ { name: 'mycontainer', }, ], }, }, }, }, ]",
project : "myproject",
cluster : "oc4-test-cluster",
appLabel : "label",
rolloutKind : "deployment",
waitForRollout: true,
rolloutSelector: [test: 'selector']
]]
}


}

// Interface used to mock openshift Selector
interface Selector {
def rollout()
}

// Interface used to mock openshift RolloutManager
interface RolloutManager {
def status()
}
2 changes: 0 additions & 2 deletions test/groovy/vars/OpenshiftProcessSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ class OpenshiftProcessSpec extends JenkinsPipelineSpecification {
def openshiftProcess = loadPipelineScriptForTest('vars/openshiftProcess.groovy')

def setup() {
explicitlyMockPipelineStep('ansiColor')
explicitlyMockPipelineStep('executable')
explicitlyMockPipelineStep('fail')
}

def 'it should fail when templateFilePath is not set'() {
Expand Down

0 comments on commit 8fdf5dd

Please sign in to comment.