mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-14 11:03:09 +02:00
Merge remote-tracking branch 'github/master' into HEAD
This commit is contained in:
commit
d4b0549f74
2
.gitignore
vendored
2
.gitignore
vendored
@ -16,4 +16,4 @@ target/
|
||||
targets/
|
||||
documentation/docs-gen
|
||||
|
||||
consumer-test/workspace
|
||||
consumer-test/**/workspace
|
||||
|
@ -1,6 +1,7 @@
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^it\/.*$/
|
||||
language: groovy
|
||||
sudo: required
|
||||
services:
|
||||
@ -35,8 +36,9 @@ jobs:
|
||||
cp -r documentation/docs documentation/docs-tmp
|
||||
documentation/bin/createDocu.sh vars documentation/docs-tmp/steps
|
||||
docker run --rm -it -v ${TRAVIS_BUILD_DIR}:/docs -w /docs/documentation squidfunk/mkdocs-material:3.0.4 build --clean --verbose --strict
|
||||
- name: Consumer Tests for s4sdk pipeline
|
||||
script: cd consumer-test && chmod +x runTests.sh && ./runTests.sh
|
||||
- name: Consumer Tests
|
||||
if: repo = "SAP/jenkins-library" && ( (type != pull_request && branch =~ /^master$|^it\/.*$/) || (type == pull_request && head_repo = "SAP/jenkins-library" && head_branch =~ /^it\/.*$/) )
|
||||
script: cd consumer-test && chmod +x integrationTestController.sh && ./integrationTestController.sh
|
||||
|
||||
- stage: Docs
|
||||
name: Deploy
|
||||
|
19
Jenkinsfile
vendored
19
Jenkinsfile
vendored
@ -1,19 +0,0 @@
|
||||
node {
|
||||
try {
|
||||
lock(resource: "sap-jenkins-library/10", inversePrecedence: true) {
|
||||
milestone 10
|
||||
deleteDir()
|
||||
stage ('Checkout'){
|
||||
checkout scm
|
||||
}
|
||||
stage ('Test') {
|
||||
sh "mvn clean test --batch-mode"
|
||||
}
|
||||
}
|
||||
} catch (Throwable err) {
|
||||
echo "Error occured: ${err}"
|
||||
currentBuild.result = 'FAILURE'
|
||||
mail subject: '[Build failed] SAP/jenkins-library', body: 'Fix the build.', to: 'marcus.holl@sap.com,oliver.nocon@sap.com'
|
||||
throw err
|
||||
}
|
||||
}
|
@ -108,7 +108,7 @@ Register to our [google group][google-group] in order to get updates or for aski
|
||||
Read and understand our [contribution guidelines][piper-library-contribution]
|
||||
before opening a pull request.
|
||||
|
||||
# [License][piper-library-license]
|
||||
# License
|
||||
|
||||
Copyright (c) 2017 SAP SE or an SAP affiliate company. All rights reserved.
|
||||
This file is licensed under the Apache Software License, v. 2 except as noted
|
||||
|
138
consumer-test/integrationTestController.sh
Executable file
138
consumer-test/integrationTestController.sh
Executable file
@ -0,0 +1,138 @@
|
||||
#!/bin/bash
|
||||
|
||||
function fail() {
|
||||
local message="$1"
|
||||
local returnCode=${2:-1}
|
||||
echo "[ERROR] ${message}" >&2
|
||||
exit "${returnCode}"
|
||||
}
|
||||
|
||||
function notify() {
|
||||
|
||||
local state=${1}
|
||||
local description=${2}
|
||||
local hash=${3}
|
||||
|
||||
echo "[INFO] Notifying about state \"${state}\" for commit \"${hash}\"."
|
||||
|
||||
curl -X POST \
|
||||
--fail \
|
||||
--silent \
|
||||
--output /dev/null \
|
||||
--data "{\"state\": \"${state}\", \"target_url\": \"${TRAVIS_BUILD_WEB_URL}\", \"description\": \"${description}\", \"context\": \"integration-tests\"}" \
|
||||
--user "${INTEGRATION_TEST_VOTING_USER}:${INTEGRATION_TEST_VOTING_TOKEN}" \
|
||||
"https://api.github.com/repos/SAP/jenkins-library/statuses/${hash}" || fail "Cannot send notification. curl return code: $?"
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
[ -z "${notificationThreadPid}" ] || kill -PIPE "${notificationThreadPid}" &>/dev/null
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
#
|
||||
# In case the build is performed for a pull request TRAVIS_COMMIT is a merge
|
||||
# commit between the base branch and the PR branch HEAD. That commit is actually built.
|
||||
# But for notifying about a build status we need the commit which is currenty
|
||||
# the HEAD of the PR branch.
|
||||
#
|
||||
# In case the build is performed for a simple branch (not associated with a PR)
|
||||
# In this case there is no merge commit between any base branch and HEAD of a PR branch.
|
||||
# The commit which we need for notifying about a build status is in this case simply
|
||||
# TRAVIS_COMMIT itself.
|
||||
#
|
||||
COMMIT_HASH_FOR_STATUS_NOTIFICATIONS="${TRAVIS_PULL_REQUEST_SHA}"
|
||||
[ -z "${COMMIT_HASH_FOR_STATUS_NOTIFICATIONS}" ] && COMMIT_HASH_FOR_STATUS_NOTIFICATIONS="${TRAVIS_COMMIT}"
|
||||
|
||||
notify "pending" "Integration tests in progress." "${COMMIT_HASH_FOR_STATUS_NOTIFICATIONS}"
|
||||
|
||||
WORKSPACES_ROOT=workspaces
|
||||
[ -e "${WORKSPACES_ROOT}" ] && rm -rf ${WORKSPACES_ROOT}
|
||||
|
||||
TEST_CASES=$(find testCases -name '*.yml')
|
||||
|
||||
# This auxiliar thread is needed in order to produce some output while the
|
||||
# test are running. Otherwise the job will be canceled after 10 minutes without
|
||||
# output.
|
||||
while true; do sleep 10; echo "[INFO] Integration tests still running."; done &
|
||||
notificationThreadPid=$!
|
||||
|
||||
declare -a processes
|
||||
i=0
|
||||
for f in ${TEST_CASES}
|
||||
do
|
||||
testCase=$(basename "${f%.*}")
|
||||
area=$(dirname "${f#*/}")
|
||||
echo "[INFO] Running test case \"${testCase}\" in area \"${area}\"."
|
||||
TEST_CASE_ROOT="${WORKSPACES_ROOT}/${area}/${testCase}"
|
||||
[ -e "${TEST_CASE_ROOT}" ] && rm -rf "${TEST_CASE_ROOT}"
|
||||
mkdir -p "${TEST_CASE_ROOT}" || fail "Cannot create test case root directory for test case \"${testCase}\"." 1
|
||||
source ./runTest.sh "${testCase}" "${TEST_CASE_ROOT}" &> "${TEST_CASE_ROOT}/log.txt" &
|
||||
pid=$!
|
||||
processes[$i]="${area}/${testCase}:${pid}"
|
||||
echo "[INFO] Test case \"${testCase}\" in area \"${area}\" launched. (PID: \"${pid}\")."
|
||||
let i=i+1
|
||||
done
|
||||
|
||||
[ "${i}" == 0 ] && fail "No tests has been executed." 1
|
||||
|
||||
#
|
||||
# wait for the test cases and cat the log
|
||||
for p in "${processes[@]}"
|
||||
do
|
||||
area=$(dirname "${p%:*}")
|
||||
testCase=$(basename "${p%:*}")
|
||||
processId="${p#*:}"
|
||||
echo "[INFO] Waiting for test case \"${testCase}\" in area \"${area}\" (PID: \"${processId}\")."
|
||||
wait "${processId}"
|
||||
echo "[INFO] Test case \"${testCase}\" in area \"${area}\" finished (PID: \"${processId}\")."
|
||||
done
|
||||
|
||||
kill -PIPE "${notificationThreadPid}" &>/dev/null && notificationThreadPid=""
|
||||
|
||||
#
|
||||
# provide the logs
|
||||
for p in "${processes[@]}"
|
||||
do
|
||||
area=$(dirname "${p%:*}")
|
||||
testCase=$(basename "${p%:*}")
|
||||
echo "[INFO] === START === Logs for test case \"${testCase}\" ===."
|
||||
cat "${TEST_CASE_ROOT}/log.txt"
|
||||
echo "[INFO] === END === Logs for test case \"${testCase}\" ===."
|
||||
done
|
||||
|
||||
#
|
||||
# list test case status
|
||||
echo "[INFO] Build status:"
|
||||
failure="false"
|
||||
for p in "${processes[@]}"
|
||||
do
|
||||
status="UNDEFINED"
|
||||
area=$(dirname "${p%:*}")
|
||||
testCase=$(basename "${p%:*}")
|
||||
TEST_CASE_ROOT="${WORKSPACES_ROOT}/${area}/${testCase}"
|
||||
if [ -f "${TEST_CASE_ROOT}/SUCCESS" ]
|
||||
then
|
||||
status="SUCCESS"
|
||||
else
|
||||
status="FAILURE"
|
||||
failure="true"
|
||||
fi
|
||||
printf "[INFO] %-30s: %s\n" "${testCase}" "${status}"
|
||||
done
|
||||
|
||||
STATUS_DESCRIPTION="The integration tests failed."
|
||||
STATUS_STATE="failure"
|
||||
|
||||
if [ "${failure}" == "false" ]
|
||||
then
|
||||
STATUS_DESCRIPTION="The integration tests succeeded."
|
||||
STATUS_STATE="success"
|
||||
fi
|
||||
|
||||
notify "${STATUS_STATE}" "${STATUS_DESCRIPTION}" "${COMMIT_HASH_FOR_STATUS_NOTIFICATIONS}"
|
||||
|
||||
[ "${failure}" != "false" ] && fail "Integration tests failed." 1
|
||||
|
||||
echo "[INFO] Integration tests succeeded."
|
||||
exit 0
|
30
consumer-test/runTest.sh
Executable file
30
consumer-test/runTest.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
TEST_CASE=$1
|
||||
TEST_CASE_ROOT=$2
|
||||
TEST_CASE_WORKSPACE="${TEST_CASE_ROOT}/workspace"
|
||||
|
||||
LIBRARY_VERSION_UNDER_TEST=$(git log --format="%H" -n 1)
|
||||
REPOSITORY_UNDER_TEST=${TRAVIS_REPO_SLUG:-SAP/jenkins-library}
|
||||
|
||||
git clone -b "${TEST_CASE}" https://github.com/sap/cloud-s4-sdk-book "${TEST_CASE_WORKSPACE}"
|
||||
cp -f jenkins.yml "${TEST_CASE_WORKSPACE}"
|
||||
cd "${TEST_CASE_WORKSPACE}" || exit 1
|
||||
|
||||
# Configure path to library-repository under test in Jenkins config
|
||||
sed -i -e "s:__REPO_SLUG__:${REPOSITORY_UNDER_TEST}:g" jenkins.yml
|
||||
|
||||
# Force usage of library version under test by setting it in the Jenkinsfile which is then the first definition and thus has the highest precedence
|
||||
echo "@Library(\"piper-library-os@$LIBRARY_VERSION_UNDER_TEST\") _" | cat - Jenkinsfile > temp && mv temp Jenkinsfile
|
||||
|
||||
# Commit the changed version because artifactSetVersion expects the git repo not to be dirty
|
||||
git commit --all --author="piper-testing-bot <piper-testing-bot@example.com>" --message="Set piper lib version for test"
|
||||
|
||||
docker run -v /var/run/docker.sock:/var/run/docker.sock -v "${PWD}":/workspace -v /tmp -e CASC_JENKINS_CONFIG=/workspace/jenkins.yml \
|
||||
-e CX_INFRA_IT_CF_USERNAME -e CX_INFRA_IT_CF_PASSWORD -e BRANCH_NAME="${TEST_CASE}" ppiper/jenkinsfile-runner
|
||||
|
||||
RC=$?
|
||||
|
||||
cd - &> /dev/null || { echo "[ERROR] change directory back into integration test root folder failed."; exit 1; }
|
||||
|
||||
[ "${RC}" == 0 ] && touch "${TEST_CASE_ROOT}/SUCCESS"
|
@ -1,14 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
LIBRARY_VERSION_UNDER_TEST=$(git log --format="%H" -n 1)
|
||||
REPOSITORY_UNDER_TEST=${TRAVIS_REPO_SLUG:-SAP/jenkins-library}
|
||||
|
||||
rm -rf workspace
|
||||
git clone -b consumer-test https://github.com/sap/cloud-s4-sdk-book workspace
|
||||
cp -f jenkins.yml workspace
|
||||
cd workspace
|
||||
sed -i -e "s:__REPO_SLUG__:${REPOSITORY_UNDER_TEST}:g" jenkins.yml
|
||||
echo "@Library(\"piper-library-os@$LIBRARY_VERSION_UNDER_TEST\") _" | cat - Jenkinsfile > temp && mv temp Jenkinsfile
|
||||
git commit --all --author="piper-testing-bot <null@null.com>" --message="Set piper lib version for test"
|
||||
|
||||
docker run -v /var/run/docker.sock:/var/run/docker.sock -v "${PWD}":/workspace -v /tmp -e CASC_JENKINS_CONFIG=/workspace/jenkins.yml -e CX_INFRA_IT_CF_USERNAME -e CX_INFRA_IT_CF_PASSWORD -e BRANCH_NAME=consumer-test ppiper/jenkinsfile-runner
|
2
consumer-test/testCases/s4sdk/consumer-test-neo.yml
Normal file
2
consumer-test/testCases/s4sdk/consumer-test-neo.yml
Normal file
@ -0,0 +1,2 @@
|
||||
# Empty for the moment.
|
||||
# Might contain test configuration in the future.
|
2
consumer-test/testCases/s4sdk/consumer-test.yml
Normal file
2
consumer-test/testCases/s4sdk/consumer-test.yml
Normal file
@ -0,0 +1,2 @@
|
||||
# Empty for the moment.
|
||||
# Might contain test configuration in the future.
|
@ -2,7 +2,7 @@
|
||||
|
||||
## Description
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -10,11 +10,11 @@ Content here is generated from corresponnding step, see `vars`.
|
||||
|
||||
## Parameters
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Step configuration
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Exceptions
|
||||
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
## Description
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Parameters
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Kubernetes support
|
||||
|
||||
@ -14,7 +14,7 @@ If the Jenkins is setup on a Kubernetes cluster, then you can execute the closur
|
||||
|
||||
## Step configuration
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Side effects
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
## Description
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -13,11 +13,11 @@ Content here is generated from corresponnding step, see `vars`.
|
||||
|
||||
## Parameters
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Step configuration
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Side effects
|
||||
|
||||
|
@ -2,82 +2,20 @@
|
||||
|
||||
## Description
|
||||
|
||||
In this step the ([Karma test runner](http://karma-runner.github.io)) is executed.
|
||||
|
||||
The step is using the `seleniumExecuteTest` step to spins up two containers in a Docker network:
|
||||
|
||||
- a Selenium/Chrome container (`selenium/standalone-chrome`)
|
||||
- a NodeJS container (`node:8-stretch`)
|
||||
|
||||
In the Docker network, the containers can be referenced by the values provided in `dockerName` and `sidecarName`, the default values are `karma` and `selenium`. These values must be used in the `hostname` properties of the test configuration ([Karma](https://karma-runner.github.io/1.0/config/configuration-file.html) and [WebDriver](https://github.com/karma-runner/karma-webdriver-launcher#usage)).
|
||||
|
||||
!!! note
|
||||
In a Kubernetes environment, the containers both need to be referenced with `localhost`.
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **running Karma tests** - have a NPM module with running tests executed with Karma
|
||||
- **configured WebDriver** - have the [`karma-webdriver-launcher`](https://github.com/karma-runner/karma-webdriver-launcher) package installed and a custom, WebDriver-based browser configured in Karma
|
||||
* **running Karma tests** - have a NPM module with running tests executed with Karma
|
||||
* **configured WebDriver** - have the [`karma-webdriver-launcher`](https://github.com/karma-runner/karma-webdriver-launcher) package installed and a custom, WebDriver-based browser configured in Karma
|
||||
|
||||
## Parameters
|
||||
|
||||
| parameter | mandatory | default | possible values |
|
||||
| ----------|-----------|---------|-----------------|
|
||||
|script|yes|||
|
||||
|containerPortMappings|no|`[node:8-stretch: [[containerPort: 9876, hostPort: 9876]]]`||
|
||||
|dockerEnvVars|no|`[ NO_PROXY: 'localhost,karma,$NO_PROXY', no_proxy: 'localhost,karma,$no_proxy']`||
|
||||
|dockerImage|no|`node:8-stretch`||
|
||||
|dockerName|no|`karma`||
|
||||
|dockerWorkspace|no|`/home/node`||
|
||||
|failOnError|no|||
|
||||
|installCommand|no|`npm install --quiet`||
|
||||
|modules|no|`['.']`||
|
||||
|runCommand|no|`npm run karma`||
|
||||
|sidecarEnvVars|no|`[ NO_PROXY: 'localhost,selenium,$NO_PROXY', no_proxy: 'localhost,selenium,$no_proxy']`||
|
||||
|sidecarImage|no|||
|
||||
|sidecarName|no|||
|
||||
|sidecarVolumeBind|no|||
|
||||
|stashContent|no|`['buildDescriptor', 'tests']`||
|
||||
|
||||
- `script` - defines the global script environment of the Jenkinsfile run. Typically `this` is passed to this parameter. This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md) for storing the measured duration.
|
||||
- `containerPortMappings` - see step [dockerExecute](dockerExecute.md)
|
||||
- `dockerEnvVars` - see step [dockerExecute](dockerExecute.md)
|
||||
- `dockerImage` - see step [dockerExecute](dockerExecute.md)
|
||||
- `dockerName` - see step [dockerExecute](dockerExecute.md)
|
||||
- `dockerWorkspace` - see step [dockerExecute](dockerExecute.md)
|
||||
- `failOnError` - see step [seleniumExecuteTests](seleniumExecuteTests.md)
|
||||
- `installCommand` - the command that is executed to install dependencies
|
||||
- `modules` - define the paths of the modules to execute tests on
|
||||
- `runCommand` - the command that is executed to start the tests
|
||||
- `sidecarEnvVars` - see step [dockerExecute](dockerExecute.md)
|
||||
- `sidecarImage` - see step [dockerExecute](dockerExecute.md)
|
||||
- `sidecarName` - see step [dockerExecute](dockerExecute.md)
|
||||
- `sidecarVolumeBind` - see step [dockerExecute](dockerExecute.md)
|
||||
- `stashContent` - pass specific stashed that should be considered for the tests
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
|
||||
## Step configuration
|
||||
|
||||
We recommend to define values of step parameters via [config.yml file](../configuration.md).
|
||||
|
||||
In following sections the configuration is possible:
|
||||
|
||||
| parameter | general | step | stage |
|
||||
| ----------|---------|------|-------|
|
||||
|script||||
|
||||
|containerPortMappings|X|X|X|
|
||||
|dockerEnvVars|X|X|X|
|
||||
|dockerImage|X|X|X|
|
||||
|dockerName|X|X|X|
|
||||
|dockerWorkspace|X|X|X|
|
||||
|failOnError|X|X|X|
|
||||
|installCommand|X|X|X|
|
||||
|modules|X|X|X|
|
||||
|runCommand|X|X|X|
|
||||
|sidecarEnvVars|X|X|X|
|
||||
|sidecarImage|X|X|X|
|
||||
|sidecarName|X|X|X|
|
||||
|sidecarVolumeBind|X|X|X|
|
||||
|stashContent|X|X|X|
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
|
||||
## Side effects
|
||||
|
||||
|
23
documentation/docs/steps/npmExecute.md
Normal file
23
documentation/docs/steps/npmExecute.md
Normal file
@ -0,0 +1,23 @@
|
||||
# npmExecute
|
||||
|
||||
## Description
|
||||
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Parameters
|
||||
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Step configuration
|
||||
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Exceptions
|
||||
|
||||
None
|
||||
|
||||
## Examples
|
||||
|
||||
```groovy
|
||||
npmExecute script: this, dockerImage: 'node:8-stretch', npmCommand: 'run build'
|
||||
```
|
@ -2,18 +2,21 @@
|
||||
|
||||
## Description
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
## Parameters
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Step configuration
|
||||
|
||||
Content here is generated from corresponnding step, see `vars`.
|
||||
Content here is generated from corresponding step, see `vars`.
|
||||
|
||||
## Exceptions
|
||||
|
||||
If you see an error like `fatal: Not a git repository (or any parent up to mount point /home/jenkins)` it is likely that your test description cannot be found.<br />
|
||||
Please make sure to point parameter `testOptions` to your `conf.js` file like `testOptions: './path/to/my/tests/conf.js'`
|
||||
|
||||
## Examples
|
||||
|
@ -24,6 +24,7 @@ nav:
|
||||
- mtaBuild: steps/mtaBuild.md
|
||||
- neoDeploy: steps/neoDeploy.md
|
||||
- newmanExecute: steps/newmanExecute.md
|
||||
- npmExecute: steps/npmExecute.md
|
||||
- pipelineExecute: steps/pipelineExecute.md
|
||||
- pipelineRestartSteps: steps/pipelineRestartSteps.md
|
||||
- pipelineStashFiles: steps/pipelineStashFiles.md
|
||||
|
@ -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
|
||||
@ -252,6 +258,8 @@ steps:
|
||||
newmanRunCommand: "run '${config.newmanCollection}' --environment '${config.newmanEnvironment}' --globals '${config.newmanGlobals}' --reporters junit,html --reporter-junit-export 'target/newman/TEST-${collectionDisplayName}.xml' --reporter-html-export 'target/newman/TEST-${collectionDisplayName}.html'"
|
||||
stashContent:
|
||||
- 'tests'
|
||||
npmExecute:
|
||||
dockerImage: 'node:8-stretch'
|
||||
pipelineRestartSteps:
|
||||
sendMail: true
|
||||
timeoutInSeconds: 900
|
||||
@ -361,8 +369,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: {}
|
||||
|
@ -2,6 +2,7 @@ package com.sap.piper
|
||||
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
import com.sap.piper.analytics.Telemetry
|
||||
import groovy.text.SimpleTemplateEngine
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.MessageDigest
|
||||
@ -98,3 +99,10 @@ void pushToSWA(Map parameters, Map config) {
|
||||
// some error occured in telemetry reporting. This should not break anything though.
|
||||
}
|
||||
}
|
||||
|
||||
@NonCPS
|
||||
static String fillTemplate(String templateText, Map binding){
|
||||
def engine = new SimpleTemplateEngine()
|
||||
String result = engine.createTemplate(templateText).make(binding)
|
||||
return result
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
package com.sap.piper.cm;
|
||||
|
||||
public enum BackendType {
|
||||
SOLMAN, CTS, NONE
|
||||
SOLMAN, CTS, RFC, NONE
|
||||
}
|
||||
|
@ -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,
|
||||
|
122
src/com/sap/piper/testutils/JenkinsController.groovy
Normal file
122
src/com/sap/piper/testutils/JenkinsController.groovy
Normal file
@ -0,0 +1,122 @@
|
||||
package com.sap.piper.jenkins
|
||||
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
|
||||
class JenkinsController implements Serializable {
|
||||
def script
|
||||
String jenkinsUrl
|
||||
def timeout
|
||||
|
||||
JenkinsController(script, String jenkinsUrl = "http://localhost:8080", timeout = 3600) {
|
||||
this.script = script
|
||||
this.jenkinsUrl = jenkinsUrl
|
||||
this.timeout = timeout
|
||||
}
|
||||
|
||||
def waitForJenkinsStarted() {
|
||||
def timeout = 120
|
||||
def timePerLoop = 5
|
||||
|
||||
for (int i = 0; i < timeout; i += timePerLoop) {
|
||||
script.sleep timePerLoop
|
||||
try {
|
||||
if (retrieveJenkinsStatus() == 'NORMAL') {
|
||||
return true
|
||||
}
|
||||
} catch (Exception e) {
|
||||
script.echo "Could not retrieve status for Jenkins at ${jenkinsUrl}/api/json. Message: ${e.getMessage()}. Retrying..."
|
||||
e.printStackTrace()
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
script.error("Timeout: Jenkins did not start within the expected time frame.")
|
||||
}
|
||||
|
||||
private retrieveJenkinsStatus() {
|
||||
def apiUrl = "${jenkinsUrl}/api/json"
|
||||
script.echo "Checking Jenkins Status"
|
||||
def response = getTextFromUrl(apiUrl)
|
||||
def result = script.readJSON text: response
|
||||
return result.mode
|
||||
}
|
||||
|
||||
//Trigger scanning of the multi branch builds
|
||||
def buildJob(String jobName) {
|
||||
script.sh "curl -s -X POST ${jenkinsUrl}/job/${URLEncoder.encode(jobName, 'UTF-8')}/build"
|
||||
}
|
||||
|
||||
def waitForSuccess(String jobName, String branch) {
|
||||
if (this.waitForJobStatus(jobName, branch, 'SUCCESS')) {
|
||||
this.printConsoleText(jobName, branch)
|
||||
script.echo "Build was successful"
|
||||
} else {
|
||||
this.printConsoleText(jobName, branch)
|
||||
script.error("Build of ${jobName} ${branch} was not successfull")
|
||||
}
|
||||
}
|
||||
|
||||
def getBuildUrl(String jobName, String branch) {
|
||||
return "${jenkinsUrl}/job/${URLEncoder.encode(jobName, 'UTF-8')}/job/${URLEncoder.encode(branch, 'UTF-8')}/lastBuild/"
|
||||
}
|
||||
|
||||
def waitForJobStatus(String jobName, String branch, String status) {
|
||||
def buildUrl = getBuildUrl(jobName, branch)
|
||||
def timePerLoop = 10
|
||||
|
||||
for (int i = 0; i < timeout; i += timePerLoop) {
|
||||
script.sleep timePerLoop
|
||||
try {
|
||||
script.echo "Checking Build Status of ${jobName} ${branch}"
|
||||
def buildInformation = retrieveBuildInformation(jobName, branch)
|
||||
|
||||
if (buildInformation.building) {
|
||||
script.echo "Build is still in progress"
|
||||
continue
|
||||
}
|
||||
if (buildInformation.result == status) {
|
||||
return true
|
||||
}
|
||||
} catch (Exception e) {
|
||||
script.echo "Could not retrieve status for ${buildUrl}. Message: ${e.getMessage()}. Retrying..."
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
script.error("Timeout: Build of job ${jobName}, branch ${branch} did not finish in the expected time frame.")
|
||||
}
|
||||
|
||||
def getConsoleText(String jobName, String branch) {
|
||||
def consoleUrl = this.getBuildUrl(jobName, branch) + "/consoleText"
|
||||
return getTextFromUrl(consoleUrl)
|
||||
}
|
||||
|
||||
def printConsoleText(String jobName, String branch) {
|
||||
String consoleOutput = getConsoleText(jobName, branch)
|
||||
|
||||
script.echo '***********************************************'
|
||||
script.echo '** Begin Output of Example Application Build **'
|
||||
script.echo '***********************************************'
|
||||
|
||||
script.echo consoleOutput
|
||||
|
||||
script.echo '*********************************************'
|
||||
script.echo '** End Output of Example Application Build **'
|
||||
script.echo '*********************************************'
|
||||
}
|
||||
|
||||
def retrieveBuildInformation(String jobName, String branch) {
|
||||
def buildUrl = getBuildUrl(jobName, branch)
|
||||
def url = "${buildUrl}/api/json"
|
||||
script.echo "Checking Build Status of ${jobName} ${branch}"
|
||||
script.echo "${jenkinsUrl}/job/${URLEncoder.encode(jobName, 'UTF-8')}/job/${URLEncoder.encode(branch, 'UTF-8')}/"
|
||||
def response = getTextFromUrl(url)
|
||||
def result = script.readJSON text: response
|
||||
return result
|
||||
}
|
||||
|
||||
@NonCPS
|
||||
private static String getTextFromUrl(url) {
|
||||
return new URL(url).getText()
|
||||
}
|
||||
}
|
@ -9,25 +9,23 @@ class NeoCommandHelper {
|
||||
private Script step
|
||||
private DeployMode deployMode
|
||||
private Map deploymentConfiguration
|
||||
private String pathToNeoExecutable
|
||||
private String user
|
||||
private String password
|
||||
private String source
|
||||
|
||||
//Warning: Commands generated with this class can contain passwords and should only be used within the step withCredentials
|
||||
NeoCommandHelper(Script step, DeployMode deployMode, Map deploymentConfiguration, String pathToNeoExecutable,
|
||||
NeoCommandHelper(Script step, DeployMode deployMode, Map deploymentConfiguration,
|
||||
String user, String password, String source) {
|
||||
this.step = step
|
||||
this.deployMode = deployMode
|
||||
this.deploymentConfiguration = deploymentConfiguration
|
||||
this.pathToNeoExecutable = pathToNeoExecutable
|
||||
this.user = user
|
||||
this.password = password
|
||||
this.source = source
|
||||
}
|
||||
|
||||
private String prolog() {
|
||||
return "\"${pathToNeoExecutable}\""
|
||||
return 'neo.sh'
|
||||
}
|
||||
|
||||
String statusCommand() {
|
||||
|
@ -115,9 +115,11 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest {
|
||||
.commonPipelineEnvironment
|
||||
.configuration = [steps:
|
||||
[neoDeploy:
|
||||
[ host: 'hana.example.com',
|
||||
account: 'myTestAccount',
|
||||
]
|
||||
[neo:
|
||||
[ host: 'hana.example.com',
|
||||
account: 'myTestAccount',
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
@ -139,7 +141,7 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest {
|
||||
// the neo deploy call:
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher()
|
||||
.hasProlog("\"/opt/sap/neo/tools/neo.sh\" deploy-mta")
|
||||
.hasProlog("neo.sh deploy-mta")
|
||||
.hasSingleQuotedOption('host', 'hana\\.example\\.com')
|
||||
.hasSingleQuotedOption('account', 'myTestAccount')
|
||||
.hasSingleQuotedOption('password', 'terceSpot')
|
||||
|
@ -84,109 +84,10 @@ class NeoDeployTest extends BasePiperTest {
|
||||
helper.registerAllowedMethod('dockerExecute', [Map, Closure], null)
|
||||
helper.registerAllowedMethod('fileExists', [String], { s -> return new File(workspacePath, s).exists() })
|
||||
helper.registerAllowedMethod('pwd', [], { return workspacePath })
|
||||
mockShellCommands()
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [steps: [neoDeploy: [neo: [host: 'test.deploy.host.com', account: 'trialuser123']]]]
|
||||
}
|
||||
|
||||
@Test
|
||||
void straightForwardTestCompatibilityConfiguration(){
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, '.* status .*', 'Status: STARTED')
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [
|
||||
steps: [
|
||||
neoDeploy: [
|
||||
host: 'test.deploy.host.com',
|
||||
account: 'trialuser123',
|
||||
neoCredentialsId: 'myCredentialsId'
|
||||
]]]
|
||||
|
||||
stepRule.step.neoDeploy(script: nullScript,
|
||||
archivePath: warArchiveName,
|
||||
deployMode: 'warParams',
|
||||
applicationName: 'testApp',
|
||||
runtime: 'neo-javaee6-wp',
|
||||
runtimeVersion: '2.125',
|
||||
warAction: 'rolling-update',
|
||||
vmSize: 'lite')
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" rolling-update")
|
||||
.hasSingleQuotedOption('host', 'test\\.deploy\\.host\\.com')
|
||||
.hasSingleQuotedOption('account', 'trialuser123')
|
||||
.hasSingleQuotedOption('application', 'testApp')
|
||||
.hasSingleQuotedOption('runtime', 'neo-javaee6-wp')
|
||||
.hasSingleQuotedOption('runtime-version', '2\\.125')
|
||||
.hasSingleQuotedOption('size', 'lite')
|
||||
.hasSingleQuotedOption('user', 'anonymous')
|
||||
.hasSingleQuotedOption('password', '\\*\\*\\*\\*\\*\\*\\*\\*')
|
||||
.hasSingleQuotedOption('source', '.*\\.war'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void straightForwardTestConfigViaConfigProperties() {
|
||||
|
||||
boolean buildStatusHasBeenSet = false
|
||||
boolean notifyOldConfigFrameworkUsed = false
|
||||
|
||||
nullScript.commonPipelineEnvironment.setConfigProperty('DEPLOY_HOST', 'test.deploy.host.com')
|
||||
nullScript.commonPipelineEnvironment.setConfigProperty('CI_DEPLOY_ACCOUNT', 'trialuser123')
|
||||
nullScript.commonPipelineEnvironment.configuration = [:]
|
||||
|
||||
nullScript.currentBuild = [setResult: { buildStatusHasBeenSet = true }]
|
||||
|
||||
def utils = new Utils() {
|
||||
void pushToSWA(Map parameters, Map config) {
|
||||
notifyOldConfigFrameworkUsed = parameters.stepParam4
|
||||
}
|
||||
}
|
||||
|
||||
stepRule.step.neoDeploy(script: nullScript,
|
||||
source: archiveName,
|
||||
neo: [credentialsId: 'myCredentialsId'],
|
||||
utils: utils
|
||||
)
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy-mta")
|
||||
.hasSingleQuotedOption('host', 'test\\.deploy\\.host\\.com')
|
||||
.hasSingleQuotedOption('account', 'trialuser123')
|
||||
.hasOption('synchronous', '')
|
||||
.hasSingleQuotedOption('user', 'anonymous')
|
||||
.hasSingleQuotedOption('password', '\\*\\*\\*\\*\\*\\*\\*\\*')
|
||||
.hasSingleQuotedOption('source', '.*'))
|
||||
|
||||
assert !buildStatusHasBeenSet
|
||||
assert notifyOldConfigFrameworkUsed
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConfigViaConfigPropertiesSetsBuildToUnstable() {
|
||||
|
||||
def buildStatus = 'SUCCESS'
|
||||
|
||||
nullScript.commonPipelineEnvironment.setConfigProperty('DEPLOY_HOST', 'test.deploy.host.com')
|
||||
nullScript.commonPipelineEnvironment.setConfigProperty('CI_DEPLOY_ACCOUNT', 'trialuser123')
|
||||
nullScript.commonPipelineEnvironment.configuration = [:]
|
||||
|
||||
nullScript.currentBuild = [setResult: { r -> buildStatus = r }]
|
||||
|
||||
System.setProperty('com.sap.piper.featureFlag.buildUnstableWhenOldConfigFrameworkIsUsedByNeoDeploy',
|
||||
Boolean.TRUE.toString())
|
||||
|
||||
try {
|
||||
stepRule.step.neoDeploy(script: nullScript,
|
||||
source: archiveName,
|
||||
neo:[credentialsId: 'myCredentialsId'],
|
||||
utils: utils
|
||||
)
|
||||
} finally {
|
||||
System.clearProperty('com.sap.piper.featureFlag.buildUnstableWhenOldConfigFrameworkIsUsedByNeoDeploy')
|
||||
}
|
||||
|
||||
assert buildStatus == 'UNSTABLE'
|
||||
}
|
||||
|
||||
@Test
|
||||
void straightForwardTestConfigViaConfiguration() {
|
||||
|
||||
@ -205,7 +106,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
)
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy-mta")
|
||||
new CommandLineMatcher().hasProlog("neo.sh deploy-mta")
|
||||
.hasSingleQuotedOption('host', 'test\\.deploy\\.host\\.com')
|
||||
.hasSingleQuotedOption('account', 'trialuser123')
|
||||
.hasOption('synchronous', '')
|
||||
@ -231,7 +132,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
)
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy-mta")
|
||||
new CommandLineMatcher().hasProlog("neo.sh deploy-mta")
|
||||
.hasSingleQuotedOption('host', 'configuration-frwk\\.deploy\\.host\\.com')
|
||||
.hasSingleQuotedOption('account', 'configurationFrwkUser123')
|
||||
.hasOption('synchronous', '')
|
||||
@ -246,7 +147,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
stepRule.step.neoDeploy(script: nullScript)
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy-mta")
|
||||
new CommandLineMatcher().hasProlog("neo.sh deploy-mta")
|
||||
.hasSingleQuotedOption('source', 'archive.mtar'))
|
||||
}
|
||||
|
||||
@ -257,7 +158,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
source: "archive.mtar")
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy-mta")
|
||||
new CommandLineMatcher().hasProlog("neo.sh deploy-mta")
|
||||
.hasSingleQuotedOption('source', 'archive.mtar'))
|
||||
}
|
||||
|
||||
@ -282,7 +183,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
)
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy-mta")
|
||||
new CommandLineMatcher().hasProlog("neo.sh deploy-mta")
|
||||
.hasSingleQuotedOption('host', 'test\\.deploy\\.host\\.com')
|
||||
.hasSingleQuotedOption('account', 'trialuser123')
|
||||
.hasOption('synchronous', '')
|
||||
@ -292,69 +193,6 @@ class NeoDeployTest extends BasePiperTest {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void neoHomeNotSetTest() {
|
||||
|
||||
mockHomeVariablesNotSet()
|
||||
|
||||
stepRule.step.neoDeploy(script: nullScript,
|
||||
source: archiveName
|
||||
)
|
||||
|
||||
assert shellRule.shell.find { c -> c.contains('"neo.sh" deploy-mta') }
|
||||
assert loggingRule.log.contains('SAP Cloud Platform Console Client is on PATH.')
|
||||
assert loggingRule.log.contains("Using SAP Cloud Platform Console Client 'neo.sh'.")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void neoHomeAsParameterTest() {
|
||||
|
||||
mockHomeVariablesNotSet()
|
||||
|
||||
stepRule.step.neoDeploy(script: nullScript,
|
||||
source: archiveName,
|
||||
neo:[credentialsId: 'myCredentialsId'],
|
||||
neoHome: '/param/neo'
|
||||
)
|
||||
|
||||
assert shellRule.shell.find { c -> c = "\"/param/neo/tools/neo.sh\" deploy-mta" }
|
||||
assert loggingRule.log.contains("SAP Cloud Platform Console Client home '/param/neo' retrieved from configuration.")
|
||||
assert loggingRule.log.contains("Using SAP Cloud Platform Console Client '/param/neo/tools/neo.sh'.")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void neoHomeFromEnvironmentTest() {
|
||||
|
||||
stepRule.step.neoDeploy(script: nullScript,
|
||||
source: archiveName
|
||||
)
|
||||
|
||||
assert shellRule.shell.find { c -> c.contains("\"/opt/neo/tools/neo.sh\" deploy-mta") }
|
||||
assert loggingRule.log.contains("SAP Cloud Platform Console Client home '/opt/neo' retrieved from environment.")
|
||||
assert loggingRule.log.contains("Using SAP Cloud Platform Console Client '/opt/neo/tools/neo.sh'.")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void neoHomeFromCustomStepConfigurationTest() {
|
||||
|
||||
mockHomeVariablesNotSet()
|
||||
|
||||
nullScript.commonPipelineEnvironment.configuration = [steps: [neoDeploy: [neo: [host: 'test.deploy.host.com', account: 'trialuser123'], neoHome: '/config/neo']]]
|
||||
|
||||
stepRule.step.neoDeploy(script: nullScript,
|
||||
source: archiveName
|
||||
)
|
||||
|
||||
assert shellRule.shell.find { c -> c = "\"/config/neo/tools/neo.sh\" deploy-mta" }
|
||||
assert loggingRule.log.contains("SAP Cloud Platform Console Client home '/config/neo' retrieved from configuration.")
|
||||
assert loggingRule.log.contains("Using SAP Cloud Platform Console Client '/config/neo/tools/neo.sh'.")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void archiveNotProvidedTest() {
|
||||
|
||||
@ -392,7 +230,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
stepRule.step.neoDeploy(script: nullScript, source: archiveName, deployMode: 'mta')
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy-mta")
|
||||
new CommandLineMatcher().hasProlog("neo.sh deploy-mta")
|
||||
.hasSingleQuotedOption('host', 'test\\.deploy\\.host\\.com')
|
||||
.hasSingleQuotedOption('account', 'trialuser123')
|
||||
.hasOption('synchronous', '')
|
||||
@ -417,7 +255,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
source: warArchiveName)
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy")
|
||||
new CommandLineMatcher().hasProlog("neo.sh deploy")
|
||||
.hasSingleQuotedOption('host', 'test\\.deploy\\.host\\.com')
|
||||
.hasSingleQuotedOption('account', 'trialuser123')
|
||||
.hasSingleQuotedOption('application', 'testApp')
|
||||
@ -448,7 +286,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
)
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" rolling-update")
|
||||
new CommandLineMatcher().hasProlog("neo.sh rolling-update")
|
||||
.hasSingleQuotedOption('host', 'test\\.deploy\\.host\\.com')
|
||||
.hasSingleQuotedOption('account', 'trialuser123')
|
||||
.hasSingleQuotedOption('application', 'testApp')
|
||||
@ -478,7 +316,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher()
|
||||
.hasProlog("\"/opt/neo/tools/neo.sh\" deploy")
|
||||
.hasProlog("neo.sh deploy")
|
||||
.hasSingleQuotedOption('application', 'testApp'))
|
||||
}
|
||||
|
||||
@ -541,7 +379,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
)
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy")
|
||||
new CommandLineMatcher().hasProlog("neo.sh deploy")
|
||||
.hasArgument("config.properties")
|
||||
.hasSingleQuotedOption('user', 'defaultUser')
|
||||
.hasSingleQuotedOption('password', '\\*\\*\\*\\*\\*\\*\\*\\*')
|
||||
@ -566,7 +404,7 @@ class NeoDeployTest extends BasePiperTest {
|
||||
])
|
||||
|
||||
Assert.assertThat(shellRule.shell,
|
||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" rolling-update")
|
||||
new CommandLineMatcher().hasProlog("neo.sh rolling-update")
|
||||
.hasArgument('config.properties')
|
||||
.hasSingleQuotedOption('user', 'defaultUser')
|
||||
.hasSingleQuotedOption('password', '\\*\\*\\*\\*\\*\\*\\*\\*')
|
||||
@ -654,57 +492,4 @@ class NeoDeployTest extends BasePiperTest {
|
||||
size: 'lite'
|
||||
])
|
||||
}
|
||||
|
||||
@Test
|
||||
void deployHostProvidedAsDeprecatedParameterTest() {
|
||||
|
||||
nullScript.commonPipelineEnvironment.setConfigProperty('CI_DEPLOY_ACCOUNT', 'configPropsUser123')
|
||||
|
||||
stepRule.step.neoDeploy(script: nullScript,
|
||||
source: archiveName,
|
||||
deployHost: "my.deploy.host.com"
|
||||
)
|
||||
|
||||
assert loggingRule.log.contains("[WARNING][neoDeploy] Deprecated parameter 'deployHost' is used. This will not work anymore in future versions. Use parameter 'host' instead.")
|
||||
}
|
||||
|
||||
@Test
|
||||
void deployAccountProvidedAsDeprecatedParameterTest() {
|
||||
|
||||
nullScript.commonPipelineEnvironment.setConfigProperty('CI_DEPLOY_ACCOUNT', 'configPropsUser123')
|
||||
|
||||
stepRule.step.neoDeploy(script: nullScript,
|
||||
source: archiveName,
|
||||
neo: [
|
||||
host: "my.deploy.host.com",
|
||||
],
|
||||
deployAccount: "myAccount"
|
||||
)
|
||||
|
||||
assert loggingRule.log.contains("Deprecated parameter 'deployAccount' is used. This will not work anymore in future versions. Use parameter 'account' instead.")
|
||||
}
|
||||
|
||||
private mockShellCommands() {
|
||||
String javaVersion = '''openjdk version \"1.8.0_121\"
|
||||
OpenJDK Runtime Environment (build 1.8.0_121-8u121-b13-1~bpo8+1-b13)
|
||||
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)'''
|
||||
shellRule.setReturnValue(Type.REGEX, '.*java -version.*', javaVersion)
|
||||
|
||||
String neoVersion = '''SAP Cloud Platform Console Client
|
||||
SDK version : 3.39.10
|
||||
Runtime : neo-java-web'''
|
||||
shellRule.setReturnValue(Type.REGEX, '.*neo.sh version.*', neoVersion)
|
||||
|
||||
shellRule.setReturnValue(Type.REGEX, '.*JAVA_HOME.*', '/opt/java')
|
||||
shellRule.setReturnValue(Type.REGEX, '.*NEO_HOME.*', '/opt/neo')
|
||||
shellRule.setReturnValue(Type.REGEX, '.*which java.*', 0)
|
||||
shellRule.setReturnValue(Type.REGEX, '.*which neo.*', 0)
|
||||
}
|
||||
|
||||
private mockHomeVariablesNotSet() {
|
||||
shellRule.setReturnValue(Type.REGEX, '.*JAVA_HOME.*', '')
|
||||
shellRule.setReturnValue(Type.REGEX, '.*NEO_HOME.*', '')
|
||||
shellRule.setReturnValue(Type.REGEX, '.*which java.*', 0)
|
||||
shellRule.setReturnValue(Type.REGEX, '.*which neo.*', 0)
|
||||
}
|
||||
}
|
||||
|
56
test/groovy/NpmExecuteTest.groovy
Normal file
56
test/groovy/NpmExecuteTest.groovy
Normal file
@ -0,0 +1,56 @@
|
||||
import static org.junit.Assert.assertEquals
|
||||
import hudson.AbortException
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
import org.junit.rules.RuleChain
|
||||
import util.BasePiperTest
|
||||
import util.JenkinsDockerExecuteRule
|
||||
import util.JenkinsReadYamlRule
|
||||
import util.JenkinsShellCallRule
|
||||
import util.JenkinsStepRule
|
||||
import util.Rules
|
||||
|
||||
class NpmExecuteTest extends BasePiperTest {
|
||||
|
||||
private ExpectedException thrown = new ExpectedException().none()
|
||||
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
|
||||
private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this)
|
||||
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
|
||||
private JenkinsReadYamlRule yamlRule = new JenkinsReadYamlRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain ruleChain = Rules
|
||||
.getCommonRules(this)
|
||||
.around(thrown)
|
||||
.around(yamlRule)
|
||||
.around(dockerExecuteRule)
|
||||
.around(shellRule)
|
||||
.around(stepRule)
|
||||
|
||||
@Before
|
||||
void init() {
|
||||
helper.registerAllowedMethod 'fileExists', [String], { s -> s == 'package.json' }
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNpmExecute() {
|
||||
stepRule.step.npmExecute(script: nullScript, dockerImage: 'node:8-stretch')
|
||||
assertEquals 'node:8-stretch', dockerExecuteRule.dockerParams.dockerImage
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNpmExecuteWithClosure() {
|
||||
stepRule.step.npmExecute(script: nullScript, dockerImage: 'node:8-stretch', npmCommand: 'run build') { }
|
||||
assert shellRule.shell.find { c -> c.contains('npm run build') }
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoPackageJson() {
|
||||
helper.registerAllowedMethod 'fileExists', [String], { false }
|
||||
thrown.expect AbortException
|
||||
thrown.expectMessage '[npmExecute] package.json is not found.'
|
||||
stepRule.step.npmExecute(script: nullScript, dockerImage: 'node:8-stretch', npmCommand: 'run build')
|
||||
}
|
||||
}
|
@ -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() {
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -34,7 +34,6 @@ class NeoCommandHelperTest extends BasePiperTest {
|
||||
String source = (deployMode == DeployMode.MTA) ? 'file.mta' : 'file.war'
|
||||
String username = 'username'
|
||||
String password = 'password'
|
||||
String neoExecutable = '/path/tools/neo.sh';
|
||||
|
||||
nullScript.STEP_NAME="neoDeploy"
|
||||
|
||||
@ -42,7 +41,6 @@ class NeoCommandHelperTest extends BasePiperTest {
|
||||
nullScript,
|
||||
deployMode,
|
||||
deploymentConfiguration,
|
||||
neoExecutable,
|
||||
username,
|
||||
password,
|
||||
source
|
||||
@ -52,7 +50,7 @@ class NeoCommandHelperTest extends BasePiperTest {
|
||||
@Test
|
||||
void testStatusCommand() {
|
||||
String actual = getTestFixture(DeployMode.WAR_PARAMS).statusCommand()
|
||||
String expected = "\"/path/tools/neo.sh\" status --host 'host_value' --account 'account_value' " +
|
||||
String expected = "neo.sh status --host 'host_value' --account 'account_value' " +
|
||||
"--application 'application_value' --user 'username' --password 'password'"
|
||||
Assert.assertEquals(expected, actual)
|
||||
}
|
||||
@ -60,14 +58,14 @@ class NeoCommandHelperTest extends BasePiperTest {
|
||||
@Test
|
||||
void testStatusCommandForProperties() {
|
||||
String actual = getTestFixture(DeployMode.WAR_PROPERTIES_FILE).statusCommand()
|
||||
String expected = "\"/path/tools/neo.sh\" status file.properties --user 'username' --password 'password'"
|
||||
String expected = "neo.sh status file.properties --user 'username' --password 'password'"
|
||||
Assert.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRollingUpdateCommand() {
|
||||
String actual = getTestFixture(DeployMode.WAR_PARAMS).rollingUpdateCommand()
|
||||
String basicCommand = "\"/path/tools/neo.sh\" rolling-update --host 'host_value' --account 'account_value' " +
|
||||
String basicCommand = "neo.sh rolling-update --host 'host_value' --account 'account_value' " +
|
||||
"--application 'application_value' --user 'username' --password 'password' --source 'file.war'"
|
||||
|
||||
Assert.assertTrue(actual.contains(basicCommand))
|
||||
@ -81,14 +79,14 @@ class NeoCommandHelperTest extends BasePiperTest {
|
||||
@Test
|
||||
void testRollingUpdateCommandForProperties() {
|
||||
String actual = getTestFixture(DeployMode.WAR_PROPERTIES_FILE).rollingUpdateCommand()
|
||||
String expected = "\"/path/tools/neo.sh\" rolling-update file.properties --user 'username' --password 'password' --source 'file.war' "
|
||||
String expected = "neo.sh rolling-update file.properties --user 'username' --password 'password' --source 'file.war' "
|
||||
Assert.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeployCommand() {
|
||||
String actual = getTestFixture(DeployMode.WAR_PARAMS).deployCommand()
|
||||
String basicCommand = "\"/path/tools/neo.sh\" deploy --host 'host_value' --account 'account_value' " +
|
||||
String basicCommand = "neo.sh deploy --host 'host_value' --account 'account_value' " +
|
||||
"--application 'application_value' --user 'username' --password 'password' --source 'file.war'"
|
||||
|
||||
Assert.assertTrue(actual.contains(basicCommand))
|
||||
@ -102,14 +100,14 @@ class NeoCommandHelperTest extends BasePiperTest {
|
||||
@Test
|
||||
void testDeployCommandForProperties() {
|
||||
String actual = getTestFixture(DeployMode.WAR_PROPERTIES_FILE).deployCommand()
|
||||
String expected = "\"/path/tools/neo.sh\" deploy file.properties --user 'username' --password 'password' --source 'file.war' "
|
||||
String expected = "neo.sh deploy file.properties --user 'username' --password 'password' --source 'file.war' "
|
||||
Assert.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRestartCommand() {
|
||||
String actual = getTestFixture(DeployMode.WAR_PARAMS).restartCommand()
|
||||
String expected = "\"/path/tools/neo.sh\" restart --synchronous --host 'host_value' --account 'account_value' " +
|
||||
String expected = "neo.sh restart --synchronous --host 'host_value' --account 'account_value' " +
|
||||
"--application 'application_value' --user 'username' --password 'password'"
|
||||
Assert.assertEquals(expected, actual)
|
||||
}
|
||||
@ -117,14 +115,14 @@ class NeoCommandHelperTest extends BasePiperTest {
|
||||
@Test
|
||||
void testRestartCommandForProperties() {
|
||||
String actual = getTestFixture(DeployMode.WAR_PROPERTIES_FILE).restartCommand()
|
||||
String expected = "\"/path/tools/neo.sh\" restart --synchronous file.properties --user 'username' --password 'password'"
|
||||
String expected = "neo.sh restart --synchronous file.properties --user 'username' --password 'password'"
|
||||
Assert.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
void deployMta() {
|
||||
String actual = getTestFixture(DeployMode.MTA).deployMta()
|
||||
String expected = "\"/path/tools/neo.sh\" deploy-mta --synchronous --host 'host_value' --account 'account_value' " +
|
||||
String expected = "neo.sh deploy-mta --synchronous --host 'host_value' --account 'account_value' " +
|
||||
"--user 'username' --password 'password' --source 'file.mta'"
|
||||
Assert.assertEquals(expected, actual)
|
||||
}
|
||||
|
@ -35,7 +35,10 @@ void call(Map parameters = [:]) {
|
||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS)
|
||||
.mixin([
|
||||
artifactVersion: script.commonPipelineEnvironment.getArtifactVersion()
|
||||
artifactVersion: script.commonPipelineEnvironment.getArtifactVersion(),
|
||||
influxPrefix: script.commonPipelineEnvironment.getGithubOrg() && script.commonPipelineEnvironment.getGithubRepo()
|
||||
? "${script.commonPipelineEnvironment.getGithubOrg()}_${script.commonPipelineEnvironment.getGithubRepo()}"
|
||||
: null
|
||||
])
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.addIfNull('customData', script.commonPipelineEnvironment.getInfluxCustomData())
|
||||
|
@ -1,6 +1,7 @@
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.GenerateDocumentation
|
||||
import com.sap.piper.GitUtils
|
||||
import com.sap.piper.Utils
|
||||
|
||||
@ -9,34 +10,67 @@ import groovy.transform.Field
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
@Field Set GENERAL_CONFIG_KEYS = [
|
||||
/** port mappings required for containers. This will only take effect inside a Kubernetes pod, format [[containerPort: 1111, hostPort: 1111]] */
|
||||
/**
|
||||
* Map which defines per docker image the port mappings, e.g. `containerPortMappings: ['selenium/standalone-chrome': [[name: 'selPort', containerPort: 4444, hostPort: 4444]]]`.
|
||||
*/
|
||||
'containerPortMappings',
|
||||
/** envVars to be set in the execution container if required */
|
||||
/** A map of environment variables to set in the container, e.g. [http_proxy:'proxy:8080']. */
|
||||
'dockerEnvVars',
|
||||
/** Docker image for code execution */
|
||||
/** The name of the docker image that should be used. If empty, Docker is not used and the command is executed directly on the Jenkins system. */
|
||||
'dockerImage',
|
||||
/** name of the Docker container. If not on Kubernetes pod, this will define the network-alias to the NPM container and is thus required for accessing the server, example http://karma:9876 (default). */
|
||||
/**
|
||||
* Kubernetes only:
|
||||
* Name of the container launching `dockerImage`.
|
||||
* SideCar only:
|
||||
* Name of the container in local network.
|
||||
*/
|
||||
'dockerName',
|
||||
/** user home directory for Docker execution. This will only take effect inside a Kubernetes pod. */
|
||||
/**
|
||||
* Kubernetes only:
|
||||
* Specifies a dedicated user home directory for the container which will be passed as value for environment variable `HOME`.
|
||||
*/
|
||||
'dockerWorkspace',
|
||||
/**
|
||||
* With `failOnError` the behavior in case tests fail can be defined.
|
||||
* @possibleValues `true`, `false`
|
||||
*/
|
||||
'failOnError',
|
||||
/** The command that is executed to install the test tool. */
|
||||
'installCommand',
|
||||
/** Define the paths of the modules to execute tests on. */
|
||||
'modules',
|
||||
/** The command that is executed to start the tests. */
|
||||
'runCommand',
|
||||
/** envVars to be set in Selenium container if required */
|
||||
/** A map of environment variables to set in the sidecar container, similar to `dockerEnvVars`. */
|
||||
'sidecarEnvVars',
|
||||
/** image for Selenium execution which runs as sidecar to dockerImage */
|
||||
/** The name of the docker image of the sidecar container. If empty, no sidecar container is started. */
|
||||
'sidecarImage',
|
||||
/** name of the Selenium container. If not on Kubernetes pod, this will define the network-alias to the Selenium container and is thus required for accessing the server, example http://selenium:4444 (default) */
|
||||
/**
|
||||
* as `dockerName` for the sidecar container
|
||||
*/
|
||||
'sidecarName',
|
||||
/** volume bind. This will not take effect in Kubernetes pod. */
|
||||
/** Volumes that should be mounted into the sidecar container. */
|
||||
'sidecarVolumeBind',
|
||||
/** list of stash names which are required to be unstashed before test run */
|
||||
/** If specific stashes should be considered for the tests, their names need to be passed via the parameter `stashContent`. */
|
||||
'stashContent'
|
||||
]
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
/**
|
||||
* In this step the ([Karma test runner](http://karma-runner.github.io)) is executed.
|
||||
*
|
||||
* The step is using the `seleniumExecuteTest` step to spin up two containers in a Docker network:
|
||||
*
|
||||
* * a Selenium/Chrome container (`selenium/standalone-chrome`)
|
||||
* * a NodeJS container (`node:8-stretch`)
|
||||
*
|
||||
* In the Docker network, the containers can be referenced by the values provided in `dockerName` and `sidecarName`, the default values are `karma` and `selenium`. These values must be used in the `hostname` properties of the test configuration ([Karma](https://karma-runner.github.io/1.0/config/configuration-file.html) and [WebDriver](https://github.com/karma-runner/karma-webdriver-launcher#usage)).
|
||||
*
|
||||
* !!! note
|
||||
* In a Kubernetes environment, the containers both need to be referenced with `localhost`.
|
||||
*/
|
||||
@GenerateDocumentation
|
||||
void call(Map parameters = [:]) {
|
||||
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
||||
final script = checkScript(this, parameters) ?: this
|
||||
|
@ -1,6 +1,5 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import com.sap.piper.tools.ToolDescriptor
|
||||
import com.sap.piper.tools.neo.DeployMode
|
||||
import com.sap.piper.tools.neo.NeoCommandHelper
|
||||
import com.sap.piper.tools.neo.WarAction
|
||||
@ -25,21 +24,6 @@ import static com.sap.piper.Prerequisites.checkScript
|
||||
'warAction'
|
||||
])
|
||||
|
||||
@Field Map CONFIG_KEY_COMPATIBILITY = [
|
||||
neo : [
|
||||
host : 'host',
|
||||
account : 'account',
|
||||
application : 'applicationName',
|
||||
credentialsId : 'neoCredentialsId',
|
||||
propertiesFile: 'propertiesFile',
|
||||
runtime : 'runtime',
|
||||
runtimeVersion: 'runtimeVersion',
|
||||
size : 'vmSize'
|
||||
|
||||
],
|
||||
source: 'archivePath'
|
||||
]
|
||||
|
||||
void call(parameters = [:]) {
|
||||
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
||||
|
||||
@ -49,19 +33,17 @@ void call(parameters = [:]) {
|
||||
|
||||
prepareDefaultValues script: script
|
||||
|
||||
Map stepCompatibilityConfiguration = handleCompatibility(script, parameters)
|
||||
|
||||
// load default & individual configuration
|
||||
Map configuration = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixin(stepCompatibilityConfiguration)
|
||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS)
|
||||
.addIfEmpty('source', script.commonPipelineEnvironment.getMtarFilePath())
|
||||
.mixin(parameters, PARAMETER_KEYS, CONFIG_KEY_COMPATIBILITY)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.withMandatoryProperty('neo')
|
||||
.withMandatoryProperty('source')
|
||||
.withMandatoryProperty('neo/credentialsId')
|
||||
.withPropertyInValues('deployMode', DeployMode.stringValues())
|
||||
.use()
|
||||
|
||||
@ -73,52 +55,37 @@ void call(parameters = [:]) {
|
||||
stepParam2: configuration.warAction == 'rolling-update'?'blue-green':'standard', // ['deploy', 'deploy-mta', 'rolling-update']
|
||||
stepParamKey3: 'scriptMissing',
|
||||
stepParam3: parameters?.script == null,
|
||||
stepParamKey4: 'legacyConfig',
|
||||
stepParam4: !stepCompatibilityConfiguration.isEmpty(),
|
||||
], configuration)
|
||||
|
||||
ToolDescriptor neo = new ToolDescriptor('SAP Cloud Platform Console Client', 'NEO_HOME', 'neoHome', '/tools/', 'neo.sh', null, 'version')
|
||||
ToolDescriptor java = new ToolDescriptor('Java', 'JAVA_HOME', '', '/bin/', 'java', '1.8.0', '-version 2>&1')
|
||||
|
||||
if (configuration.neo.credentialsId) {
|
||||
withCredentials([usernamePassword(
|
||||
credentialsId: configuration.neo.credentialsId,
|
||||
passwordVariable: 'NEO_PASSWORD',
|
||||
usernameVariable: 'NEO_USERNAME')]) {
|
||||
withCredentials([usernamePassword(
|
||||
credentialsId: configuration.neo.credentialsId,
|
||||
passwordVariable: 'NEO_PASSWORD',
|
||||
usernameVariable: 'NEO_USERNAME')]) {
|
||||
|
||||
assertPasswordRules(NEO_PASSWORD)
|
||||
assertPasswordRules(NEO_PASSWORD)
|
||||
|
||||
dockerExecute(
|
||||
script: script,
|
||||
dockerImage: configuration.dockerImage,
|
||||
dockerEnvVars: configuration.dockerEnvVars,
|
||||
dockerOptions: configuration.dockerOptions
|
||||
) {
|
||||
dockerExecute(
|
||||
script: script,
|
||||
dockerImage: configuration.dockerImage,
|
||||
dockerEnvVars: configuration.dockerEnvVars,
|
||||
dockerOptions: configuration.dockerOptions
|
||||
) {
|
||||
DeployMode deployMode = DeployMode.fromString(configuration.deployMode)
|
||||
|
||||
neo.verify(this, configuration)
|
||||
java.verify(this, configuration)
|
||||
NeoCommandHelper neoCommandHelper = new NeoCommandHelper(
|
||||
this,
|
||||
deployMode,
|
||||
configuration.neo,
|
||||
NEO_USERNAME,
|
||||
NEO_PASSWORD,
|
||||
configuration.source
|
||||
)
|
||||
|
||||
String neoExecutable = neo.getToolExecutable(script, configuration)
|
||||
|
||||
DeployMode deployMode = DeployMode.fromString(configuration.deployMode)
|
||||
|
||||
NeoCommandHelper neoCommandHelper = new NeoCommandHelper(
|
||||
this,
|
||||
deployMode,
|
||||
configuration.neo,
|
||||
neoExecutable,
|
||||
NEO_USERNAME,
|
||||
NEO_PASSWORD,
|
||||
configuration.source
|
||||
)
|
||||
|
||||
lock("$STEP_NAME :${neoCommandHelper.resourceLock()}") {
|
||||
deploy(script, utils, configuration, neoCommandHelper, configuration.dockerImage, deployMode)
|
||||
}
|
||||
lock("$STEP_NAME :${neoCommandHelper.resourceLock()}") {
|
||||
deploy(script, utils, configuration, neoCommandHelper, configuration.dockerImage, deployMode)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error("[neoDeploy] No credentials defined for the deployment. Please specify the value for credentialsId for neo.")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,61 +135,6 @@ private boolean isAppRunning(NeoCommandHelper commandHelper) {
|
||||
return status.contains('Status: STARTED')
|
||||
}
|
||||
|
||||
private handleCompatibility(script, parameters) {
|
||||
final Map neoCompatibilityConfiguration = [:]
|
||||
|
||||
// Backward compatibility: ensure old configuration is taken into account
|
||||
// The old configuration in not stage / step specific
|
||||
|
||||
def defaultDeployHost = script.commonPipelineEnvironment.getConfigProperty('DEPLOY_HOST')
|
||||
if (defaultDeployHost) {
|
||||
echo "[WARNING][${STEP_NAME}] A deprecated configuration framework is used for configuring parameter 'DEPLOY_HOST'. This configuration framework will be removed in future versions."
|
||||
neoCompatibilityConfiguration.put('host', defaultDeployHost)
|
||||
}
|
||||
|
||||
def defaultDeployAccount = script.commonPipelineEnvironment.getConfigProperty('CI_DEPLOY_ACCOUNT')
|
||||
if (defaultDeployAccount) {
|
||||
echo "[WARNING][${STEP_NAME}] A deprecated configuration framework is used for configuring parameter 'DEPLOY_ACCOUNT'. This configuration framekwork will be removed in future versions."
|
||||
neoCompatibilityConfiguration.put('account', defaultDeployAccount)
|
||||
}
|
||||
|
||||
if (parameters.deployHost && !parameters.host) {
|
||||
echo "[WARNING][${STEP_NAME}] Deprecated parameter 'deployHost' is used. This will not work anymore in future versions. Use parameter 'host' instead."
|
||||
parameters.put('host', parameters.deployHost)
|
||||
}
|
||||
|
||||
if (parameters.deployAccount && !parameters.account) {
|
||||
echo "[WARNING][${STEP_NAME}] Deprecated parameter 'deployAccount' is used. This will not work anymore in future versions. Use parameter 'account' instead."
|
||||
parameters.put('account', parameters.deployAccount)
|
||||
}
|
||||
|
||||
def credId = script.commonPipelineEnvironment.getConfigProperty('neoCredentialsId')
|
||||
if (credId && !parameters.neoCredentialsId) {
|
||||
echo "[WARNING][${STEP_NAME}] Deprecated parameter 'neoCredentialsId' from old configuration framework is used. This will not work anymore in future versions."
|
||||
parameters.put('neoCredentialsId', credId)
|
||||
}
|
||||
|
||||
if (!neoCompatibilityConfiguration.isEmpty()) {
|
||||
echo "[WARNING][$STEP_NAME] You are using a deprecated configuration framework. This will be removed in " +
|
||||
'futureVersions.\nAdd snippet below to \'./pipeline/config.yml\' and remove ' +
|
||||
'file \'.pipeline/configuration.properties\'.\n' +
|
||||
"""|steps:
|
||||
| neoDeploy:
|
||||
| neo:
|
||||
| host: ${neoCompatibilityConfiguration.get('host', '<Add host here>')}
|
||||
| account: ${neoCompatibilityConfiguration.get('account', '<Add account here>')}
|
||||
""".stripMargin()
|
||||
|
||||
if (Boolean.getBoolean('com.sap.piper.featureFlag.buildUnstableWhenOldConfigFrameworkIsUsedByNeoDeploy')) {
|
||||
script.currentBuild.setResult('UNSTABLE')
|
||||
echo "[WARNING][$STEP_NAME] Build has been set to unstable since old config framework is used."
|
||||
}
|
||||
return [neo: neoCompatibilityConfiguration]
|
||||
}
|
||||
|
||||
return [:]
|
||||
}
|
||||
|
||||
private assertPasswordRules(String password) {
|
||||
if (password.startsWith("@")) {
|
||||
error("Your password for the deployment to SAP Cloud Platform contains characters which are not " +
|
||||
|
73
vars/npmExecute.groovy
Normal file
73
vars/npmExecute.groovy
Normal file
@ -0,0 +1,73 @@
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
import com.sap.piper.GenerateDocumentation
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.Utils
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field def STEP_NAME = getClass().getName()
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = [
|
||||
/**
|
||||
* Name of the docker image that should be used, in which node should be installed and configured. Default value is 'node:8-stretch'.
|
||||
*/
|
||||
'dockerImage',
|
||||
/**
|
||||
* URL of default NPM registry
|
||||
*/
|
||||
'defaultNpmRegistry',
|
||||
/**
|
||||
* Which NPM command should be executed.
|
||||
*/
|
||||
'npmCommand']
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS + [
|
||||
/**
|
||||
* Docker options to be set when starting the container.
|
||||
*/
|
||||
'dockerOptions']
|
||||
/**
|
||||
* Executes NPM commands inside a docker container.
|
||||
* Docker image, docker options and npm commands can be specified or configured.
|
||||
*/
|
||||
@GenerateDocumentation
|
||||
void call(Map parameters = [:], body = null) {
|
||||
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
||||
|
||||
final script = checkScript(this, parameters) ?: this
|
||||
|
||||
// load default & individual configuration
|
||||
Map configuration = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
|
||||
new Utils().pushToSWA([
|
||||
step: STEP_NAME,
|
||||
stepParamKey1: 'scriptMissing',
|
||||
stepParam1: parameters?.script == null
|
||||
], configuration)
|
||||
|
||||
try {
|
||||
if (!fileExists('package.json')) {
|
||||
error "[${STEP_NAME}] package.json is not found."
|
||||
}
|
||||
dockerExecute(script: script, dockerImage: configuration.dockerImage, dockerOptions: configuration.dockerOptions) {
|
||||
if (configuration.defaultNpmRegistry) {
|
||||
sh "npm config set registry ${configuration.defaultNpmRegistry}"
|
||||
}
|
||||
if (configuration.npmCommand) {
|
||||
sh "npm ${configuration.npmCommand}"
|
||||
}
|
||||
if (body) {
|
||||
body()
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
println "Error while executing npm. Here are the logs:"
|
||||
sh "cat ~/.npm/_logs/*"
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import groovy.transform.Field
|
||||
@Field STEP_NAME = getClass().getName()
|
||||
|
||||
void call(Map parameters = [:]) {
|
||||
handlePipelineStepErrors (stepName: 'prepareDefaultValues', stepParameters: parameters) {
|
||||
handlePipelineStepErrors (stepName: 'prepareDefaultValues', stepParameters: parameters, echoDetails: false) {
|
||||
if(!DefaultValueCache.getInstance() || parameters.customDefaults) {
|
||||
def defaultValues = [:]
|
||||
def configFileList = ['default_pipeline_environment.yml']
|
||||
|
@ -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
|
||||
|
@ -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}'.")
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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 << '.'
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user