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/
|
targets/
|
||||||
documentation/docs-gen
|
documentation/docs-gen
|
||||||
|
|
||||||
consumer-test/workspace
|
consumer-test/**/workspace
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
- /^it\/.*$/
|
||||||
language: groovy
|
language: groovy
|
||||||
sudo: required
|
sudo: required
|
||||||
services:
|
services:
|
||||||
@ -35,8 +36,9 @@ jobs:
|
|||||||
cp -r documentation/docs documentation/docs-tmp
|
cp -r documentation/docs documentation/docs-tmp
|
||||||
documentation/bin/createDocu.sh vars documentation/docs-tmp/steps
|
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
|
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
|
- name: Consumer Tests
|
||||||
script: cd consumer-test && chmod +x runTests.sh && ./runTests.sh
|
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
|
- stage: Docs
|
||||||
name: Deploy
|
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]
|
Read and understand our [contribution guidelines][piper-library-contribution]
|
||||||
before opening a pull request.
|
before opening a pull request.
|
||||||
|
|
||||||
# [License][piper-library-license]
|
# License
|
||||||
|
|
||||||
Copyright (c) 2017 SAP SE or an SAP affiliate company. All rights reserved.
|
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
|
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
|
## Description
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@ -10,11 +10,11 @@ Content here is generated from corresponnding step, see `vars`.
|
|||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Step configuration
|
## Step configuration
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Exceptions
|
## Exceptions
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Kubernetes support
|
## Kubernetes support
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ If the Jenkins is setup on a Kubernetes cluster, then you can execute the closur
|
|||||||
|
|
||||||
## Step configuration
|
## Step configuration
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Side effects
|
## Side effects
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@ -13,11 +13,11 @@ Content here is generated from corresponnding step, see `vars`.
|
|||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Step configuration
|
## Step configuration
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Side effects
|
## Side effects
|
||||||
|
|
||||||
|
@ -2,82 +2,20 @@
|
|||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
In this step the ([Karma test runner](http://karma-runner.github.io)) is executed.
|
Content here is generated from corresponnding step, see `vars`.
|
||||||
|
|
||||||
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`.
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- **running Karma tests** - have a NPM module with running tests executed with 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
|
* **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
|
## Parameters
|
||||||
|
|
||||||
| parameter | mandatory | default | possible values |
|
Content here is generated from corresponnding step, see `vars`.
|
||||||
| ----------|-----------|---------|-----------------|
|
|
||||||
|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
|
|
||||||
|
|
||||||
## Step configuration
|
## Step configuration
|
||||||
|
|
||||||
We recommend to define values of step parameters via [config.yml file](../configuration.md).
|
Content here is generated from corresponnding step, see `vars`.
|
||||||
|
|
||||||
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|
|
|
||||||
|
|
||||||
## Side effects
|
## 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
|
## Description
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Step configuration
|
## Step configuration
|
||||||
|
|
||||||
Content here is generated from corresponnding step, see `vars`.
|
Content here is generated from corresponding step, see `vars`.
|
||||||
|
|
||||||
## Exceptions
|
## 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
|
## Examples
|
||||||
|
@ -24,6 +24,7 @@ nav:
|
|||||||
- mtaBuild: steps/mtaBuild.md
|
- mtaBuild: steps/mtaBuild.md
|
||||||
- neoDeploy: steps/neoDeploy.md
|
- neoDeploy: steps/neoDeploy.md
|
||||||
- newmanExecute: steps/newmanExecute.md
|
- newmanExecute: steps/newmanExecute.md
|
||||||
|
- npmExecute: steps/npmExecute.md
|
||||||
- pipelineExecute: steps/pipelineExecute.md
|
- pipelineExecute: steps/pipelineExecute.md
|
||||||
- pipelineRestartSteps: steps/pipelineRestartSteps.md
|
- pipelineRestartSteps: steps/pipelineRestartSteps.md
|
||||||
- pipelineStashFiles: steps/pipelineStashFiles.md
|
- pipelineStashFiles: steps/pipelineStashFiles.md
|
||||||
|
@ -16,6 +16,12 @@ general:
|
|||||||
from: 'origin/master'
|
from: 'origin/master'
|
||||||
to: 'HEAD'
|
to: 'HEAD'
|
||||||
format: '%b'
|
format: '%b'
|
||||||
|
rfc:
|
||||||
|
docker:
|
||||||
|
image: 'rfc'
|
||||||
|
options: []
|
||||||
|
envVars: {}
|
||||||
|
pullImage: true
|
||||||
githubApiUrl: 'https://api.github.com'
|
githubApiUrl: 'https://api.github.com'
|
||||||
githubServerUrl: 'https://github.com'
|
githubServerUrl: 'https://github.com'
|
||||||
gitSshKeyCredentialsId: '' #needed to allow sshagent to run with local ssh key
|
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'"
|
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:
|
stashContent:
|
||||||
- 'tests'
|
- 'tests'
|
||||||
|
npmExecute:
|
||||||
|
dockerImage: 'node:8-stretch'
|
||||||
pipelineRestartSteps:
|
pipelineRestartSteps:
|
||||||
sendMail: true
|
sendMail: true
|
||||||
timeoutInSeconds: 900
|
timeoutInSeconds: 900
|
||||||
@ -361,8 +369,14 @@ steps:
|
|||||||
failIfStatusIsNotInDevelopment: true
|
failIfStatusIsNotInDevelopment: true
|
||||||
transportRequestCreate:
|
transportRequestCreate:
|
||||||
developmentSystemId: null
|
developmentSystemId: null
|
||||||
|
verbose: false
|
||||||
transportRequestUploadFile:
|
transportRequestUploadFile:
|
||||||
|
acceptUnixStyleLineEndings: true
|
||||||
|
codePage: 'UTF-8'
|
||||||
|
failOnWarning: true
|
||||||
|
verbose: false
|
||||||
transportRequestRelease:
|
transportRequestRelease:
|
||||||
|
verbose: false
|
||||||
uiVeri5ExecuteTests:
|
uiVeri5ExecuteTests:
|
||||||
failOnError: false
|
failOnError: false
|
||||||
dockerEnvVars: {}
|
dockerEnvVars: {}
|
||||||
|
@ -2,6 +2,7 @@ package com.sap.piper
|
|||||||
|
|
||||||
import com.cloudbees.groovy.cps.NonCPS
|
import com.cloudbees.groovy.cps.NonCPS
|
||||||
import com.sap.piper.analytics.Telemetry
|
import com.sap.piper.analytics.Telemetry
|
||||||
|
import groovy.text.SimpleTemplateEngine
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.security.MessageDigest
|
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.
|
// 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;
|
package com.sap.piper.cm;
|
||||||
|
|
||||||
public enum BackendType {
|
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 com.sap.piper.GitUtils
|
||||||
|
|
||||||
|
import groovy.json.JsonSlurper
|
||||||
import hudson.AbortException
|
import hudson.AbortException
|
||||||
|
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ public class ChangeManagement implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isChangeInDevelopment(String changeId, String endpoint, String credentialsId, String clientOpts = '') {
|
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,
|
false,
|
||||||
clientOpts) as int
|
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 = '') {
|
String createTransportRequestCTS(String transportType, String targetSystemId, String description, String endpoint, String credentialsId, String clientOpts = '') {
|
||||||
try {
|
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}\""],
|
['-tt', transportType, '-ts', targetSystemId, '-d', "\"${description}\""],
|
||||||
true,
|
true,
|
||||||
clientOpts)
|
clientOpts)
|
||||||
@ -91,7 +92,7 @@ public class ChangeManagement implements Serializable {
|
|||||||
String createTransportRequestSOLMAN(String changeId, String developmentSystemId, String endpoint, String credentialsId, String clientOpts = '') {
|
String createTransportRequestSOLMAN(String changeId, String developmentSystemId, String endpoint, String credentialsId, String clientOpts = '') {
|
||||||
|
|
||||||
try {
|
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,
|
true,
|
||||||
clientOpts)
|
clientOpts)
|
||||||
return (transportRequest as String)?.trim()
|
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) {
|
try {
|
||||||
args = ['-cID', changeId,
|
|
||||||
'-tID', transportRequestId,
|
def transportRequestId = executeWithCredentials(
|
||||||
applicationId, "\"$filePath\""]
|
BackendType.RFC,
|
||||||
} else if (type == BackendType.CTS) {
|
docker,
|
||||||
args = ['-tID', transportRequestId,
|
endpoint,
|
||||||
"\"$filePath\""]
|
credentialsId,
|
||||||
} else {
|
command,
|
||||||
throw new IllegalArgumentException("Invalid backend type: ${type}")
|
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(
|
script.withCredentials([script.usernamePassword(
|
||||||
credentialsId: credentialsId,
|
credentialsId: credentialsId,
|
||||||
passwordVariable: 'password',
|
passwordVariable: 'password',
|
||||||
usernameVariable: 'username')]) {
|
usernameVariable: 'username')]) {
|
||||||
def cmScript = getCMCommandLine(type, endpoint, script.username, script.password,
|
|
||||||
command, args,
|
|
||||||
clientOpts)
|
|
||||||
|
|
||||||
Map shArgs = [:]
|
Map shArgs = [:]
|
||||||
|
|
||||||
if(returnStdout)
|
if(returnStdout)
|
||||||
shArgs.put('returnStdout', true)
|
shArgs.put('returnStdout', true)
|
||||||
else
|
else
|
||||||
shArgs.put('returnStatus', true)
|
shArgs.put('returnStatus', true)
|
||||||
|
|
||||||
shArgs.put('script', cmScript)
|
def result = 1
|
||||||
|
|
||||||
// user and password are masked by withCredentials
|
switch(type) {
|
||||||
script.echo """[INFO] Executing command line: "${cmScript}"."""
|
|
||||||
return script.sh(shArgs)
|
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
|
def cmd = 'release-transport'
|
||||||
List args = []
|
def args = [
|
||||||
|
'-cID',
|
||||||
|
changeId,
|
||||||
|
'-tID',
|
||||||
|
transportRequestId,
|
||||||
|
]
|
||||||
|
|
||||||
if(type == BackendType.SOLMAN) {
|
int rc = executeWithCredentials(
|
||||||
cmd = 'release-transport'
|
BackendType.SOLMAN,
|
||||||
args << '-cID'
|
[:],
|
||||||
args << changeId
|
endpoint,
|
||||||
} else if(type == BackendType.CTS) {
|
credentialsId,
|
||||||
cmd = 'export-transport'
|
cmd,
|
||||||
} else {
|
args,
|
||||||
throw new IllegalStateException("Invalid backend type: '${type}'")
|
false,
|
||||||
}
|
clientOpts) as int
|
||||||
|
|
||||||
args << '-tID'
|
if(rc != 0) {
|
||||||
args << transportRequestId
|
|
||||||
|
|
||||||
int rc = executeWithCredentials(type, endpoint, credentialsId, cmd, args, false, clientOpts) as int
|
|
||||||
if(rc == 0) {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
throw new ChangeManagementException("Cannot release Transport Request '$transportRequestId'. Return code from cmclient: $rc.")
|
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 getCMCommandLine(BackendType type,
|
||||||
String endpoint,
|
String endpoint,
|
||||||
String username,
|
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 Script step
|
||||||
private DeployMode deployMode
|
private DeployMode deployMode
|
||||||
private Map deploymentConfiguration
|
private Map deploymentConfiguration
|
||||||
private String pathToNeoExecutable
|
|
||||||
private String user
|
private String user
|
||||||
private String password
|
private String password
|
||||||
private String source
|
private String source
|
||||||
|
|
||||||
//Warning: Commands generated with this class can contain passwords and should only be used within the step withCredentials
|
//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) {
|
String user, String password, String source) {
|
||||||
this.step = step
|
this.step = step
|
||||||
this.deployMode = deployMode
|
this.deployMode = deployMode
|
||||||
this.deploymentConfiguration = deploymentConfiguration
|
this.deploymentConfiguration = deploymentConfiguration
|
||||||
this.pathToNeoExecutable = pathToNeoExecutable
|
|
||||||
this.user = user
|
this.user = user
|
||||||
this.password = password
|
this.password = password
|
||||||
this.source = source
|
this.source = source
|
||||||
}
|
}
|
||||||
|
|
||||||
private String prolog() {
|
private String prolog() {
|
||||||
return "\"${pathToNeoExecutable}\""
|
return 'neo.sh'
|
||||||
}
|
}
|
||||||
|
|
||||||
String statusCommand() {
|
String statusCommand() {
|
||||||
|
@ -115,9 +115,11 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest {
|
|||||||
.commonPipelineEnvironment
|
.commonPipelineEnvironment
|
||||||
.configuration = [steps:
|
.configuration = [steps:
|
||||||
[neoDeploy:
|
[neoDeploy:
|
||||||
[ host: 'hana.example.com',
|
[neo:
|
||||||
account: 'myTestAccount',
|
[ host: 'hana.example.com',
|
||||||
]
|
account: 'myTestAccount',
|
||||||
|
]
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -139,7 +141,7 @@ class FioriOnCloudPlatformPipelineTest extends BasePiperTest {
|
|||||||
// the neo deploy call:
|
// the neo deploy call:
|
||||||
Assert.assertThat(shellRule.shell,
|
Assert.assertThat(shellRule.shell,
|
||||||
new CommandLineMatcher()
|
new CommandLineMatcher()
|
||||||
.hasProlog("\"/opt/sap/neo/tools/neo.sh\" deploy-mta")
|
.hasProlog("neo.sh deploy-mta")
|
||||||
.hasSingleQuotedOption('host', 'hana\\.example\\.com')
|
.hasSingleQuotedOption('host', 'hana\\.example\\.com')
|
||||||
.hasSingleQuotedOption('account', 'myTestAccount')
|
.hasSingleQuotedOption('account', 'myTestAccount')
|
||||||
.hasSingleQuotedOption('password', 'terceSpot')
|
.hasSingleQuotedOption('password', 'terceSpot')
|
||||||
|
@ -84,109 +84,10 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
helper.registerAllowedMethod('dockerExecute', [Map, Closure], null)
|
helper.registerAllowedMethod('dockerExecute', [Map, Closure], null)
|
||||||
helper.registerAllowedMethod('fileExists', [String], { s -> return new File(workspacePath, s).exists() })
|
helper.registerAllowedMethod('fileExists', [String], { s -> return new File(workspacePath, s).exists() })
|
||||||
helper.registerAllowedMethod('pwd', [], { return workspacePath })
|
helper.registerAllowedMethod('pwd', [], { return workspacePath })
|
||||||
mockShellCommands()
|
|
||||||
|
|
||||||
nullScript.commonPipelineEnvironment.configuration = [steps: [neoDeploy: [neo: [host: 'test.deploy.host.com', account: 'trialuser123']]]]
|
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
|
@Test
|
||||||
void straightForwardTestConfigViaConfiguration() {
|
void straightForwardTestConfigViaConfiguration() {
|
||||||
|
|
||||||
@ -205,7 +106,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
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('host', 'test\\.deploy\\.host\\.com')
|
||||||
.hasSingleQuotedOption('account', 'trialuser123')
|
.hasSingleQuotedOption('account', 'trialuser123')
|
||||||
.hasOption('synchronous', '')
|
.hasOption('synchronous', '')
|
||||||
@ -231,7 +132,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
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('host', 'configuration-frwk\\.deploy\\.host\\.com')
|
||||||
.hasSingleQuotedOption('account', 'configurationFrwkUser123')
|
.hasSingleQuotedOption('account', 'configurationFrwkUser123')
|
||||||
.hasOption('synchronous', '')
|
.hasOption('synchronous', '')
|
||||||
@ -246,7 +147,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
stepRule.step.neoDeploy(script: nullScript)
|
stepRule.step.neoDeploy(script: nullScript)
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
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'))
|
.hasSingleQuotedOption('source', 'archive.mtar'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +158,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
source: "archive.mtar")
|
source: "archive.mtar")
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
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'))
|
.hasSingleQuotedOption('source', 'archive.mtar'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +183,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
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('host', 'test\\.deploy\\.host\\.com')
|
||||||
.hasSingleQuotedOption('account', 'trialuser123')
|
.hasSingleQuotedOption('account', 'trialuser123')
|
||||||
.hasOption('synchronous', '')
|
.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
|
@Test
|
||||||
void archiveNotProvidedTest() {
|
void archiveNotProvidedTest() {
|
||||||
|
|
||||||
@ -392,7 +230,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
stepRule.step.neoDeploy(script: nullScript, source: archiveName, deployMode: 'mta')
|
stepRule.step.neoDeploy(script: nullScript, source: archiveName, deployMode: 'mta')
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
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('host', 'test\\.deploy\\.host\\.com')
|
||||||
.hasSingleQuotedOption('account', 'trialuser123')
|
.hasSingleQuotedOption('account', 'trialuser123')
|
||||||
.hasOption('synchronous', '')
|
.hasOption('synchronous', '')
|
||||||
@ -417,7 +255,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
source: warArchiveName)
|
source: warArchiveName)
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
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('host', 'test\\.deploy\\.host\\.com')
|
||||||
.hasSingleQuotedOption('account', 'trialuser123')
|
.hasSingleQuotedOption('account', 'trialuser123')
|
||||||
.hasSingleQuotedOption('application', 'testApp')
|
.hasSingleQuotedOption('application', 'testApp')
|
||||||
@ -448,7 +286,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
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('host', 'test\\.deploy\\.host\\.com')
|
||||||
.hasSingleQuotedOption('account', 'trialuser123')
|
.hasSingleQuotedOption('account', 'trialuser123')
|
||||||
.hasSingleQuotedOption('application', 'testApp')
|
.hasSingleQuotedOption('application', 'testApp')
|
||||||
@ -478,7 +316,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
Assert.assertThat(shellRule.shell,
|
||||||
new CommandLineMatcher()
|
new CommandLineMatcher()
|
||||||
.hasProlog("\"/opt/neo/tools/neo.sh\" deploy")
|
.hasProlog("neo.sh deploy")
|
||||||
.hasSingleQuotedOption('application', 'testApp'))
|
.hasSingleQuotedOption('application', 'testApp'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,7 +379,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
Assert.assertThat(shellRule.shell,
|
||||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" deploy")
|
new CommandLineMatcher().hasProlog("neo.sh deploy")
|
||||||
.hasArgument("config.properties")
|
.hasArgument("config.properties")
|
||||||
.hasSingleQuotedOption('user', 'defaultUser')
|
.hasSingleQuotedOption('user', 'defaultUser')
|
||||||
.hasSingleQuotedOption('password', '\\*\\*\\*\\*\\*\\*\\*\\*')
|
.hasSingleQuotedOption('password', '\\*\\*\\*\\*\\*\\*\\*\\*')
|
||||||
@ -566,7 +404,7 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
])
|
])
|
||||||
|
|
||||||
Assert.assertThat(shellRule.shell,
|
Assert.assertThat(shellRule.shell,
|
||||||
new CommandLineMatcher().hasProlog("\"/opt/neo/tools/neo.sh\" rolling-update")
|
new CommandLineMatcher().hasProlog("neo.sh rolling-update")
|
||||||
.hasArgument('config.properties')
|
.hasArgument('config.properties')
|
||||||
.hasSingleQuotedOption('user', 'defaultUser')
|
.hasSingleQuotedOption('user', 'defaultUser')
|
||||||
.hasSingleQuotedOption('password', '\\*\\*\\*\\*\\*\\*\\*\\*')
|
.hasSingleQuotedOption('password', '\\*\\*\\*\\*\\*\\*\\*\\*')
|
||||||
@ -654,57 +492,4 @@ class NeoDeployTest extends BasePiperTest {
|
|||||||
size: 'lite'
|
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.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -54,7 +61,7 @@ public class TransportRequestCreateTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void changeIdNotProvidedTest() {
|
public void changeIdNotProvidedSOLANTest() {
|
||||||
|
|
||||||
thrown.expect(IllegalArgumentException)
|
thrown.expect(IllegalArgumentException)
|
||||||
thrown.expectMessage("Change document id not provided (parameter: 'changeDocumentId' or via commit history).")
|
thrown.expectMessage("Change document id not provided (parameter: 'changeDocumentId' or via commit history).")
|
||||||
@ -73,7 +80,7 @@ public class TransportRequestCreateTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void developmentSystemIdNotProvidedTest() {
|
public void developmentSystemIdNotProvidedSOLMANTest() {
|
||||||
|
|
||||||
thrown.expect(IllegalArgumentException)
|
thrown.expect(IllegalArgumentException)
|
||||||
thrown.expectMessage("ERROR - NO VALUE AVAILABLE FOR developmentSystemId")
|
thrown.expectMessage("ERROR - NO VALUE AVAILABLE FOR developmentSystemId")
|
||||||
@ -82,7 +89,7 @@ public class TransportRequestCreateTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createTransportRequestFailureTest() {
|
public void createTransportRequestFailureSOLMANTest() {
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
|
|
||||||
@ -154,8 +161,7 @@ public class TransportRequestCreateTest extends BasePiperTest {
|
|||||||
String description,
|
String description,
|
||||||
String endpoint,
|
String endpoint,
|
||||||
String credentialsId,
|
String credentialsId,
|
||||||
String clientOpts
|
String clientOpts) {
|
||||||
) {
|
|
||||||
result.transportType = transportType
|
result.transportType = transportType
|
||||||
result.targetSystemId = targetSystemId
|
result.targetSystemId = targetSystemId
|
||||||
result.description = description
|
result.description = description
|
||||||
@ -186,6 +192,120 @@ public class TransportRequestCreateTest extends BasePiperTest {
|
|||||||
assert loggingRule.log.contains("[INFO] Transport Request '001' has been successfully created.")
|
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
|
@Test
|
||||||
public void cmIntegrationSwichtedOffTest() {
|
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.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -10,6 +14,7 @@ import com.sap.piper.cm.ChangeManagementException
|
|||||||
|
|
||||||
import util.BasePiperTest
|
import util.BasePiperTest
|
||||||
import util.JenkinsCredentialsRule
|
import util.JenkinsCredentialsRule
|
||||||
|
import util.JenkinsDockerExecuteRule
|
||||||
import util.JenkinsStepRule
|
import util.JenkinsStepRule
|
||||||
import util.JenkinsLoggingRule
|
import util.JenkinsLoggingRule
|
||||||
import util.JenkinsReadYamlRule
|
import util.JenkinsReadYamlRule
|
||||||
@ -48,7 +53,7 @@ public class TransportRequestReleaseTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void changeIdNotProvidedTest() {
|
public void changeDocumentIdNotProvidedSOLMANTest() {
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
String getChangeDocumentId(String from,
|
String getChangeDocumentId(String from,
|
||||||
@ -84,14 +89,14 @@ public class TransportRequestReleaseTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void releaseTransportRequestFailureTest() {
|
public void releaseTransportRequestFailsSOLMANTest() {
|
||||||
|
|
||||||
thrown.expect(AbortException)
|
thrown.expect(AbortException)
|
||||||
thrown.expectMessage("Something went wrong")
|
thrown.expectMessage("Something went wrong")
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
|
|
||||||
void releaseTransportRequest(BackendType type,
|
void releaseTransportRequestSOLMAN(
|
||||||
String changeId,
|
String changeId,
|
||||||
String transportRequestId,
|
String transportRequestId,
|
||||||
String endpoint,
|
String endpoint,
|
||||||
@ -106,7 +111,257 @@ public class TransportRequestReleaseTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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
|
// Here we test only the case where the transportRequestId is
|
||||||
// provided via parameters. The other cases are tested by
|
// provided via parameters. The other cases are tested by
|
||||||
@ -118,14 +373,13 @@ public class TransportRequestReleaseTest extends BasePiperTest {
|
|||||||
Map receivedParams = [:]
|
Map receivedParams = [:]
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
void releaseTransportRequest(BackendType type,
|
void releaseTransportRequestSOLMAN(
|
||||||
String changeId,
|
String changeId,
|
||||||
String transportRequestId,
|
String transportRequestId,
|
||||||
String endpoint,
|
String endpoint,
|
||||||
String credentialsId,
|
String credentialsId,
|
||||||
String clientOpts) {
|
String clientOpts) {
|
||||||
|
|
||||||
receivedParams.type = type
|
|
||||||
receivedParams.changeId = changeId
|
receivedParams.changeId = changeId
|
||||||
receivedParams.transportRequestId = transportRequestId
|
receivedParams.transportRequestId = transportRequestId
|
||||||
receivedParams.endpoint = endpoint
|
receivedParams.endpoint = endpoint
|
||||||
@ -136,7 +390,7 @@ public class TransportRequestReleaseTest extends BasePiperTest {
|
|||||||
|
|
||||||
stepRule.step.transportRequestRelease(script: nullScript, changeDocumentId: '001', transportRequestId: '002', cmUtils: cm)
|
stepRule.step.transportRequestRelease(script: nullScript, changeDocumentId: '001', transportRequestId: '002', cmUtils: cm)
|
||||||
|
|
||||||
assert receivedParams == [type: BackendType.SOLMAN,
|
assert receivedParams == [
|
||||||
changeId: '001',
|
changeId: '001',
|
||||||
transportRequestId: '002',
|
transportRequestId: '002',
|
||||||
endpoint: 'https://example.org/cm',
|
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 java.util.Map
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.ExpectedException
|
import org.junit.rules.ExpectedException
|
||||||
import org.junit.rules.RuleChain
|
import org.junit.rules.RuleChain
|
||||||
|
|
||||||
|
import com.sap.piper.JenkinsUtils
|
||||||
import com.sap.piper.cm.BackendType
|
import com.sap.piper.cm.BackendType
|
||||||
import com.sap.piper.cm.ChangeManagement
|
import com.sap.piper.cm.ChangeManagement
|
||||||
import com.sap.piper.cm.ChangeManagementException
|
import com.sap.piper.cm.ChangeManagementException
|
||||||
@ -119,10 +125,10 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uploadFileToTransportRequestFailureTest() {
|
public void uploadFileToTransportRequestSOLMANFailureTest() {
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
void uploadFileToTransportRequest(BackendType type,
|
void uploadFileToTransportRequestSOLMAN(
|
||||||
String changeId,
|
String changeId,
|
||||||
String transportRequestId,
|
String transportRequestId,
|
||||||
String applicationId,
|
String applicationId,
|
||||||
@ -152,19 +158,14 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
loggingRule.expect("[INFO] File '/path' has been successfully uploaded to transport request '002'.")
|
loggingRule.expect("[INFO] File '/path' has been successfully uploaded to transport request '002'.")
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
void uploadFileToTransportRequest(BackendType type,
|
void uploadFileToTransportRequestCTS(
|
||||||
String changeId,
|
|
||||||
String transportRequestId,
|
String transportRequestId,
|
||||||
String applicationId,
|
|
||||||
String filePath,
|
String filePath,
|
||||||
String endpoint,
|
String endpoint,
|
||||||
String credentialsId,
|
String credentialsId,
|
||||||
String cmclientOpts) {
|
String cmclientOpts) {
|
||||||
|
|
||||||
cmUtilReceivedParams.type = type
|
|
||||||
cmUtilReceivedParams.changeId = changeId
|
|
||||||
cmUtilReceivedParams.transportRequestId = transportRequestId
|
cmUtilReceivedParams.transportRequestId = transportRequestId
|
||||||
cmUtilReceivedParams.applicationId = applicationId
|
|
||||||
cmUtilReceivedParams.filePath = filePath
|
cmUtilReceivedParams.filePath = filePath
|
||||||
cmUtilReceivedParams.endpoint = endpoint
|
cmUtilReceivedParams.endpoint = endpoint
|
||||||
cmUtilReceivedParams.credentialsId = credentialsId
|
cmUtilReceivedParams.credentialsId = credentialsId
|
||||||
@ -180,10 +181,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
|
|
||||||
assert cmUtilReceivedParams ==
|
assert cmUtilReceivedParams ==
|
||||||
[
|
[
|
||||||
type: BackendType.CTS,
|
|
||||||
changeId: null,
|
|
||||||
transportRequestId: '002',
|
transportRequestId: '002',
|
||||||
applicationId: null,
|
|
||||||
filePath: '/path',
|
filePath: '/path',
|
||||||
endpoint: 'https://example.org/cm',
|
endpoint: 'https://example.org/cm',
|
||||||
credentialsId: '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
|
@Test
|
||||||
public void uploadFileToTransportRequestSOLMANSuccessTest() {
|
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'.")
|
loggingRule.expect("[INFO] File '/path' has been successfully uploaded to transport request '002' of change document '001'.")
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
void uploadFileToTransportRequest(BackendType type,
|
void uploadFileToTransportRequestSOLMAN(
|
||||||
String changeId,
|
String changeId,
|
||||||
String transportRequestId,
|
String transportRequestId,
|
||||||
String applicationId,
|
String applicationId,
|
||||||
@ -211,7 +369,6 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
String credentialsId,
|
String credentialsId,
|
||||||
String cmclientOpts) {
|
String cmclientOpts) {
|
||||||
|
|
||||||
cmUtilReceivedParams.type = type
|
|
||||||
cmUtilReceivedParams.changeId = changeId
|
cmUtilReceivedParams.changeId = changeId
|
||||||
cmUtilReceivedParams.transportRequestId = transportRequestId
|
cmUtilReceivedParams.transportRequestId = transportRequestId
|
||||||
cmUtilReceivedParams.applicationId = applicationId
|
cmUtilReceivedParams.applicationId = applicationId
|
||||||
@ -231,7 +388,6 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
|
|
||||||
assert cmUtilReceivedParams ==
|
assert cmUtilReceivedParams ==
|
||||||
[
|
[
|
||||||
type: BackendType.SOLMAN,
|
|
||||||
changeId: '001',
|
changeId: '001',
|
||||||
transportRequestId: '002',
|
transportRequestId: '002',
|
||||||
applicationId: 'app',
|
applicationId: 'app',
|
||||||
@ -243,14 +399,14 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uploadFileToTransportRequestSuccessApplicationIdFromConfigurationTest() {
|
public void uploadFileToTransportRequestSOLMANSuccessApplicationIdFromConfigurationTest() {
|
||||||
|
|
||||||
nullScript.commonPipelineEnvironment.configuration.put(['steps',
|
nullScript.commonPipelineEnvironment.configuration.put(['steps',
|
||||||
[transportRequestUploadFile:
|
[transportRequestUploadFile:
|
||||||
[applicationId: 'AppIdfromConfig']]])
|
[applicationId: 'AppIdfromConfig']]])
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
void uploadFileToTransportRequest(BackendType type,
|
void uploadFileToTransportRequestSOLMAN(
|
||||||
String changeId,
|
String changeId,
|
||||||
String transportRequestId,
|
String transportRequestId,
|
||||||
String applicationId,
|
String applicationId,
|
||||||
@ -274,13 +430,13 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uploadFileToTransportRequestFilePathFromParameters() {
|
public void uploadFileToTransportRequestSOLMANFilePathFromParameters() {
|
||||||
|
|
||||||
// this one is not used when file path is provided via signature
|
// this one is not used when file path is provided via signature
|
||||||
nullScript.commonPipelineEnvironment.setMtarFilePath('/path2')
|
nullScript.commonPipelineEnvironment.setMtarFilePath('/path2')
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
void uploadFileToTransportRequest(BackendType type,
|
void uploadFileToTransportRequestSOLMAN(
|
||||||
String changeId,
|
String changeId,
|
||||||
String transportRequestId,
|
String transportRequestId,
|
||||||
String applicationId,
|
String applicationId,
|
||||||
@ -304,13 +460,13 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uploadFileToTransportRequestFilePathFromCommonPipelineEnvironment() {
|
public void uploadFileToTransportRequestSOLMANFilePathFromCommonPipelineEnvironment() {
|
||||||
|
|
||||||
// this one is used since there is nothing in the signature
|
// this one is used since there is nothing in the signature
|
||||||
nullScript.commonPipelineEnvironment.setMtarFilePath('/path2')
|
nullScript.commonPipelineEnvironment.setMtarFilePath('/path2')
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
void uploadFileToTransportRequest(BackendType type,
|
void uploadFileToTransportRequestSOLMAN(
|
||||||
String changeId,
|
String changeId,
|
||||||
String transportRequestId,
|
String transportRequestId,
|
||||||
String applicationId,
|
String applicationId,
|
||||||
@ -333,13 +489,13 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uploadFileToTransportRequestUploadFailureTest() {
|
public void uploadFileToTransportRequestSOLMANUploadFailureTest() {
|
||||||
|
|
||||||
thrown.expect(AbortException)
|
thrown.expect(AbortException)
|
||||||
thrown.expectMessage('Upload failure.')
|
thrown.expectMessage('Upload failure.')
|
||||||
|
|
||||||
ChangeManagement cm = new ChangeManagement(nullScript) {
|
ChangeManagement cm = new ChangeManagement(nullScript) {
|
||||||
void uploadFileToTransportRequest(BackendType type,
|
void uploadFileToTransportRequestSOLMAN(
|
||||||
String changeId,
|
String changeId,
|
||||||
String transportRequestId,
|
String transportRequestId,
|
||||||
String applicationId,
|
String applicationId,
|
||||||
@ -362,7 +518,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest {
|
|||||||
@Test
|
@Test
|
||||||
public void invalidBackendTypeTest() {
|
public void invalidBackendTypeTest() {
|
||||||
thrown.expect(AbortException)
|
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\'.')
|
'Configuration: \'changeManagement/type\'.')
|
||||||
|
|
||||||
stepRule.step.transportRequestUploadFile(script: nullScript,
|
stepRule.step.transportRequestUploadFile(script: nullScript,
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package com.sap.piper.cm
|
package com.sap.piper.cm
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.allOf
|
import static org.hamcrest.Matchers.allOf
|
||||||
|
import static org.hamcrest.Matchers.contains
|
||||||
import static org.hamcrest.Matchers.containsString
|
import static org.hamcrest.Matchers.containsString
|
||||||
import static org.hamcrest.Matchers.equalTo
|
import static org.hamcrest.Matchers.equalTo
|
||||||
import static org.hamcrest.Matchers.hasItem
|
import static org.hamcrest.Matchers.hasItem
|
||||||
import static org.hamcrest.Matchers.is
|
import static org.hamcrest.Matchers.is
|
||||||
import static org.hamcrest.Matchers.not
|
import static org.hamcrest.Matchers.not
|
||||||
import static org.junit.Assert.assertThat
|
import static org.junit.Assert.assertThat
|
||||||
|
import static org.junit.Assert.assertEquals
|
||||||
|
|
||||||
import org.hamcrest.Matchers
|
import org.hamcrest.Matchers
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
@ -22,6 +23,7 @@ import util.JenkinsLoggingRule
|
|||||||
import util.JenkinsScriptLoaderRule
|
import util.JenkinsScriptLoaderRule
|
||||||
import util.JenkinsShellCallRule
|
import util.JenkinsShellCallRule
|
||||||
import util.JenkinsCredentialsRule
|
import util.JenkinsCredentialsRule
|
||||||
|
import util.JenkinsDockerExecuteRule
|
||||||
import util.Rules
|
import util.Rules
|
||||||
|
|
||||||
import hudson.AbortException
|
import hudson.AbortException
|
||||||
@ -32,6 +34,7 @@ public class ChangeManagementTest extends BasePiperTest {
|
|||||||
|
|
||||||
private JenkinsShellCallRule script = new JenkinsShellCallRule(this)
|
private JenkinsShellCallRule script = new JenkinsShellCallRule(this)
|
||||||
private JenkinsLoggingRule logging = new JenkinsLoggingRule(this)
|
private JenkinsLoggingRule logging = new JenkinsLoggingRule(this)
|
||||||
|
private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this)
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public RuleChain rules = Rules.getCommonRules(this)
|
public RuleChain rules = Rules.getCommonRules(this)
|
||||||
@ -39,6 +42,7 @@ public class ChangeManagementTest extends BasePiperTest {
|
|||||||
.around(script)
|
.around(script)
|
||||||
.around(logging)
|
.around(logging)
|
||||||
.around(new JenkinsCredentialsRule(this).withCredentials('me','user','password'))
|
.around(new JenkinsCredentialsRule(this).withCredentials('me','user','password'))
|
||||||
|
.around(dockerExecuteRule)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRetrieveChangeDocumentIdOutsideGitWorkTreeTest() {
|
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
|
@Test
|
||||||
public void testCreateTransportRequestCTSSucceeds() {
|
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
|
@Test
|
||||||
public void testUploadFileToTransportSucceedsSOLMAN() {
|
public void testUploadFileToTransportSucceedsSOLMAN() {
|
||||||
|
|
||||||
// the regex provided below is an implicit check that the command line is fine.
|
// 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)
|
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, 'upload-file-to-transport.*-cID 001 -tID 002 XXX "/path"', 0)
|
||||||
|
|
||||||
new ChangeManagement(nullScript).uploadFileToTransportRequest(
|
new ChangeManagement(nullScript).uploadFileToTransportRequestSOLMAN(
|
||||||
BackendType.SOLMAN,
|
|
||||||
'001',
|
'001',
|
||||||
'002',
|
'002',
|
||||||
'XXX',
|
'XXX',
|
||||||
@ -228,11 +264,8 @@ public void testGetCommandLineWithCMClientOpts() {
|
|||||||
// the regex provided below is an implicit check that the command line is fine.
|
// 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)
|
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t CTS upload-file-to-transport -tID 002 "/path"', 0)
|
||||||
|
|
||||||
new ChangeManagement(nullScript).uploadFileToTransportRequest(
|
new ChangeManagement(nullScript).uploadFileToTransportRequestCTS(
|
||||||
BackendType.CTS,
|
|
||||||
null,
|
|
||||||
'002',
|
'002',
|
||||||
null,
|
|
||||||
'/path',
|
'/path',
|
||||||
'https://example.org/cm',
|
'https://example.org/cm',
|
||||||
'me')
|
'me')
|
||||||
@ -242,15 +275,85 @@ public void testGetCommandLineWithCMClientOpts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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.expect(ChangeManagementException)
|
||||||
thrown.expectMessage("Cannot upload file '/path' for change document '001' with transport request '002'. " +
|
thrown.expectMessage('Cannot upload file into transport request. Return code from rfc client: 1.')
|
||||||
"Return code from cmclient: 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)
|
script.setReturnValue(JenkinsShellCallRule.Type.REGEX,, 'upload-file-to-transport', 1)
|
||||||
|
|
||||||
new ChangeManagement(nullScript).uploadFileToTransportRequest(BackendType.SOLMAN,
|
new ChangeManagement(nullScript).uploadFileToTransportRequestSOLMAN(
|
||||||
'001',
|
'001',
|
||||||
'002',
|
'002',
|
||||||
'XXX',
|
'XXX',
|
||||||
@ -265,8 +368,7 @@ public void testGetCommandLineWithCMClientOpts() {
|
|||||||
// the regex provided below is an implicit check that the command line is fine.
|
// 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)
|
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t SOLMAN release-transport.*-cID 001.*-tID 002', 0)
|
||||||
|
|
||||||
new ChangeManagement(nullScript).releaseTransportRequest(
|
new ChangeManagement(nullScript).releaseTransportRequestSOLMAN(
|
||||||
BackendType.SOLMAN,
|
|
||||||
'001',
|
'001',
|
||||||
'002',
|
'002',
|
||||||
'https://example.org',
|
'https://example.org',
|
||||||
@ -283,9 +385,7 @@ public void testGetCommandLineWithCMClientOpts() {
|
|||||||
// the regex provided below is an implicit check that the command line is fine.
|
// 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)
|
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t CTS export-transport.*-tID 002', 0)
|
||||||
|
|
||||||
new ChangeManagement(nullScript).releaseTransportRequest(
|
new ChangeManagement(nullScript).releaseTransportRequestCTS(
|
||||||
BackendType.CTS,
|
|
||||||
null,
|
|
||||||
'002',
|
'002',
|
||||||
'https://example.org',
|
'https://example.org',
|
||||||
'me',
|
'me',
|
||||||
@ -296,7 +396,31 @@ public void testGetCommandLineWithCMClientOpts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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.expect(ChangeManagementException)
|
||||||
thrown.expectMessage("Cannot release Transport Request '002'. Return code from cmclient: 1.")
|
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.
|
// 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)
|
script.setReturnValue(JenkinsShellCallRule.Type.REGEX, 'release-transport.*-cID 001.*-tID 002', 1)
|
||||||
|
|
||||||
new ChangeManagement(nullScript).releaseTransportRequest(
|
new ChangeManagement(nullScript).releaseTransportRequestSOLMAN(
|
||||||
BackendType.SOLMAN,
|
|
||||||
'001',
|
'001',
|
||||||
'002',
|
'002',
|
||||||
'https://example.org',
|
'https://example.org',
|
||||||
'me',
|
'me')
|
||||||
'openSesame')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private GitUtils gitUtilsMock(boolean insideWorkTree, String[] changeIds) {
|
private GitUtils gitUtilsMock(boolean insideWorkTree, String[] changeIds) {
|
||||||
return new GitUtils() {
|
return new GitUtils() {
|
||||||
public boolean insideWorkTree() {
|
public boolean insideWorkTree() {
|
||||||
|
@ -34,7 +34,6 @@ class NeoCommandHelperTest extends BasePiperTest {
|
|||||||
String source = (deployMode == DeployMode.MTA) ? 'file.mta' : 'file.war'
|
String source = (deployMode == DeployMode.MTA) ? 'file.mta' : 'file.war'
|
||||||
String username = 'username'
|
String username = 'username'
|
||||||
String password = 'password'
|
String password = 'password'
|
||||||
String neoExecutable = '/path/tools/neo.sh';
|
|
||||||
|
|
||||||
nullScript.STEP_NAME="neoDeploy"
|
nullScript.STEP_NAME="neoDeploy"
|
||||||
|
|
||||||
@ -42,7 +41,6 @@ class NeoCommandHelperTest extends BasePiperTest {
|
|||||||
nullScript,
|
nullScript,
|
||||||
deployMode,
|
deployMode,
|
||||||
deploymentConfiguration,
|
deploymentConfiguration,
|
||||||
neoExecutable,
|
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
source
|
source
|
||||||
@ -52,7 +50,7 @@ class NeoCommandHelperTest extends BasePiperTest {
|
|||||||
@Test
|
@Test
|
||||||
void testStatusCommand() {
|
void testStatusCommand() {
|
||||||
String actual = getTestFixture(DeployMode.WAR_PARAMS).statusCommand()
|
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'"
|
"--application 'application_value' --user 'username' --password 'password'"
|
||||||
Assert.assertEquals(expected, actual)
|
Assert.assertEquals(expected, actual)
|
||||||
}
|
}
|
||||||
@ -60,14 +58,14 @@ class NeoCommandHelperTest extends BasePiperTest {
|
|||||||
@Test
|
@Test
|
||||||
void testStatusCommandForProperties() {
|
void testStatusCommandForProperties() {
|
||||||
String actual = getTestFixture(DeployMode.WAR_PROPERTIES_FILE).statusCommand()
|
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)
|
Assert.assertEquals(expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRollingUpdateCommand() {
|
void testRollingUpdateCommand() {
|
||||||
String actual = getTestFixture(DeployMode.WAR_PARAMS).rollingUpdateCommand()
|
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'"
|
"--application 'application_value' --user 'username' --password 'password' --source 'file.war'"
|
||||||
|
|
||||||
Assert.assertTrue(actual.contains(basicCommand))
|
Assert.assertTrue(actual.contains(basicCommand))
|
||||||
@ -81,14 +79,14 @@ class NeoCommandHelperTest extends BasePiperTest {
|
|||||||
@Test
|
@Test
|
||||||
void testRollingUpdateCommandForProperties() {
|
void testRollingUpdateCommandForProperties() {
|
||||||
String actual = getTestFixture(DeployMode.WAR_PROPERTIES_FILE).rollingUpdateCommand()
|
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)
|
Assert.assertEquals(expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDeployCommand() {
|
void testDeployCommand() {
|
||||||
String actual = getTestFixture(DeployMode.WAR_PARAMS).deployCommand()
|
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'"
|
"--application 'application_value' --user 'username' --password 'password' --source 'file.war'"
|
||||||
|
|
||||||
Assert.assertTrue(actual.contains(basicCommand))
|
Assert.assertTrue(actual.contains(basicCommand))
|
||||||
@ -102,14 +100,14 @@ class NeoCommandHelperTest extends BasePiperTest {
|
|||||||
@Test
|
@Test
|
||||||
void testDeployCommandForProperties() {
|
void testDeployCommandForProperties() {
|
||||||
String actual = getTestFixture(DeployMode.WAR_PROPERTIES_FILE).deployCommand()
|
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)
|
Assert.assertEquals(expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRestartCommand() {
|
void testRestartCommand() {
|
||||||
String actual = getTestFixture(DeployMode.WAR_PARAMS).restartCommand()
|
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'"
|
"--application 'application_value' --user 'username' --password 'password'"
|
||||||
Assert.assertEquals(expected, actual)
|
Assert.assertEquals(expected, actual)
|
||||||
}
|
}
|
||||||
@ -117,14 +115,14 @@ class NeoCommandHelperTest extends BasePiperTest {
|
|||||||
@Test
|
@Test
|
||||||
void testRestartCommandForProperties() {
|
void testRestartCommandForProperties() {
|
||||||
String actual = getTestFixture(DeployMode.WAR_PROPERTIES_FILE).restartCommand()
|
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)
|
Assert.assertEquals(expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void deployMta() {
|
void deployMta() {
|
||||||
String actual = getTestFixture(DeployMode.MTA).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'"
|
"--user 'username' --password 'password' --source 'file.mta'"
|
||||||
Assert.assertEquals(expected, actual)
|
Assert.assertEquals(expected, actual)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,10 @@ void call(Map parameters = [:]) {
|
|||||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||||
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS)
|
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS)
|
||||||
.mixin([
|
.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)
|
.mixin(parameters, PARAMETER_KEYS)
|
||||||
.addIfNull('customData', script.commonPipelineEnvironment.getInfluxCustomData())
|
.addIfNull('customData', script.commonPipelineEnvironment.getInfluxCustomData())
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import static com.sap.piper.Prerequisites.checkScript
|
import static com.sap.piper.Prerequisites.checkScript
|
||||||
|
|
||||||
import com.sap.piper.ConfigurationHelper
|
import com.sap.piper.ConfigurationHelper
|
||||||
|
import com.sap.piper.GenerateDocumentation
|
||||||
import com.sap.piper.GitUtils
|
import com.sap.piper.GitUtils
|
||||||
import com.sap.piper.Utils
|
import com.sap.piper.Utils
|
||||||
|
|
||||||
@ -9,34 +10,67 @@ import groovy.transform.Field
|
|||||||
|
|
||||||
@Field String STEP_NAME = getClass().getName()
|
@Field String STEP_NAME = getClass().getName()
|
||||||
@Field Set GENERAL_CONFIG_KEYS = [
|
@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',
|
'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',
|
'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',
|
'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',
|
'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',
|
'dockerWorkspace',
|
||||||
|
/**
|
||||||
|
* With `failOnError` the behavior in case tests fail can be defined.
|
||||||
|
* @possibleValues `true`, `false`
|
||||||
|
*/
|
||||||
'failOnError',
|
'failOnError',
|
||||||
|
/** The command that is executed to install the test tool. */
|
||||||
'installCommand',
|
'installCommand',
|
||||||
|
/** Define the paths of the modules to execute tests on. */
|
||||||
'modules',
|
'modules',
|
||||||
|
/** The command that is executed to start the tests. */
|
||||||
'runCommand',
|
'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',
|
'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',
|
'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',
|
'sidecarName',
|
||||||
/** volume bind. This will not take effect in Kubernetes pod. */
|
/** Volumes that should be mounted into the sidecar container. */
|
||||||
'sidecarVolumeBind',
|
'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'
|
'stashContent'
|
||||||
]
|
]
|
||||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS
|
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS
|
||||||
@Field Set PARAMETER_KEYS = STEP_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 = [:]) {
|
void call(Map parameters = [:]) {
|
||||||
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
||||||
final script = checkScript(this, parameters) ?: this
|
final script = checkScript(this, parameters) ?: this
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import com.sap.piper.ConfigurationHelper
|
import com.sap.piper.ConfigurationHelper
|
||||||
import com.sap.piper.Utils
|
import com.sap.piper.Utils
|
||||||
import com.sap.piper.tools.ToolDescriptor
|
|
||||||
import com.sap.piper.tools.neo.DeployMode
|
import com.sap.piper.tools.neo.DeployMode
|
||||||
import com.sap.piper.tools.neo.NeoCommandHelper
|
import com.sap.piper.tools.neo.NeoCommandHelper
|
||||||
import com.sap.piper.tools.neo.WarAction
|
import com.sap.piper.tools.neo.WarAction
|
||||||
@ -25,21 +24,6 @@ import static com.sap.piper.Prerequisites.checkScript
|
|||||||
'warAction'
|
'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 = [:]) {
|
void call(parameters = [:]) {
|
||||||
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
||||||
|
|
||||||
@ -49,19 +33,17 @@ void call(parameters = [:]) {
|
|||||||
|
|
||||||
prepareDefaultValues script: script
|
prepareDefaultValues script: script
|
||||||
|
|
||||||
Map stepCompatibilityConfiguration = handleCompatibility(script, parameters)
|
|
||||||
|
|
||||||
// load default & individual configuration
|
// load default & individual configuration
|
||||||
Map configuration = ConfigurationHelper.newInstance(this)
|
Map configuration = ConfigurationHelper.newInstance(this)
|
||||||
.loadStepDefaults()
|
.loadStepDefaults()
|
||||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||||
.mixin(stepCompatibilityConfiguration)
|
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS)
|
||||||
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
|
||||||
.addIfEmpty('source', script.commonPipelineEnvironment.getMtarFilePath())
|
.addIfEmpty('source', script.commonPipelineEnvironment.getMtarFilePath())
|
||||||
.mixin(parameters, PARAMETER_KEYS, CONFIG_KEY_COMPATIBILITY)
|
.mixin(parameters, PARAMETER_KEYS)
|
||||||
.withMandatoryProperty('neo')
|
.withMandatoryProperty('neo')
|
||||||
.withMandatoryProperty('source')
|
.withMandatoryProperty('source')
|
||||||
|
.withMandatoryProperty('neo/credentialsId')
|
||||||
.withPropertyInValues('deployMode', DeployMode.stringValues())
|
.withPropertyInValues('deployMode', DeployMode.stringValues())
|
||||||
.use()
|
.use()
|
||||||
|
|
||||||
@ -73,52 +55,37 @@ void call(parameters = [:]) {
|
|||||||
stepParam2: configuration.warAction == 'rolling-update'?'blue-green':'standard', // ['deploy', 'deploy-mta', 'rolling-update']
|
stepParam2: configuration.warAction == 'rolling-update'?'blue-green':'standard', // ['deploy', 'deploy-mta', 'rolling-update']
|
||||||
stepParamKey3: 'scriptMissing',
|
stepParamKey3: 'scriptMissing',
|
||||||
stepParam3: parameters?.script == null,
|
stepParam3: parameters?.script == null,
|
||||||
stepParamKey4: 'legacyConfig',
|
|
||||||
stepParam4: !stepCompatibilityConfiguration.isEmpty(),
|
|
||||||
], configuration)
|
], 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(
|
||||||
withCredentials([usernamePassword(
|
credentialsId: configuration.neo.credentialsId,
|
||||||
credentialsId: configuration.neo.credentialsId,
|
passwordVariable: 'NEO_PASSWORD',
|
||||||
passwordVariable: 'NEO_PASSWORD',
|
usernameVariable: 'NEO_USERNAME')]) {
|
||||||
usernameVariable: 'NEO_USERNAME')]) {
|
|
||||||
|
|
||||||
assertPasswordRules(NEO_PASSWORD)
|
assertPasswordRules(NEO_PASSWORD)
|
||||||
|
|
||||||
dockerExecute(
|
dockerExecute(
|
||||||
script: script,
|
script: script,
|
||||||
dockerImage: configuration.dockerImage,
|
dockerImage: configuration.dockerImage,
|
||||||
dockerEnvVars: configuration.dockerEnvVars,
|
dockerEnvVars: configuration.dockerEnvVars,
|
||||||
dockerOptions: configuration.dockerOptions
|
dockerOptions: configuration.dockerOptions
|
||||||
) {
|
) {
|
||||||
|
DeployMode deployMode = DeployMode.fromString(configuration.deployMode)
|
||||||
|
|
||||||
neo.verify(this, configuration)
|
NeoCommandHelper neoCommandHelper = new NeoCommandHelper(
|
||||||
java.verify(this, configuration)
|
this,
|
||||||
|
deployMode,
|
||||||
|
configuration.neo,
|
||||||
|
NEO_USERNAME,
|
||||||
|
NEO_PASSWORD,
|
||||||
|
configuration.source
|
||||||
|
)
|
||||||
|
|
||||||
String neoExecutable = neo.getToolExecutable(script, configuration)
|
lock("$STEP_NAME :${neoCommandHelper.resourceLock()}") {
|
||||||
|
deploy(script, utils, configuration, neoCommandHelper, configuration.dockerImage, deployMode)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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')
|
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) {
|
private assertPasswordRules(String password) {
|
||||||
if (password.startsWith("@")) {
|
if (password.startsWith("@")) {
|
||||||
error("Your password for the deployment to SAP Cloud Platform contains characters which are not " +
|
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()
|
@Field STEP_NAME = getClass().getName()
|
||||||
|
|
||||||
void call(Map parameters = [:]) {
|
void call(Map parameters = [:]) {
|
||||||
handlePipelineStepErrors (stepName: 'prepareDefaultValues', stepParameters: parameters) {
|
handlePipelineStepErrors (stepName: 'prepareDefaultValues', stepParameters: parameters, echoDetails: false) {
|
||||||
if(!DefaultValueCache.getInstance() || parameters.customDefaults) {
|
if(!DefaultValueCache.getInstance() || parameters.customDefaults) {
|
||||||
def defaultValues = [:]
|
def defaultValues = [:]
|
||||||
def configFileList = ['default_pipeline_environment.yml']
|
def configFileList = ['default_pipeline_environment.yml']
|
||||||
|
@ -14,7 +14,7 @@ void call(Map parameters = [:]) {
|
|||||||
|
|
||||||
handlePipelineStepErrors (stepName: 'toolValidate', stepParameters: 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 tool = parameters.tool
|
||||||
def home = parameters.home
|
def home = parameters.home
|
||||||
|
@ -23,6 +23,7 @@ import hudson.AbortException
|
|||||||
'developmentSystemId', // SOLMAN
|
'developmentSystemId', // SOLMAN
|
||||||
'targetSystem', // CTS
|
'targetSystem', // CTS
|
||||||
'transportType', // CTS
|
'transportType', // CTS
|
||||||
|
'verbose', // RFC
|
||||||
]
|
]
|
||||||
|
|
||||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus(['changeDocumentId'])
|
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus(['changeDocumentId'])
|
||||||
@ -38,6 +39,7 @@ void call(parameters = [:]) {
|
|||||||
ChangeManagement cm = parameters.cmUtils ?: new ChangeManagement(script)
|
ChangeManagement cm = parameters.cmUtils ?: new ChangeManagement(script)
|
||||||
|
|
||||||
ConfigurationHelper configHelper = ConfigurationHelper.newInstance(this)
|
ConfigurationHelper configHelper = ConfigurationHelper.newInstance(this)
|
||||||
|
.collectValidationFailures()
|
||||||
.loadStepDefaults()
|
.loadStepDefaults()
|
||||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||||
@ -60,6 +62,9 @@ void call(parameters = [:]) {
|
|||||||
.withMandatoryProperty('transportType', null, { backendType == BackendType.CTS})
|
.withMandatoryProperty('transportType', null, { backendType == BackendType.CTS})
|
||||||
.withMandatoryProperty('targetSystem', null, { backendType == BackendType.CTS})
|
.withMandatoryProperty('targetSystem', null, { backendType == BackendType.CTS})
|
||||||
.withMandatoryProperty('description', 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
|
def changeDocumentId = null
|
||||||
|
|
||||||
@ -88,7 +93,8 @@ void call(parameters = [:]) {
|
|||||||
creatingMessage << '.'
|
creatingMessage << '.'
|
||||||
echo creatingMessage.join()
|
echo creatingMessage.join()
|
||||||
|
|
||||||
try {
|
|
||||||
|
try {
|
||||||
if(backendType == BackendType.SOLMAN) {
|
if(backendType == BackendType.SOLMAN) {
|
||||||
transportRequestId = cm.createTransportRequestSOLMAN(
|
transportRequestId = cm.createTransportRequestSOLMAN(
|
||||||
configuration.changeDocumentId,
|
configuration.changeDocumentId,
|
||||||
@ -104,6 +110,15 @@ void call(parameters = [:]) {
|
|||||||
configuration.changeManagement.endpoint,
|
configuration.changeManagement.endpoint,
|
||||||
configuration.changeManagement.credentialsId,
|
configuration.changeManagement.credentialsId,
|
||||||
configuration.changeManagement.clientOpts)
|
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 {
|
} else {
|
||||||
throw new IllegalArgumentException("Invalid backend type: '${backendType}'.")
|
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([
|
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus([
|
||||||
'changeDocumentId',
|
'changeDocumentId',
|
||||||
'transportRequestId',
|
'transportRequestId',
|
||||||
|
'verbose',
|
||||||
])
|
])
|
||||||
|
|
||||||
void call(parameters = [:]) {
|
void call(parameters = [:]) {
|
||||||
@ -49,12 +50,16 @@ void call(parameters = [:]) {
|
|||||||
if(backendType == BackendType.NONE) return
|
if(backendType == BackendType.NONE) return
|
||||||
|
|
||||||
configHelper
|
configHelper
|
||||||
|
.collectValidationFailures()
|
||||||
.withMandatoryProperty('changeManagement/clientOpts')
|
.withMandatoryProperty('changeManagement/clientOpts')
|
||||||
.withMandatoryProperty('changeManagement/credentialsId')
|
.withMandatoryProperty('changeManagement/credentialsId')
|
||||||
.withMandatoryProperty('changeManagement/endpoint')
|
.withMandatoryProperty('changeManagement/endpoint')
|
||||||
.withMandatoryProperty('changeManagement/git/to')
|
.withMandatoryProperty('changeManagement/git/to')
|
||||||
.withMandatoryProperty('changeManagement/git/from')
|
.withMandatoryProperty('changeManagement/git/from')
|
||||||
.withMandatoryProperty('changeManagement/git/format')
|
.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()
|
configuration = configHelper.use()
|
||||||
|
|
||||||
@ -89,13 +94,44 @@ void call(parameters = [:]) {
|
|||||||
echo closingMessage.join()
|
echo closingMessage.join()
|
||||||
|
|
||||||
try {
|
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) {
|
} catch(ChangeManagementException ex) {
|
||||||
throw new AbortException(ex.getMessage())
|
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([
|
@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([
|
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus([
|
||||||
'changeDocumentId',
|
'changeDocumentId',
|
||||||
'filePath',
|
|
||||||
'transportRequestId'])
|
'transportRequestId'])
|
||||||
|
|
||||||
void call(parameters = [:]) {
|
void call(parameters = [:]) {
|
||||||
@ -51,6 +58,7 @@ void call(parameters = [:]) {
|
|||||||
if(backendType == BackendType.NONE) return
|
if(backendType == BackendType.NONE) return
|
||||||
|
|
||||||
configHelper
|
configHelper
|
||||||
|
.collectValidationFailures()
|
||||||
.withMandatoryProperty('changeManagement/changeDocumentLabel')
|
.withMandatoryProperty('changeManagement/changeDocumentLabel')
|
||||||
.withMandatoryProperty('changeManagement/clientOpts')
|
.withMandatoryProperty('changeManagement/clientOpts')
|
||||||
.withMandatoryProperty('changeManagement/credentialsId')
|
.withMandatoryProperty('changeManagement/credentialsId')
|
||||||
@ -59,7 +67,22 @@ void call(parameters = [:]) {
|
|||||||
.withMandatoryProperty('changeManagement/git/from')
|
.withMandatoryProperty('changeManagement/git/from')
|
||||||
.withMandatoryProperty('changeManagement/git/to')
|
.withMandatoryProperty('changeManagement/git/to')
|
||||||
.withMandatoryProperty('changeManagement/git/format')
|
.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([
|
new Utils().pushToSWA([
|
||||||
step: STEP_NAME,
|
step: STEP_NAME,
|
||||||
@ -85,14 +108,15 @@ void call(parameters = [:]) {
|
|||||||
configHelper
|
configHelper
|
||||||
.withMandatoryProperty('changeDocumentId',
|
.withMandatoryProperty('changeDocumentId',
|
||||||
"Change document id not provided (parameter: \'changeDocumentId\' or via commit history).")
|
"Change document id not provided (parameter: \'changeDocumentId\' or via commit history).")
|
||||||
.withMandatoryProperty('applicationId')
|
|
||||||
}
|
}
|
||||||
configuration = configHelper
|
configuration = configHelper
|
||||||
.withMandatoryProperty('transportRequestId',
|
.withMandatoryProperty('transportRequestId',
|
||||||
"Transport request id not provided (parameter: \'transportRequestId\' or via commit history).")
|
"Transport request id not provided (parameter: \'transportRequestId\' or via commit history).")
|
||||||
.use()
|
.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)
|
if(backendType == BackendType.SOLMAN)
|
||||||
uploadingMessage << " of change document '${configuration.changeDocumentId}'"
|
uploadingMessage << " of change document '${configuration.changeDocumentId}'"
|
||||||
uploadingMessage << '.'
|
uploadingMessage << '.'
|
||||||
@ -101,22 +125,55 @@ void call(parameters = [:]) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
switch(backendType) {
|
||||||
|
|
||||||
cm.uploadFileToTransportRequest(backendType,
|
case BackendType.SOLMAN:
|
||||||
configuration.changeDocumentId,
|
cm.uploadFileToTransportRequestSOLMAN(
|
||||||
configuration.transportRequestId,
|
configuration.changeDocumentId,
|
||||||
configuration.applicationId,
|
configuration.transportRequestId,
|
||||||
configuration.filePath,
|
configuration.applicationId,
|
||||||
configuration.changeManagement.endpoint,
|
configuration.filePath,
|
||||||
configuration.changeManagement.credentialsId,
|
configuration.changeManagement.endpoint,
|
||||||
configuration.changeManagement.clientOpts)
|
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) {
|
} catch(ChangeManagementException ex) {
|
||||||
throw new AbortException(ex.getMessage())
|
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)
|
if(backendType == BackendType.SOLMAN)
|
||||||
uploadedMessage << " of change document '${configuration.changeDocumentId}'"
|
uploadedMessage << " of change document '${configuration.changeDocumentId}'"
|
||||||
uploadedMessage << '.'
|
uploadedMessage << '.'
|
||||||
|
@ -74,7 +74,12 @@ import static com.sap.piper.Prerequisites.checkScript
|
|||||||
/**
|
/**
|
||||||
* With `testRepository` the tests can be loaded from another reposirory.
|
* 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
|
@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.stashContent = config.testRepository ? [GitUtils.handleTestRepository(this, config)] : utils.unstashAll(config.stashContent)
|
||||||
config.installCommand = SimpleTemplateEngine.newInstance().createTemplate(config.installCommand).make([config: config]).toString()
|
config.installCommand = SimpleTemplateEngine.newInstance().createTemplate(config.installCommand).make([config: config]).toString()
|
||||||
config.runCommand = SimpleTemplateEngine.newInstance().createTemplate(config.runCommand).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(
|
seleniumExecuteTests(
|
||||||
script: script,
|
script: script,
|
||||||
|
Loading…
Reference in New Issue
Block a user