1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-14 11:03:09 +02:00

Merge branch 'master' into whitesource-step

This commit is contained in:
Sven Merk 2019-03-15 13:16:29 +01:00 committed by GitHub
commit bb31060dad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1184 additions and 159 deletions

View File

@ -16,6 +16,12 @@ general:
from: 'origin/master'
to: 'HEAD'
format: '%b'
rfc:
docker:
image: 'rfc'
options: []
envVars: {}
pullImage: true
githubApiUrl: 'https://api.github.com'
githubServerUrl: 'https://github.com'
gitSshKeyCredentialsId: '' #needed to allow sshagent to run with local ssh key
@ -416,8 +422,14 @@ steps:
failIfStatusIsNotInDevelopment: true
transportRequestCreate:
developmentSystemId: null
verbose: false
transportRequestUploadFile:
acceptUnixStyleLineEndings: true
codePage: 'UTF-8'
failOnWarning: true
verbose: false
transportRequestRelease:
verbose: false
uiVeri5ExecuteTests:
failOnError: false
dockerEnvVars: {}

View File

@ -55,6 +55,7 @@ def stashWithMessage(name, msg, include = '**/*.*', exclude = '') {
}
def unstash(name, msg = "Unstash failed:") {
def unstashedContent = []
try {
echo "Unstash content: ${name}"
@ -70,7 +71,9 @@ def unstashAll(stashContent) {
def unstashedContent = []
if (stashContent) {
for (i = 0; i < stashContent.size(); i++) {
unstashedContent += unstash(stashContent[i])
if(stashContent[i]) {
unstashedContent += unstash(stashContent[i])
}
}
}
return unstashedContent

View File

@ -1,5 +1,5 @@
package com.sap.piper.cm;
public enum BackendType {
SOLMAN, CTS, NONE
SOLMAN, CTS, RFC, NONE
}

View File

@ -2,6 +2,7 @@ package com.sap.piper.cm
import com.sap.piper.GitUtils
import groovy.json.JsonSlurper
import hudson.AbortException
@ -63,7 +64,7 @@ public class ChangeManagement implements Serializable {
}
boolean isChangeInDevelopment(String changeId, String endpoint, String credentialsId, String clientOpts = '') {
int rc = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'is-change-in-development', ['-cID', "'${changeId}'", '--return-code'],
int rc = executeWithCredentials(BackendType.SOLMAN, [:], endpoint, credentialsId, 'is-change-in-development', ['-cID', "'${changeId}'", '--return-code'],
false,
clientOpts) as int
@ -78,7 +79,7 @@ public class ChangeManagement implements Serializable {
String createTransportRequestCTS(String transportType, String targetSystemId, String description, String endpoint, String credentialsId, String clientOpts = '') {
try {
def transportRequest = executeWithCredentials(BackendType.CTS, endpoint, credentialsId, 'create-transport',
def transportRequest = executeWithCredentials(BackendType.CTS, [:], endpoint, credentialsId, 'create-transport',
['-tt', transportType, '-ts', targetSystemId, '-d', "\"${description}\""],
true,
clientOpts)
@ -91,7 +92,7 @@ public class ChangeManagement implements Serializable {
String createTransportRequestSOLMAN(String changeId, String developmentSystemId, String endpoint, String credentialsId, String clientOpts = '') {
try {
def transportRequest = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'create-transport', ['-cID', changeId, '-dID', developmentSystemId],
def transportRequest = executeWithCredentials(BackendType.SOLMAN, [:], endpoint, credentialsId, 'create-transport', ['-cID', changeId, '-dID', developmentSystemId],
true,
clientOpts)
return (transportRequest as String)?.trim()
@ -100,86 +101,311 @@ public class ChangeManagement implements Serializable {
}
}
void uploadFileToTransportRequest(BackendType type, String changeId, String transportRequestId, String applicationId, String filePath, String endpoint, String credentialsId, String cmclientOpts = '') {
String createTransportRequestRFC(
Map docker,
String endpoint,
String developmentInstance,
String developmentClient,
String credentialsId,
String description,
boolean verbose) {
def args = null
def command = 'cts createTransportRequest'
def args = [
TRANSPORT_DESCRIPTION: description,
ABAP_DEVELOPMENT_INSTANCE: developmentInstance,
ABAP_DEVELOPMENT_CLIENT: developmentClient,
VERBOSE: verbose,
]
if(type == BackendType.SOLMAN) {
args = ['-cID', changeId,
'-tID', transportRequestId,
applicationId, "\"$filePath\""]
} else if (type == BackendType.CTS) {
args = ['-tID', transportRequestId,
"\"$filePath\""]
} else {
throw new IllegalArgumentException("Invalid backend type: ${type}")
try {
def transportRequestId = executeWithCredentials(
BackendType.RFC,
docker,
endpoint,
credentialsId,
command,
args,
true)
return new JsonSlurper().parseText(transportRequestId).REQUESTID
} catch(AbortException ex) {
throw new ChangeManagementException(
"Cannot create transport request: ${ex.getMessage()}", ex)
}
int rc = executeWithCredentials(type,
endpoint,
credentialsId,
'upload-file-to-transport',
args,
false,
cmclientOpts) as int
if(rc == 0) {
return
} else {
throw new ChangeManagementException("Cannot upload file '$filePath' for change document '$changeId' with transport request '$transportRequestId'. Return code from cmclient: $rc.")
}
}
def executeWithCredentials(BackendType type, String endpoint, String credentialsId, String command, List<String> args, boolean returnStdout = false, String clientOpts = '') {
void uploadFileToTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String applicationId,
String filePath,
String endpoint,
String credentialsId,
String cmclientOpts = '') {
def args = [
'-cID', changeId,
'-tID', transportRequestId,
applicationId, "\"$filePath\""
]
int rc = executeWithCredentials(
BackendType.SOLMAN,
[:],
endpoint,
credentialsId,
'upload-file-to-transport',
args,
false,
cmclientOpts) as int
if(rc != 0) {
throw new ChangeManagementException(
"Cannot upload file into transport request. Return code from cm client: $rc.")
}
}
void uploadFileToTransportRequestCTS(
String transportRequestId,
String filePath,
String endpoint,
String credentialsId,
String cmclientOpts = '') {
def args = [
'-tID', transportRequestId,
"\"$filePath\""
]
int rc = executeWithCredentials(
BackendType.CTS,
[:],
endpoint,
credentialsId,
'upload-file-to-transport',
args,
false,
cmclientOpts) as int
if(rc != 0) {
throw new ChangeManagementException(
"Cannot upload file into transport request. Return code from cm client: $rc.")
}
}
void uploadFileToTransportRequestRFC(
Map docker,
String transportRequestId,
String applicationName,
String filePath,
String endpoint,
String credentialsId,
String developmentInstance,
String developmentClient,
String applicationDescription,
String abapPackage,
String codePage,
boolean acceptUnixStyleEndOfLine,
boolean failOnWarning,
boolean verbose) {
def args = [
ABAP_DEVELOPMENT_INSTANCE: developmentInstance,
ABAP_DEVELOPMENT_CLIENT: developmentClient,
ABAP_APPLICATION_NAME: applicationName,
ABAP_APPLICATION_DESC: applicationDescription,
ABAP_PACKAGE: abapPackage,
ZIP_FILE_URL: filePath,
CODE_PAGE: codePage,
ABAP_ACCEPT_UNIX_STYLE_EOL: acceptUnixStyleEndOfLine ? 'X' : '-',
FAIL_UPLOAD_ON_WARNING: Boolean.toString(failOnWarning),
VERBOSE: Boolean.toString(verbose),
]
int rc = executeWithCredentials(
BackendType.RFC,
docker,
endpoint,
credentialsId,
"cts uploadToABAP:${transportRequestId}",
args,
false) as int
if(rc != 0) {
throw new ChangeManagementException(
"Cannot upload file into transport request. Return code from rfc client: $rc.")
}
}
def executeWithCredentials(
BackendType type,
Map docker,
String endpoint,
String credentialsId,
String command,
def args,
boolean returnStdout = false,
String clientOpts = '') {
def script = this.script
script.withCredentials([script.usernamePassword(
credentialsId: credentialsId,
passwordVariable: 'password',
usernameVariable: 'username')]) {
def cmScript = getCMCommandLine(type, endpoint, script.username, script.password,
command, args,
clientOpts)
Map shArgs = [:]
if(returnStdout)
shArgs.put('returnStdout', true)
else
shArgs.put('returnStatus', true)
shArgs.put('script', cmScript)
def result = 1
// user and password are masked by withCredentials
script.echo """[INFO] Executing command line: "${cmScript}"."""
return script.sh(shArgs)
switch(type) {
case BackendType.RFC:
if(! (args in Map)) {
throw new IllegalArgumentException("args expected as Map for backend types ${[BackendType.RFC]}")
}
shArgs.script = command
args = args.plus([
ABAP_DEVELOPMENT_SERVER: endpoint,
ABAP_DEVELOPMENT_USER: script.username,
ABAP_DEVELOPMENT_PASSWORD: script.password,
])
// user and password are masked by withCredentials
script.echo """[INFO] Executing command line: "${shArgs.script}"."""
script.dockerExecute(
script: script,
dockerImage: docker.image,
dockerOptions: docker.options,
dockerEnvVars: (docker.envVars?:[:]).plus(args),
dockerPullImage: docker.pullImage) {
result = script.sh(shArgs)
}
break
case BackendType.SOLMAN:
case BackendType.CTS:
if(! (args in Collection))
throw new IllegalArgumentException("args expected as Collection for backend types ${[BackendType.SOLMAN, BackendType.CTS]}")
shArgs.script = getCMCommandLine(type, endpoint, script.username, script.password,
command, args,
clientOpts)
// user and password are masked by withCredentials
script.echo """[INFO] Executing command line: "${shArgs.script}"."""
result = script.sh(shArgs)
break
}
return result
}
}
void releaseTransportRequest(BackendType type,String changeId, String transportRequestId, String endpoint, String credentialsId, String clientOpts = '') {
void releaseTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String endpoint,
String credentialsId,
String clientOpts = '') {
def cmd
List args = []
def cmd = 'release-transport'
def args = [
'-cID',
changeId,
'-tID',
transportRequestId,
]
if(type == BackendType.SOLMAN) {
cmd = 'release-transport'
args << '-cID'
args << changeId
} else if(type == BackendType.CTS) {
cmd = 'export-transport'
} else {
throw new IllegalStateException("Invalid backend type: '${type}'")
}
int rc = executeWithCredentials(
BackendType.SOLMAN,
[:],
endpoint,
credentialsId,
cmd,
args,
false,
clientOpts) as int
args << '-tID'
args << transportRequestId
int rc = executeWithCredentials(type, endpoint, credentialsId, cmd, args, false, clientOpts) as int
if(rc == 0) {
return
} else {
if(rc != 0) {
throw new ChangeManagementException("Cannot release Transport Request '$transportRequestId'. Return code from cmclient: $rc.")
}
}
void releaseTransportRequestCTS(
String transportRequestId,
String endpoint,
String credentialsId,
String clientOpts = '') {
def cmd = 'export-transport'
def args = [
'-tID',
transportRequestId,
]
int rc = executeWithCredentials(
BackendType.CTS,
[:],
endpoint,
credentialsId,
cmd,
args,
false) as int
if(rc != 0) {
throw new ChangeManagementException("Cannot release Transport Request '$transportRequestId'. Return code from cmclient: $rc.")
}
}
void releaseTransportRequestRFC(
Map docker,
String transportRequestId,
String endpoint,
String developmentInstance,
String developmentClient,
String credentialsId,
boolean verbose) {
def cmd = "cts releaseTransport:${transportRequestId}"
def args = [
ABAP_DEVELOPMENT_INSTANCE: developmentInstance,
ABAP_DEVELOPMENT_CLIENT: developmentClient,
VERBOSE: verbose,
]
int rc = executeWithCredentials(
BackendType.RFC,
docker,
endpoint,
credentialsId,
cmd,
args,
false) as int
if(rc != 0) {
throw new ChangeManagementException("Cannot release Transport Request '$transportRequestId'. Return code from rfcclient: $rc.")
}
}
String getCMCommandLine(BackendType type,
String endpoint,
String username,

View File

@ -1,3 +1,10 @@
import static org.hamcrest.Matchers.allOf
import static org.hamcrest.Matchers.containsString
import java.util.Map
import org.hamcrest.Matchers
import org.hamcrest.core.StringContains
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -54,7 +61,7 @@ public class TransportRequestCreateTest extends BasePiperTest {
}
@Test
public void changeIdNotProvidedTest() {
public void changeIdNotProvidedSOLANTest() {
thrown.expect(IllegalArgumentException)
thrown.expectMessage("Change document id not provided (parameter: 'changeDocumentId' or via commit history).")
@ -73,7 +80,7 @@ public class TransportRequestCreateTest extends BasePiperTest {
}
@Test
public void developmentSystemIdNotProvidedTest() {
public void developmentSystemIdNotProvidedSOLMANTest() {
thrown.expect(IllegalArgumentException)
thrown.expectMessage("ERROR - NO VALUE AVAILABLE FOR developmentSystemId")
@ -82,7 +89,7 @@ public class TransportRequestCreateTest extends BasePiperTest {
}
@Test
public void createTransportRequestFailureTest() {
public void createTransportRequestFailureSOLMANTest() {
ChangeManagement cm = new ChangeManagement(nullScript) {
@ -154,8 +161,7 @@ public class TransportRequestCreateTest extends BasePiperTest {
String description,
String endpoint,
String credentialsId,
String clientOpts
) {
String clientOpts) {
result.transportType = transportType
result.targetSystemId = targetSystemId
result.description = description
@ -186,6 +192,120 @@ public class TransportRequestCreateTest extends BasePiperTest {
assert loggingRule.log.contains("[INFO] Transport Request '001' has been successfully created.")
}
@Test
public void createTransportRequestSuccessRFCTest() {
def result = [:]
ChangeManagement cm = new ChangeManagement(nullScript) {
String createTransportRequestRFC(
Map docker,
String endpoint,
String developmentInstance,
String developmentClient,
String credentialsId,
String description,
boolean verbose) {
result.docker = docker
result.endpoint = endpoint
result.developmentClient = developmentClient
result.developmentInstance= developmentInstance
result.credentialsId = credentialsId
result.description = description
result.verbose = verbose
return '001'
}
}
stepRule.step.transportRequestCreate(
script: nullScript,
changeManagement: [
type: 'RFC',
rfc: [
developmentInstance: '01',
developmentClient: '001',
],
endpoint: 'https://example.org/rfc',
],
developmentSystemId: '001',
description: '',
cmUtils: cm,
verbose: true)
assert nullScript.commonPipelineEnvironment.getTransportRequestId() == '001'
assert result == [
docker: [
image: 'rfc',
options: [],
envVars: [:],
pullImage: true
],
endpoint: 'https://example.org/rfc',
developmentClient: '001',
developmentInstance: '01',
credentialsId: 'CM',
description: '',
verbose: true
]
assert loggingRule.log.contains("[INFO] Creating transport request.")
assert loggingRule.log.contains("[INFO] Transport Request '001' has been successfully created.")
}
@Test
public void createTransportRequestFailureRFCTest() {
thrown.expect(AbortException)
thrown.expectMessage('upload failed')
ChangeManagement cm = new ChangeManagement(nullScript) {
String createTransportRequestRFC(
Map docker,
String endpoint,
String developmentClient,
String developmentInstance,
String credentialsId,
String description,
boolean verbose) {
throw new ChangeManagementException('upload failed')
}
}
stepRule.step.transportRequestCreate(
script: nullScript,
changeManagement: [
type: 'RFC',
rfc: [
developmentInstance: '01',
developmentClient: '001',
],
endpoint: 'https://example.org/rfc',
],
developmentSystemId: '001',
description: '',
cmUtils: cm)
}
@Test
public void createTransportRequestSanityChecksRFCTest() {
thrown.expect(IllegalArgumentException)
thrown.expectMessage(allOf(
containsString('changeManagement/rfc/developmentInstance'),
containsString('changeManagement/rfc/developmentClient'),
))
stepRule.step.transportRequestCreate(
script: nullScript,
changeManagement: [
type: 'RFC',
])
}
@Test
public void cmIntegrationSwichtedOffTest() {

View File

@ -1,3 +1,7 @@
import static org.hamcrest.Matchers.allOf
import static org.hamcrest.Matchers.containsString
import org.hamcrest.Matchers
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -10,6 +14,7 @@ import com.sap.piper.cm.ChangeManagementException
import util.BasePiperTest
import util.JenkinsCredentialsRule
import util.JenkinsDockerExecuteRule
import util.JenkinsStepRule
import util.JenkinsLoggingRule
import util.JenkinsReadYamlRule
@ -48,7 +53,7 @@ public class TransportRequestReleaseTest extends BasePiperTest {
}
@Test
public void changeIdNotProvidedTest() {
public void changeDocumentIdNotProvidedSOLMANTest() {
ChangeManagement cm = new ChangeManagement(nullScript) {
String getChangeDocumentId(String from,
@ -84,14 +89,14 @@ public class TransportRequestReleaseTest extends BasePiperTest {
}
@Test
public void releaseTransportRequestFailureTest() {
public void releaseTransportRequestFailsSOLMANTest() {
thrown.expect(AbortException)
thrown.expectMessage("Something went wrong")
ChangeManagement cm = new ChangeManagement(nullScript) {
void releaseTransportRequest(BackendType type,
void releaseTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String endpoint,
@ -106,7 +111,257 @@ public class TransportRequestReleaseTest extends BasePiperTest {
}
@Test
public void releaseTransportRequestSuccessTest() {
public void releaseTransportRequestFailsCTSTest() {
thrown.expect(AbortException)
thrown.expectMessage("Something went wrong")
nullScript
.commonPipelineEnvironment
.configuration
.general
.changeManagement
.type = 'CTS'
ChangeManagement cm = new ChangeManagement(nullScript) {
void releaseTransportRequestCTS(
String transportRequestId,
String endpoint,
String credentialsId,
String clientOpts) {
throw new ChangeManagementException('Something went wrong')
}
}
stepRule.step.transportRequestRelease(
script: nullScript,
transportRequestId: '001',
cmUtils: cm)
}
@Test
public void releaseTransportRequestSuccessRFCTest() {
def receivedParameters
nullScript
.commonPipelineEnvironment
.configuration
.general
.changeManagement =
[
credentialsId: 'CM',
type: 'RFC',
endpoint: 'https://example.org/rfc',
rfc: [
dockerImage: 'rfc',
dockerOptions: [],
],
]
ChangeManagement cm = new ChangeManagement(nullScript) {
void releaseTransportRequestRFC(
Map docker,
String transportRequestId,
String endpoint,
String developmentInstance,
String developmentClient,
String credentialsId,
boolean verbose) {
receivedParameters = [
docker: docker,
transportRequestId: transportRequestId,
endpoint: endpoint,
developmentInstance: developmentInstance,
developmentClient: developmentClient,
credentialsId: credentialsId,
verbose: verbose,
]
}
}
stepRule.step.transportRequestRelease(
script: nullScript,
transportRequestId: '002',
changeManagement: [
rfc: [
developmentClient: '003',
developmentInstance: '002',
]
],
verbose: true,
cmUtils: cm)
assert receivedParameters == [
docker: [
image: 'rfc',
options: [],
envVars: [:],
pullImage: true,
],
transportRequestId: '002',
endpoint: 'https://example.org/rfc',
developmentInstance: '002',
developmentClient: '003',
credentialsId: 'CM',
'verbose': true,
]
}
@Test
public void releaseTransportRequestSuccessCTSTest() {
def receivedParameters
nullScript
.commonPipelineEnvironment
.configuration
.general
.changeManagement =
[
credentialsId: 'CM',
type: 'CTS',
endpoint: 'https://example.org/cts'
]
ChangeManagement cm = new ChangeManagement(nullScript) {
void releaseTransportRequestCTS(
String transportRequestId,
String endpoint,
String credentialsId,
String clientOpts = '') {
receivedParameters = [
transportRequestId: transportRequestId,
endpoint: endpoint,
credentialsId: credentialsId,
clientOpts: clientOpts
]
}
}
stepRule.step.transportRequestRelease(
script: nullScript,
transportRequestId: '002',
cmUtils: cm)
assert receivedParameters == [
transportRequestId: '002',
endpoint: 'https://example.org/cts',
credentialsId: 'CM',
clientOpts: ''
]
}
@Test
public void releaseTransportRequestFailsRFCTest() {
thrown.expect(AbortException)
thrown.expectMessage('Failed releasing transport request.')
nullScript
.commonPipelineEnvironment
.configuration
.general
.changeManagement =
[
credentialsId: 'CM',
type: 'RFC',
endpoint: 'https://example.org/rfc',
rfc: [dockerImage: 'rfc']
]
ChangeManagement cm = new ChangeManagement(nullScript) {
void releaseTransportRequestRFC(
Map docker,
String transportRequestId,
String endpoint,
String developmentInstance,
String developmentClient,
String credentialsId,
boolean verbose) {
throw new ChangeManagementException('Failed releasing transport request.')
}
}
stepRule.step.transportRequestRelease(
script: nullScript,
transportRequestId: '002',
changeManagement: [
rfc: [
developmentClient: '003',
developmentInstance: '002'
]
],
cmUtils: cm)
}
@Test
public void releaseTransportRequestSanityChecksSOLMANTest() {
thrown.expect(IllegalArgumentException)
thrown.expectMessage(allOf(
containsString('ERROR - NO VALUE AVAILABLE FOR'),
containsString('changeManagement/endpoint')))
// changeDocumentId and transportRequestId are not checked
// by the sanity checks here since they are looked up from
// commit history in case they are not provided.
nullScript
.commonPipelineEnvironment
.configuration = null
stepRule.step.transportRequestRelease(
script: nullScript,
changeManagement: [type: 'SOLMAN']
)
}
@Test
public void releaseTransportRequestSanityChecksCTSTest() {
thrown.expect(IllegalArgumentException)
thrown.expectMessage(allOf(
containsString('ERROR - NO VALUE AVAILABLE FOR'),
containsString('changeManagement/endpoint')))
nullScript
.commonPipelineEnvironment
.configuration = null
stepRule.step.transportRequestRelease(
script: nullScript,
changeManagement: [type: 'CTS']
)
}
@Test
public void releaseTransportRequestSanityChecksRFCTest() {
thrown.expect(IllegalArgumentException)
thrown.expectMessage(allOf(
containsString('ERROR - NO VALUE AVAILABLE FOR:'),
containsString('changeManagement/endpoint'),
containsString('developmentClient')))
nullScript
.commonPipelineEnvironment
.configuration = null
stepRule.step.transportRequestRelease(
script: nullScript,
changeManagement: [type: 'RFC'],
transportRequestId: '002')
}
@Test
public void releaseTransportRequestSuccessSOLMANTest() {
// Here we test only the case where the transportRequestId is
// provided via parameters. The other cases are tested by
@ -118,14 +373,13 @@ public class TransportRequestReleaseTest extends BasePiperTest {
Map receivedParams = [:]
ChangeManagement cm = new ChangeManagement(nullScript) {
void releaseTransportRequest(BackendType type,
void releaseTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String endpoint,
String credentialsId,
String clientOpts) {
receivedParams.type = type
receivedParams.changeId = changeId
receivedParams.transportRequestId = transportRequestId
receivedParams.endpoint = endpoint
@ -136,7 +390,7 @@ public class TransportRequestReleaseTest extends BasePiperTest {
stepRule.step.transportRequestRelease(script: nullScript, changeDocumentId: '001', transportRequestId: '002', cmUtils: cm)
assert receivedParams == [type: BackendType.SOLMAN,
assert receivedParams == [
changeId: '001',
transportRequestId: '002',
endpoint: 'https://example.org/cm',

View File

@ -1,11 +1,17 @@
import static org.hamcrest.Matchers.allOf
import static org.hamcrest.Matchers.containsString
import java.util.List
import java.util.Map
import org.hamcrest.Matchers
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.rules.RuleChain
import com.sap.piper.JenkinsUtils
import com.sap.piper.cm.BackendType
import com.sap.piper.cm.ChangeManagement
import com.sap.piper.cm.ChangeManagementException
@ -119,10 +125,10 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
}
@Test
public void uploadFileToTransportRequestFailureTest() {
public void uploadFileToTransportRequestSOLMANFailureTest() {
ChangeManagement cm = new ChangeManagement(nullScript) {
void uploadFileToTransportRequest(BackendType type,
void uploadFileToTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String applicationId,
@ -152,19 +158,14 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
loggingRule.expect("[INFO] File '/path' has been successfully uploaded to transport request '002'.")
ChangeManagement cm = new ChangeManagement(nullScript) {
void uploadFileToTransportRequest(BackendType type,
String changeId,
void uploadFileToTransportRequestCTS(
String transportRequestId,
String applicationId,
String filePath,
String endpoint,
String credentialsId,
String cmclientOpts) {
cmUtilReceivedParams.type = type
cmUtilReceivedParams.changeId = changeId
cmUtilReceivedParams.transportRequestId = transportRequestId
cmUtilReceivedParams.applicationId = applicationId
cmUtilReceivedParams.filePath = filePath
cmUtilReceivedParams.endpoint = endpoint
cmUtilReceivedParams.credentialsId = credentialsId
@ -180,10 +181,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
assert cmUtilReceivedParams ==
[
type: BackendType.CTS,
changeId: null,
transportRequestId: '002',
applicationId: null,
filePath: '/path',
endpoint: 'https://example.org/cm',
credentialsId: 'CM',
@ -191,6 +189,166 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
]
}
@Test
public void uploadFileToTransportRequestRFCSanityChecksTest() {
thrown.expect(IllegalArgumentException)
thrown.expectMessage(allOf(
containsString('NO VALUE AVAILABLE FOR'),
containsString('applicationUrl'),
containsString('developmentInstance'),
containsString('developmentClient'),
containsString('applicationDescription'),
containsString('abapPackage'),
containsString('applicationName')))
stepRule.step.transportRequestUploadFile(script: nullScript,
transportRequestId: '123456', //no sanity check, can be read from git history
changeManagement: [type: 'RFC'],
)
}
@Test
public void uploadFileToTransportRequestRFCSuccessTest() {
def cmUtilsReceivedParams
nullScript.commonPipelineEnvironment.configuration =
[general:
[changeManagement:
[
endpoint: 'https://example.org/rfc'
]
]
]
def cm = new ChangeManagement(nullScript) {
void uploadFileToTransportRequestRFC(
Map docker,
String transportRequestId,
String applicationId,
String applicationURL,
String endpoint,
String credentialsId,
String developmentInstance,
String developmentClient,
String applicationDescription,
String abapPackage,
String codePage,
boolean acceptUnixStyleLineEndings,
boolean failUploadOnWarning,
boolean verbose) {
cmUtilsReceivedParams = [
docker: docker,
transportRequestId: transportRequestId,
applicationName: applicationId,
applicationURL: applicationURL,
endpoint: endpoint,
credentialsId: credentialsId,
developmentInstance: developmentInstance,
developmentClient: developmentClient,
applicationDescription: applicationDescription,
abapPackage: abapPackage,
codePage: codePage,
acceptUnixStyleLineEndings: acceptUnixStyleLineEndings,
failUploadOnWarning: failUploadOnWarning,
]
}
}
stepRule.step.transportRequestUploadFile(script: nullScript,
applicationUrl: 'http://example.org/blobstore/xyz.zip',
codePage: 'UTF-9',
acceptUnixStyleLineEndings: true,
transportRequestId: '123456',
changeManagement: [
type: 'RFC',
rfc: [
developmentClient: '002',
developmentInstance: '001'
]
],
applicationName: '42',
applicationDescription: 'Lorem ipsum',
abapPackage: 'XYZ',
cmUtils: cm,)
assert cmUtilsReceivedParams ==
[
docker: [
image: 'rfc',
options: [],
envVars: [:],
pullImage: true
],
transportRequestId: '123456',
applicationName: '42',
applicationURL: 'http://example.org/blobstore/xyz.zip',
endpoint: 'https://example.org/rfc',
credentialsId: 'CM',
developmentInstance: '001',
developmentClient: '002',
applicationDescription: 'Lorem ipsum',
abapPackage:'XYZ',
codePage: 'UTF-9',
acceptUnixStyleLineEndings: true,
failUploadOnWarning: true,
]
}
@Test
public void uploadFileToTransportRequestRFCUploadFailsTest() {
thrown.expect(AbortException)
thrown.expectMessage('upload failed')
def cm = new ChangeManagement(nullScript) {
void uploadFileToTransportRequestRFC(
Map docker,
String transportRequestId,
String applicationId,
String applicationURL,
String endpoint,
String credentialsId,
String developmentInstance,
String developmentClient,
String applicationDescription,
String abapPackage,
String codePage,
boolean acceptUnixStyleLineEndings,
boolean failOnUploadWarning,
boolean verbose) {
throw new ChangeManagementException('upload failed')
}
}
stepRule.step.transportRequestUploadFile(script: nullScript,
applicationUrl: 'http://example.org/blobstore/xyz.zip',
codePage: 'UTF-9',
acceptUnixStyleLineEndings: true,
transportRequestId: '123456',
changeManagement: [
type: 'RFC',
rfc: [
docker: [
image: 'rfc',
options: [],
envVars: [:],
pullImage: false,
],
developmentClient: '002',
developmentInstance: '001',
]
],
applicationName: '42',
applicationDescription: 'Lorem ipsum',
abapPackage: 'XYZ',
cmUtils: cm,)
}
@Test
public void uploadFileToTransportRequestSOLMANSuccessTest() {
@ -202,7 +360,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
loggingRule.expect("[INFO] File '/path' has been successfully uploaded to transport request '002' of change document '001'.")
ChangeManagement cm = new ChangeManagement(nullScript) {
void uploadFileToTransportRequest(BackendType type,
void uploadFileToTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String applicationId,
@ -211,7 +369,6 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
String credentialsId,
String cmclientOpts) {
cmUtilReceivedParams.type = type
cmUtilReceivedParams.changeId = changeId
cmUtilReceivedParams.transportRequestId = transportRequestId
cmUtilReceivedParams.applicationId = applicationId
@ -231,7 +388,6 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
assert cmUtilReceivedParams ==
[
type: BackendType.SOLMAN,
changeId: '001',
transportRequestId: '002',
applicationId: 'app',
@ -243,14 +399,14 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
}
@Test
public void uploadFileToTransportRequestSuccessApplicationIdFromConfigurationTest() {
public void uploadFileToTransportRequestSOLMANSuccessApplicationIdFromConfigurationTest() {
nullScript.commonPipelineEnvironment.configuration.put(['steps',
[transportRequestUploadFile:
[applicationId: 'AppIdfromConfig']]])
ChangeManagement cm = new ChangeManagement(nullScript) {
void uploadFileToTransportRequest(BackendType type,
void uploadFileToTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String applicationId,
@ -274,13 +430,13 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
}
@Test
public void uploadFileToTransportRequestFilePathFromParameters() {
public void uploadFileToTransportRequestSOLMANFilePathFromParameters() {
// this one is not used when file path is provided via signature
nullScript.commonPipelineEnvironment.setMtarFilePath('/path2')
ChangeManagement cm = new ChangeManagement(nullScript) {
void uploadFileToTransportRequest(BackendType type,
void uploadFileToTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String applicationId,
@ -304,13 +460,13 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
}
@Test
public void uploadFileToTransportRequestFilePathFromCommonPipelineEnvironment() {
public void uploadFileToTransportRequestSOLMANFilePathFromCommonPipelineEnvironment() {
// this one is used since there is nothing in the signature
nullScript.commonPipelineEnvironment.setMtarFilePath('/path2')
ChangeManagement cm = new ChangeManagement(nullScript) {
void uploadFileToTransportRequest(BackendType type,
void uploadFileToTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String applicationId,
@ -333,13 +489,13 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
}
@Test
public void uploadFileToTransportRequestUploadFailureTest() {
public void uploadFileToTransportRequestSOLMANUploadFailureTest() {
thrown.expect(AbortException)
thrown.expectMessage('Upload failure.')
ChangeManagement cm = new ChangeManagement(nullScript) {
void uploadFileToTransportRequest(BackendType type,
void uploadFileToTransportRequestSOLMAN(
String changeId,
String transportRequestId,
String applicationId,
@ -362,7 +518,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
@Test
public void invalidBackendTypeTest() {
thrown.expect(AbortException)
thrown.expectMessage('Invalid backend type: \'DUMMY\'. Valid values: [SOLMAN, CTS, NONE]. ' +
thrown.expectMessage('Invalid backend type: \'DUMMY\'. Valid values: [SOLMAN, CTS, RFC, NONE]. ' +
'Configuration: \'changeManagement/type\'.')
stepRule.step.transportRequestUploadFile(script: nullScript,

View File

@ -38,6 +38,7 @@ class UtilsTest extends BasePiperTest {
void setup() {
parameters = [:]
}
@Test
@ -70,4 +71,11 @@ class UtilsTest extends BasePiperTest {
// generated with "echo -n 'ContinuousDelivery' | sha1sum | sed 's/ -//'"
assertThat(result, is('0dad6c33b6246702132454f604dee80740f399ad'))
}
@Test
void testUnstashAllSkipNull() {
def stashResult = utils.unstashAll(['a', null, 'b'])
assert stashResult == ['a', 'b']
}
}

View File

@ -1,12 +1,13 @@
package com.sap.piper.cm
import static org.hamcrest.Matchers.allOf
import static org.hamcrest.Matchers.contains
import static org.hamcrest.Matchers.containsString
import static org.hamcrest.Matchers.equalTo
import static org.hamcrest.Matchers.hasItem
import static org.hamcrest.Matchers.is
import static org.hamcrest.Matchers.not
import static org.junit.Assert.assertThat
import static org.junit.Assert.assertEquals
import org.hamcrest.Matchers
import org.junit.Assert
@ -22,6 +23,7 @@ import util.JenkinsLoggingRule
import util.JenkinsScriptLoaderRule
import util.JenkinsShellCallRule
import util.JenkinsCredentialsRule
import util.JenkinsDockerExecuteRule
import util.Rules
import hudson.AbortException
@ -32,6 +34,7 @@ public class ChangeManagementTest extends BasePiperTest {
private JenkinsShellCallRule script = new JenkinsShellCallRule(this)
private JenkinsLoggingRule logging = new JenkinsLoggingRule(this)
private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this)
@Rule
public RuleChain rules = Rules.getCommonRules(this)
@ -39,6 +42,7 @@ public class ChangeManagementTest extends BasePiperTest {
.around(script)
.around(logging)
.around(new JenkinsCredentialsRule(this).withCredentials('me','user','password'))
.around(dockerExecuteRule)
@Test
public void testRetrieveChangeDocumentIdOutsideGitWorkTreeTest() {
@ -167,6 +171,57 @@ public void testGetCommandLineWithCMClientOpts() {
}
@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', // instance
'001', // client
'me', // credentialsId
'Lorem ipsum', // description
true // verbose
)
assert dockerExecuteRule.dockerParams.dockerImage == 'rfc'
assert dockerExecuteRule.dockerParams.dockerEnvVars == [
TRANSPORT_DESCRIPTION: 'Lorem ipsum',
ABAP_DEVELOPMENT_INSTANCE: '01',
ABAP_DEVELOPMENT_CLIENT: '001',
ABAP_DEVELOPMENT_SERVER: 'https://example.org/rfc',
ABAP_DEVELOPMENT_USER: 'user',
ABAP_DEVELOPMENT_PASSWORD: 'password',
VERBOSE: true
]
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
'001', // client
'01', // instance
'me', // credentialsId
'Lorem ipsum', // description
true, //verbose
)
}
@Test
public void testCreateTransportRequestCTSSucceeds() {
@ -185,32 +240,13 @@ public void testGetCommandLineWithCMClientOpts() {
}
@Test
public void testCreateTransportRequestFails() {
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '.*upload-file-to-transport.*', 1)
thrown.expect(ChangeManagementException)
thrown.expectMessage('Cannot upload file \'/path\' for change document \'001\''+
' with transport request \'002\'. Return code from cmclient: 1.')
new ChangeManagement(nullScript).uploadFileToTransportRequest(BackendType.SOLMAN,
'001',
'002',
'XXX',
'/path',
'https://example.org/cm',
'me')
}
@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).uploadFileToTransportRequest(
BackendType.SOLMAN,
new ChangeManagement(nullScript).uploadFileToTransportRequestSOLMAN(
'001',
'002',
'XXX',
@ -228,11 +264,8 @@ public void testGetCommandLineWithCMClientOpts() {
// 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).uploadFileToTransportRequest(
BackendType.CTS,
null,
new ChangeManagement(nullScript).uploadFileToTransportRequestCTS(
'002',
null,
'/path',
'https://example.org/cm',
'me')
@ -242,15 +275,85 @@ public void testGetCommandLineWithCMClientOpts() {
}
@Test
public void testUploadFileToTransportFails() {
public void testUploadFileToTransportSucceedsRFC() {
new ChangeManagement(nullScript).uploadFileToTransportRequestRFC(
[image:'rfc', options: [], pullImage: true],
'002', //transportRequestId
'001', // applicationId
'https://example.org/mypath/deployArtifact.zip',
'https://example.org/rfc',
'me',
'00', //developmentInstance
'001', // developmentClient
'Lorem ipsum', // applicationDescription
'XYZ', // abapPackage
'UTF-9', //codePage
true, // accept unix style EOL
true, // failUploadOnWarning
false, // verbose
)
assert dockerExecuteRule.dockerParams.dockerImage == 'rfc'
assert dockerExecuteRule.dockerParams.dockerPullImage == true
assert dockerExecuteRule.dockerParams.dockerEnvVars ==
[
ABAP_DEVELOPMENT_INSTANCE: '00',
ABAP_DEVELOPMENT_CLIENT: '001',
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',
CODE_PAGE: 'UTF-9',
ABAP_ACCEPT_UNIX_STYLE_EOL: 'X',
FAIL_UPLOAD_ON_WARNING: 'true',
VERBOSE: 'false'
]
assertThat(script.shell, contains('cts uploadToABAP:002'))
}
@Test
public void testUploadFileToTransportFailsRFC() {
thrown.expect(ChangeManagementException)
thrown.expectMessage("Cannot upload file '/path' for change document '001' with transport request '002'. " +
"Return code from cmclient: 1.")
thrown.expectMessage('Cannot upload file into transport request. Return code from rfc client: 1.')
script.setReturnValue('cts uploadToABAP:002', 1)
new ChangeManagement(nullScript).uploadFileToTransportRequestRFC(
[:],
'002', //transportRequestId
'001', // applicationId
'https://example.org/mypath/deployArtifact.zip',
'https://example.org/rfc',
'me',
'00', //developmentInstance
'001', // developmentClient
'Lorem ipsum', // applicationDescription
'XYZ', // abapPackage
'UTF-9', // codePage
true, // accept unix style EOL
true, // failUploadOnWarning
false, // verbose
)
}
@Test
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).uploadFileToTransportRequest(BackendType.SOLMAN,
new ChangeManagement(nullScript).uploadFileToTransportRequestSOLMAN(
'001',
'002',
'XXX',
@ -265,8 +368,7 @@ public void testGetCommandLineWithCMClientOpts() {
// 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).releaseTransportRequest(
BackendType.SOLMAN,
new ChangeManagement(nullScript).releaseTransportRequestSOLMAN(
'001',
'002',
'https://example.org',
@ -283,9 +385,7 @@ public void testGetCommandLineWithCMClientOpts() {
// the regex provided below is an implicit check that the command line is fine.
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t CTS export-transport.*-tID 002', 0)
new ChangeManagement(nullScript).releaseTransportRequest(
BackendType.CTS,
null,
new ChangeManagement(nullScript).releaseTransportRequestCTS(
'002',
'https://example.org',
'me',
@ -296,7 +396,31 @@ public void testGetCommandLineWithCMClientOpts() {
}
@Test
public void testReleaseTransportRequestFails() {
public void testReleaseTransportRequestSucceedsRFC() {
new ChangeManagement(nullScript).releaseTransportRequestRFC(
[:],
'002',
'https://example.org',
'002',
'001',
'me',
true)
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',
VERBOSE: true,
]
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.")
@ -304,16 +428,13 @@ public void testGetCommandLineWithCMClientOpts() {
// 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).releaseTransportRequest(
BackendType.SOLMAN,
new ChangeManagement(nullScript).releaseTransportRequestSOLMAN(
'001',
'002',
'https://example.org',
'me',
'openSesame')
'me')
}
private GitUtils gitUtilsMock(boolean insideWorkTree, String[] changeIds) {
return new GitUtils() {
public boolean insideWorkTree() {

View File

@ -16,19 +16,30 @@ void call(Map parameters = [:], body) {
echo "--- Begin library step of: ${stepName} ---"
body()
} catch (Throwable err) {
} catch (Throwable error) {
if (verbose)
message += SimpleTemplateEngine.newInstance()
.createTemplate(libraryResource('com.sap.piper/templates/error.log'))
.make([
stepName: stepName,
stepParameters: stepParameters?.toString(),
error: err
error: error
]).toString()
throw err
writeErrorToInfluxData(parameters, error)
throw error
} finally {
if (verbose)
message += "--- End library step of: ${stepName} ---"
echo message
}
}
private void writeErrorToInfluxData(config, error){
def script = config?.stepParameters?.script
if(script && script.commonPipelineEnvironment?.getInfluxCustomDataMapTags().build_error_message == null){
script.commonPipelineEnvironment?.setInfluxCustomDataMapTagsEntry('pipeline_data', 'build_error_step', config.stepName)
script.commonPipelineEnvironment?.setInfluxCustomDataMapTagsEntry('pipeline_data', 'build_error_stage', script.env?.STAGE_NAME)
script.commonPipelineEnvironment?.setInfluxCustomDataMapEntry('pipeline_data', 'build_error_message', error.getMessage())
}
}

View File

@ -14,7 +14,7 @@ void call(Map parameters = [:]) {
handlePipelineStepErrors (stepName: 'toolValidate', stepParameters: parameters) {
echo '[WARNING][toolValidate] This step is deprecated, and it will be removed in future versions. Validation is automatically done inside the steps.'
echo '[WARNING][toolValidate] This step is deprecated, and it will be removed in future versions.'
def tool = parameters.tool
def home = parameters.home

View File

@ -23,6 +23,7 @@ import hudson.AbortException
'developmentSystemId', // SOLMAN
'targetSystem', // CTS
'transportType', // CTS
'verbose', // RFC
]
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus(['changeDocumentId'])
@ -38,6 +39,7 @@ void call(parameters = [:]) {
ChangeManagement cm = parameters.cmUtils ?: new ChangeManagement(script)
ConfigurationHelper configHelper = ConfigurationHelper.newInstance(this)
.collectValidationFailures()
.loadStepDefaults()
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
@ -60,6 +62,9 @@ void call(parameters = [:]) {
.withMandatoryProperty('transportType', null, { backendType == BackendType.CTS})
.withMandatoryProperty('targetSystem', null, { backendType == BackendType.CTS})
.withMandatoryProperty('description', null, { backendType == BackendType.CTS})
.withMandatoryProperty('changeManagement/rfc/developmentInstance', null, {backendType == BackendType.RFC})
.withMandatoryProperty('changeManagement/rfc/developmentClient', null, {backendType == BackendType.RFC})
.withMandatoryProperty('verbose', null, {backendType == BackendType.RFC})
def changeDocumentId = null
@ -88,7 +93,8 @@ void call(parameters = [:]) {
creatingMessage << '.'
echo creatingMessage.join()
try {
try {
if(backendType == BackendType.SOLMAN) {
transportRequestId = cm.createTransportRequestSOLMAN(
configuration.changeDocumentId,
@ -104,6 +110,15 @@ void call(parameters = [:]) {
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.clientOpts)
} else if (backendType == BackendType.RFC) {
transportRequestId = cm.createTransportRequestRFC(
configuration.changeManagement.rfc.docker,
configuration.changeManagement.endpoint,
configuration.changeManagement.rfc.developmentInstance,
configuration.changeManagement.rfc.developmentClient,
configuration.changeManagement.credentialsId,
configuration.description,
configuration.verbose)
} else {
throw new IllegalArgumentException("Invalid backend type: '${backendType}'.")
}

View File

@ -25,6 +25,7 @@ import static com.sap.piper.cm.StepHelpers.getBackendTypeAndLogInfoIfCMIntegrati
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus([
'changeDocumentId',
'transportRequestId',
'verbose',
])
void call(parameters = [:]) {
@ -49,12 +50,16 @@ void call(parameters = [:]) {
if(backendType == BackendType.NONE) return
configHelper
.collectValidationFailures()
.withMandatoryProperty('changeManagement/clientOpts')
.withMandatoryProperty('changeManagement/credentialsId')
.withMandatoryProperty('changeManagement/endpoint')
.withMandatoryProperty('changeManagement/git/to')
.withMandatoryProperty('changeManagement/git/from')
.withMandatoryProperty('changeManagement/git/format')
.withMandatoryProperty('changeManagement/rfc/developmentInstance', null, { backendType == BackendType.RFC})
.withMandatoryProperty('changeManagement/rfc/developmentClient', null, { backendType == BackendType.RFC})
.withMandatoryProperty('verbose', null, { backendType == BackendType.RFC})
configuration = configHelper.use()
@ -89,13 +94,44 @@ void call(parameters = [:]) {
echo closingMessage.join()
try {
cm.releaseTransportRequest(backendType,
configuration.changeDocumentId,
configuration.transportRequestId,
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.clientOpts)
switch(backendType) {
case BackendType.SOLMAN:
cm.releaseTransportRequestSOLMAN(
configuration.changeDocumentId,
configuration.transportRequestId,
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.clientOpts)
break
case BackendType.CTS:
cm.releaseTransportRequestCTS(
configuration.transportRequestId,
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.clientOpts)
break
case BackendType.RFC:
cm.releaseTransportRequestRFC(
configuration.changeManagement.rfc.docker,
configuration.transportRequestId,
configuration.changeManagement.endpoint,
configuration.changeManagement.rfc.developmentInstance,
configuration.changeManagement.rfc.developmentClient,
configuration.changeManagement.credentialsId,
configuration.verbose)
break
default:
throw new IllegalArgumentException("Invalid backend type: '${backendType}'.")
}
} catch(ChangeManagementException ex) {
throw new AbortException(ex.getMessage())
}

View File

@ -21,12 +21,19 @@ import static com.sap.piper.cm.StepHelpers.getBackendTypeAndLogInfoIfCMIntegrati
]
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
'applicationId'
'applicationName', // RFC
'applicationId', // SOLMAN
'applicationDescription',
'filePath', // SOLMAN, CTS
'applicationUrl', // RFC
'abapPackage',
'codePage', //RFC
'acceptUnixStyleLineEndings', // RFC
'verbose', // RFC
])
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus([
'changeDocumentId',
'filePath',
'transportRequestId'])
void call(parameters = [:]) {
@ -51,6 +58,7 @@ void call(parameters = [:]) {
if(backendType == BackendType.NONE) return
configHelper
.collectValidationFailures()
.withMandatoryProperty('changeManagement/changeDocumentLabel')
.withMandatoryProperty('changeManagement/clientOpts')
.withMandatoryProperty('changeManagement/credentialsId')
@ -59,7 +67,22 @@ void call(parameters = [:]) {
.withMandatoryProperty('changeManagement/git/from')
.withMandatoryProperty('changeManagement/git/to')
.withMandatoryProperty('changeManagement/git/format')
.withMandatoryProperty('filePath')
.withMandatoryProperty('filePath', null, { backendType in [BackendType.SOLMAN, BackendType.CTS] })
.withMandatoryProperty('applicationUrl', null, { backendType == BackendType.RFC })
.withMandatoryProperty('codePage', null, { backendType == BackendType.RFC })
.withMandatoryProperty('acceptUnixStyleLineEndings', null, { backendType == BackendType.RFC })
.withMandatoryProperty('changeManagement/rfc/developmentInstance', null, { backendType == BackendType.RFC })
.withMandatoryProperty('changeManagement/rfc/developmentClient', null, { backendType == BackendType.RFC })
.withMandatoryProperty('changeManagement/rfc/docker/image', null, {backendType == BackendType.RFC})
.withMandatoryProperty('changeManagement/rfc/docker/options', null, {backendType == BackendType.RFC})
.withMandatoryProperty('changeManagement/rfc/docker/envVars', null, {backendType == BackendType.RFC})
.withMandatoryProperty('changeManagement/rfc/docker/pullImage', null, {backendType == BackendType.RFC})
.withMandatoryProperty('applicationDescription', null, { backendType == BackendType.RFC })
.withMandatoryProperty('abapPackage', null, { backendType == BackendType.RFC })
.withMandatoryProperty('applicationId', null, {backendType == BackendType.SOLMAN})
.withMandatoryProperty('applicationName', null, {backendType == BackendType.RFC})
.withMandatoryProperty('failOnWarning', null, {backendType == BackendType.RFC})
.withMandatoryProperty('verbose', null, {backendType == BackendType.RFC})
new Utils().pushToSWA([
step: STEP_NAME,
@ -85,14 +108,15 @@ void call(parameters = [:]) {
configHelper
.withMandatoryProperty('changeDocumentId',
"Change document id not provided (parameter: \'changeDocumentId\' or via commit history).")
.withMandatoryProperty('applicationId')
}
configuration = configHelper
.withMandatoryProperty('transportRequestId',
"Transport request id not provided (parameter: \'transportRequestId\' or via commit history).")
.use()
def uploadingMessage = ["[INFO] Uploading file '${configuration.filePath}' to transport request '${configuration.transportRequestId}'"]
def uploadingMessage = ['[INFO] Uploading file ' +
"'${backendType == BackendType.RFC ? configuration.applicationUrl : configuration.filePath}' " +
"to transport request '${configuration.transportRequestId}'"]
if(backendType == BackendType.SOLMAN)
uploadingMessage << " of change document '${configuration.changeDocumentId}'"
uploadingMessage << '.'
@ -101,22 +125,55 @@ void call(parameters = [:]) {
try {
switch(backendType) {
cm.uploadFileToTransportRequest(backendType,
configuration.changeDocumentId,
configuration.transportRequestId,
configuration.applicationId,
configuration.filePath,
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.clientOpts)
case BackendType.SOLMAN:
cm.uploadFileToTransportRequestSOLMAN(
configuration.changeDocumentId,
configuration.transportRequestId,
configuration.applicationId,
configuration.filePath,
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.clientOpts)
break
case BackendType.CTS:
cm.uploadFileToTransportRequestCTS(
configuration.transportRequestId,
configuration.filePath,
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.clientOpts)
break
case BackendType.RFC:
cm.uploadFileToTransportRequestRFC(
configuration.changeManagement.rfc.docker ?: [],
configuration.transportRequestId,
configuration.applicationName,
configuration.applicationUrl,
configuration.changeManagement.endpoint,
configuration.changeManagement.credentialsId,
configuration.changeManagement.rfc.developmentInstance,
configuration.changeManagement.rfc.developmentClient,
configuration.applicationDescription,
configuration.abapPackage,
configuration.codePage,
configuration.acceptUnixStyleLineEndings,
configuration.failOnWarning,
configuration.verbose
)
break
}
} catch(ChangeManagementException ex) {
throw new AbortException(ex.getMessage())
}
def uploadedMessage = ["[INFO] File '${configuration.filePath}' has been successfully uploaded to transport request '${configuration.transportRequestId}'"]
def uploadedMessage = ["[INFO] File '${backendType == BackendType.RFC ? configuration.applicationUrl : configuration.filePath}' has been successfully uploaded to transport request '${configuration.transportRequestId}'"]
if(backendType == BackendType.SOLMAN)
uploadedMessage << " of change document '${configuration.changeDocumentId}'"
uploadedMessage << '.'

View File

@ -74,7 +74,12 @@ import static com.sap.piper.Prerequisites.checkScript
/**
* With `testRepository` the tests can be loaded from another reposirory.
*/
'testRepository'
'testRepository',
/**
* The `testServerUrl` is passed as environment variable `TARGET_SERVER_URL` to the test execution.
* The tests should read the host information from this environment variable in order to be infrastructure agnostic.
*/
'testServerUrl'
])
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
@ -123,6 +128,7 @@ void call(Map parameters = [:]) {
config.stashContent = config.testRepository ? [GitUtils.handleTestRepository(this, config)] : utils.unstashAll(config.stashContent)
config.installCommand = SimpleTemplateEngine.newInstance().createTemplate(config.installCommand).make([config: config]).toString()
config.runCommand = SimpleTemplateEngine.newInstance().createTemplate(config.runCommand).make([config: config]).toString()
config.dockerEnvVars.TARGET_SERVER_URL = config.dockerEnvVars.TARGET_SERVER_URL ?: config.testServerUrl
seleniumExecuteTests(
script: script,