1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-16 11:09:33 +02:00
sap-jenkins-library/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy

446 lines
16 KiB
Groovy
Raw Normal View History

2018-06-26 12:49:51 +02:00
package com.sap.piper.cm
2018-06-25 13:59:25 +02:00
import static org.hamcrest.Matchers.allOf
import static org.hamcrest.Matchers.contains
2018-06-25 13:59:25 +02:00
import static org.hamcrest.Matchers.containsString
import static org.hamcrest.Matchers.equalTo
2018-06-25 16:56:38 +02:00
import static org.hamcrest.Matchers.hasItem
2018-06-25 13:59:25 +02:00
import static org.hamcrest.Matchers.is
import static org.hamcrest.Matchers.not
2018-06-25 13:59:25 +02:00
import static org.junit.Assert.assertThat
2019-01-29 12:06:36 +02:00
import static org.junit.Assert.assertEquals
2018-06-25 13:59:25 +02:00
import org.hamcrest.Matchers
import org.junit.Assert
2018-06-26 12:49:51 +02:00
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.rules.RuleChain
import com.sap.piper.GitUtils
import util.BasePiperTest
2018-06-25 16:56:38 +02:00
import util.JenkinsLoggingRule
import util.JenkinsScriptLoaderRule
2018-06-25 13:59:25 +02:00
import util.JenkinsShellCallRule
import util.JenkinsCredentialsRule
2019-01-29 12:06:36 +02:00
import util.JenkinsDockerExecuteRule
2018-06-26 12:49:51 +02:00
import util.Rules
import hudson.AbortException
2018-06-26 12:49:51 +02:00
public class ChangeManagementTest extends BasePiperTest {
private ExpectedException thrown = ExpectedException.none()
2018-06-25 13:59:25 +02:00
private JenkinsShellCallRule script = new JenkinsShellCallRule(this)
private JenkinsLoggingRule logging = new JenkinsLoggingRule(this)
2019-01-29 12:06:36 +02:00
private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this)
2018-06-25 13:59:25 +02:00
2018-06-26 12:49:51 +02:00
@Rule
2018-06-25 13:59:25 +02:00
public RuleChain rules = Rules.getCommonRules(this)
.around(thrown)
.around(script)
2018-06-25 16:56:38 +02:00
.around(logging)
.around(new JenkinsCredentialsRule(this).withCredentials('me','user','password'))
2019-01-29 12:06:36 +02:00
.around(dockerExecuteRule)
2018-06-26 12:49:51 +02:00
@Test
public void testRetrieveChangeDocumentIdOutsideGitWorkTreeTest() {
thrown.expect(ChangeManagementException)
thrown.expectMessage('Cannot retrieve ChangeDocumentId. ' +
2018-06-26 12:49:51 +02:00
'Not in a git work tree. ' +
'ChangeDocumentId is extracted from git commit messages.')
2018-06-26 12:49:51 +02:00
new ChangeManagement(nullScript, gitUtilsMock(false, new String[0])).getChangeDocumentId()
2018-06-26 12:49:51 +02:00
}
@Test
public void testRetrieveChangeDocumentIdNothingFound() {
thrown.expect(ChangeManagementException)
thrown.expectMessage('Cannot retrieve ChangeDocumentId from git commits.')
2018-06-26 12:49:51 +02:00
new ChangeManagement(nullScript, gitUtilsMock(true, new String[0])).getChangeDocumentId()
2018-06-26 12:49:51 +02:00
}
@Test
public void testRetrieveChangeDocumentIdReturnsArrayWithNullValue() {
thrown.expect(ChangeManagementException)
thrown.expectMessage('Cannot retrieve ChangeDocumentId from git commits.')
new ChangeManagement(nullScript, gitUtilsMock(true, (String[])[ null ])).getChangeDocumentId()
}
2018-06-21 15:32:47 +02:00
@Test
public void testRetrieveChangeDocumentNotUnique() {
thrown.expect(ChangeManagementException)
thrown.expectMessage('Multiple ChangeDocumentIds found')
2018-06-21 15:32:47 +02:00
String[] changeIds = [ 'a', 'b' ]
new ChangeManagement(nullScript, gitUtilsMock(true, changeIds)).getChangeDocumentId()
}
@Test
public void testRetrieveChangeDocumentSameChangeIdFoundTwice() {
String[] changeIds = [ 'a', 'a' ]
def changeID = new ChangeManagement(nullScript, gitUtilsMock(true, changeIds)).getChangeDocumentId()
assert changeID == 'a'
}
2018-06-25 13:59:25 +02:00
@Test
public void testIsChangeInDevelopmentReturnsTrueWhenChangeIsInDevelopent() {
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, "cmclient.*is-change-in-development -cID '001'", 0)
boolean inDevelopment = new ChangeManagement(nullScript, null).isChangeInDevelopment('001', 'endpoint', 'me')
2018-06-25 13:59:25 +02:00
assertThat(inDevelopment, is(equalTo(true)))
assertThat(script.shell[0], allOf(containsString("cmclient"),
containsString("-u 'user'"),
containsString("-p 'password'"),
2018-06-25 09:16:42 +02:00
containsString("-e 'endpoint'"),
2018-06-25 13:59:25 +02:00
containsString('is-change-in-development'),
containsString("-cID '001'"),
containsString("-t SOLMAN")))
}
@Test
public void testIsChangeInDevelopmentReturnsFalseWhenChangeIsNotInDevelopent() {
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, "cmclient.*is-change-in-development -cID '001'", 3)
boolean inDevelopment = new ChangeManagement(nullScript, null)
.isChangeInDevelopment('001',
'endpoint',
'me')
2018-06-25 13:59:25 +02:00
assertThat(inDevelopment, is(equalTo(false)))
}
@Test
public void testIsChangeInDevelopmentThrowsExceptionWhenCMClientReturnsUnexpectedExitCode() {
thrown.expect(ChangeManagementException)
thrown.expectMessage('Cannot retrieve status for change document \'001\'. Does this change exist? Return code from cmclient: 1.')
2018-06-25 13:59:25 +02:00
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, "cmclient.*is-change-in-development -cID '001'", 1)
new ChangeManagement(nullScript, null).isChangeInDevelopment('001', 'endpoint', 'me')
2018-06-25 13:59:25 +02:00
}
2018-06-21 15:32:47 +02:00
2018-06-25 08:46:17 +02:00
@Test
public void testGetCommandLineWithoutCMClientOpts() {
2018-06-25 08:46:17 +02:00
String commandLine = new ChangeManagement(nullScript, null)
.getCMCommandLine(BackendType.SOLMAN,
'https://example.org/cm',
2018-06-25 08:46:17 +02:00
"me",
"topSecret",
"the-command",
["-key1", "val1", "-key2", "val2"])
commandLine = commandLine.replaceAll(' +', " ")
assertThat(commandLine, not(containsString("CMCLIENT_OPTS")))
2018-06-25 08:46:17 +02:00
assertThat(commandLine, containsString("cmclient -e 'https://example.org/cm' -u 'me' -p 'topSecret' -t SOLMAN the-command -key1 val1 -key2 val2"))
}
2018-06-25 08:46:17 +02:00
@Test
public void testGetCommandLineWithCMClientOpts() {
String commandLine = new ChangeManagement(nullScript, null)
.getCMCommandLine(BackendType.SOLMAN,
'https://example.org/cm',
"me",
"topSecret",
"the-command",
["-key1", "val1", "-key2", "val2"],
'-Djavax.net.debug=all')
commandLine = commandLine.replaceAll(' +', " ")
assertThat(commandLine, containsString('export CMCLIENT_OPTS="-Djavax.net.debug=all"'))
}
@Test
2018-09-25 09:12:07 +02:00
public void testCreateTransportRequestSOLMANSucceeds() {
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".*cmclient.*create-transport -cID 001 -dID 002.*", '004')
2018-09-25 09:12:07 +02:00
def transportRequestId = new ChangeManagement(nullScript).createTransportRequestSOLMAN( '001', '002', '003', 'me')
// the check for the transportRequestID is sufficient. This checks implicit the command line since that value is
// returned only in case the shell call matches.
assert transportRequestId == '004'
}
@Test
public void testCreateTransportRequestRFCSucceeds() {
script.setReturnValue('cts createTransportRequest', '{"REQUESTID":"XYZK9000004"}')
def transportRequestId = new ChangeManagement(nullScript).createTransportRequestRFC(
[image: 'rfc', options: []],
'https://example.org/rfc', // endpoint
'01', // client
'001', // instance
'me', // credentialsId
'Lorem ipsum' // description
)
assert dockerExecuteRule.dockerParams.dockerImage == 'rfc'
assert dockerExecuteRule.dockerParams.dockerEnvVars == [
TRANSPORT_DESCRIPTION: 'Lorem ipsum',
ABAP_DEVELOPMENT_INSTANCE: '001',
ABAP_DEVELOPMENT_CLIENT: '01',
ABAP_DEVELOPMENT_SERVER: 'https://example.org/rfc',
ABAP_DEVELOPMENT_USER: 'user',
ABAP_DEVELOPMENT_PASSWORD: 'password',
]
assert transportRequestId == 'XYZK9000004'
}
@Test
public void testCreateTransportRequestRFCFails() {
thrown.expect(ChangeManagementException)
thrown.expectMessage('Cannot create transport request: script returned exit code 3')
script.setReturnValue('cts createTransportRequest',
{ throw new AbortException('script returned exit code 3')})
def transportRequestId = new ChangeManagement(nullScript).createTransportRequestRFC(
[image: 'rfc', options: []],
'https://example.org/rfc', // endpoint
'01', // client
'001', // instance
'me', // credentialsId
'Lorem ipsum' // description
)
}
2018-09-25 09:12:07 +02:00
@Test
public void testCreateTransportRequestCTSSucceeds() {
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, 'cmclient.* -t CTS .*create-transport -tt W -ts XYZ -d "desc 123"$', '004')
def transportRequestId = new ChangeManagement(nullScript)
.createTransportRequestCTS(
'W', // transport type
'XYZ', // target system
'desc 123', // description
'https://example.org/cm',
'me')
// the check for the transportRequestID is sufficient. This checks implicit the command line since that value is
// returned only in case the shell call matches.
assert transportRequestId == '004'
}
@Test
public void testUploadFileToTransportSucceedsSOLMAN() {
// the regex provided below is an implicit check that the command line is fine.
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, 'upload-file-to-transport.*-cID 001 -tID 002 XXX "/path"', 0)
new ChangeManagement(nullScript).uploadFileToTransportRequestSOLMAN(
'001',
'002',
'XXX',
'/path',
'https://example.org/cm',
'me')
// no assert required here, since the regex registered above to the script rule is an implicit check for
// the command line.
}
@Test
public void testUploadFileToTransportSucceedsCTS() {
// the regex provided below is an implicit check that the command line is fine.
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t CTS upload-file-to-transport -tID 002 "/path"', 0)
new ChangeManagement(nullScript).uploadFileToTransportRequestCTS(
'002',
'/path',
'https://example.org/cm',
'me')
// no assert required here, since the regex registered above to the script rule is an implicit check for
// the command line.
}
@Test
public void testUploadFileToTransportSucceedsRFC() {
new ChangeManagement(nullScript).uploadFileToTransportRequestRFC(
2019-02-12 14:44:09 +02:00
[image:'rfc', options: [], pullImage: true],
'002', //transportRequestId
'001', // applicationId
'https://example.org/mypath/deployArtifact.zip',
'https://example.org/rfc',
'me',
'01', //developmentInstance
'00', // developmentClient
'Lorem ipsum', // applicationDescription
2019-02-14 10:36:51 +02:00
'XYZ', // abapPackage
'UTF-9', //codePage
2019-02-14 14:51:24 +02:00
true, // accept unix style EOL
true, //failUploadOnWarning
)
2019-02-12 14:44:09 +02:00
assert dockerExecuteRule.dockerParams.dockerImage == 'rfc'
2019-02-12 14:44:09 +02:00
assert dockerExecuteRule.dockerParams.dockerPullImage == true
assert dockerExecuteRule.dockerParams.dockerEnvVars ==
[
ABAP_DEVELOPMENT_INSTANCE: '01',
ABAP_DEVELOPMENT_CLIENT: '00',
ABAP_APPLICATION_NAME: '001',
ABAP_APPLICATION_DESC: 'Lorem ipsum',
ABAP_PACKAGE: 'XYZ',
ZIP_FILE_URL: 'https://example.org/mypath/deployArtifact.zip',
ABAP_DEVELOPMENT_SERVER: 'https://example.org/rfc',
ABAP_DEVELOPMENT_USER: 'user',
ABAP_DEVELOPMENT_PASSWORD: 'password',
2019-02-14 10:36:51 +02:00
CODE_PAGE: 'UTF-9',
2019-02-14 14:51:24 +02:00
ABAP_ACCEPT_UNIX_STYLE_EOL: 'X',
FAIL_UPLOAD_ON_WARNING: 'true',
]
assertThat(script.shell, contains('cts uploadToABAP:002'))
}
@Test
public void testUploadFileToTransportFailsRFC() {
thrown.expect(ChangeManagementException)
thrown.expectMessage('Cannot upload file into transport request. Return code from rfc client: 1.')
script.setReturnValue('cts uploadToABAP:002', 1)
new ChangeManagement(nullScript).uploadFileToTransportRequestRFC(
2019-02-12 14:44:09 +02:00
[:],
'002', //transportRequestId
'001', // applicationId
'https://example.org/mypath/deployArtifact.zip',
'https://example.org/rfc',
'me',
'01', //developmentInstance
'00', // developmentClient
'Lorem ipsum', // applicationDescription
2019-02-14 10:36:51 +02:00
'XYZ', // abapPackage
'UTF-9', // codePage
2019-02-14 14:51:24 +02:00
true, // accept unix style EOL
true, // failUploadOnWarning
)
}
@Test
2019-01-29 12:06:36 +02:00
public void testUploadFileToTransportFailsSOLMAN() {
thrown.expect(ChangeManagementException)
thrown.expectMessage("Cannot upload file into transport request. " +
"Return code from cm client: 1.")
script.setReturnValue(JenkinsShellCallRule.Type.REGEX,, 'upload-file-to-transport', 1)
new ChangeManagement(nullScript).uploadFileToTransportRequestSOLMAN(
'001',
'002',
'XXX',
'/path',
'https://example.org/cm',
'me')
}
@Test
public void testReleaseTransportRequestSucceedsSOLMAN() {
// the regex provided below is an implicit check that the command line is fine.
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t SOLMAN release-transport.*-cID 001.*-tID 002', 0)
new ChangeManagement(nullScript).releaseTransportRequestSOLMAN(
'001',
'002',
'https://example.org',
'me',
'openSesame')
// no assert required here, since the regex registered above to the script rule is an implicit check for
// the command line.
}
@Test
public void testReleaseTransportRequestSucceedsCTS() {
// the regex provided below is an implicit check that the command line is fine.
2018-09-25 11:12:04 +02:00
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t CTS export-transport.*-tID 002', 0)
new ChangeManagement(nullScript).releaseTransportRequestCTS(
'002',
'https://example.org',
'me',
'openSesame')
// no assert required here, since the regex registered above to the script rule is an implicit check for
// the command line.
}
2019-01-29 12:06:36 +02:00
@Test
public void testReleaseTransportRequestSucceedsRFC() {
new ChangeManagement(nullScript).releaseTransportRequestRFC(
[:],
2019-01-29 12:06:36 +02:00
'002',
'https://example.org',
'002',
'001',
'me')
2019-01-29 12:06:36 +02:00
assert dockerExecuteRule.dockerParams.dockerEnvVars == [
ABAP_DEVELOPMENT_SERVER: 'https://example.org',
ABAP_DEVELOPMENT_USER: 'user',
ABAP_DEVELOPMENT_PASSWORD: 'password',
ABAP_DEVELOPMENT_CLIENT: '001',
ABAP_DEVELOPMENT_INSTANCE: '002',
]
2019-01-29 12:06:36 +02:00
assertThat(script.shell, hasItem('cts releaseTransport:002'))
}
@Test
public void testReleaseTransportRequestFailsSOLMAN() {
thrown.expect(ChangeManagementException)
thrown.expectMessage("Cannot release Transport Request '002'. Return code from cmclient: 1.")
// the regex provided below is an implicit check that the command line is fine.
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, 'release-transport.*-cID 001.*-tID 002', 1)
new ChangeManagement(nullScript).releaseTransportRequestSOLMAN(
'001',
'002',
'https://example.org',
'me')
}
2018-06-21 15:32:47 +02:00
private GitUtils gitUtilsMock(boolean insideWorkTree, String[] changeIds) {
return new GitUtils() {
public boolean insideWorkTree() {
return insideWorkTree
}
public String[] extractLogLines(
String filter = '',
String from = 'origin/master',
String to = 'HEAD',
String format = '%b') {
return changeIds
}
}
}
2018-06-26 12:49:51 +02:00
}