How can I integrate my test suite to inform review acceptance or rejection?
Integrating Perforce Swarm with a test suite involves enabling Automated Tests in your project's configuration and providing a trigger URL. When the trigger URL is requested, Swarm expects your test suite to be executed. When the tests complete, Swarm expects either a pass callback URL or fail callback URL to be requested by your test suite.
-
Visit your project page.
-
Click . The Edit Project page is displayed.
-
Click the checkbox next to Automated Tests to display the Automated Tests configuration fields:
-
Provide a URL that triggers your test suite execution.
Special arguments are provided to inform your test suite of various details from Swarm:
- {change}
-
The change number.
- {status}
-
Status of the shelved change, shelved or committed.
- {review}
-
The review's identifier.
- {project}
-
The project's identifier.
- {projectName}
-
The project's name.
- {branch}
-
The branch identifier(s) impacted by the review, comma-separated.
- {branchName}
-
The branch name(s) impacted by the review, comma-separated.
- {pass}
-
Tests pass callback URL.
- {fail}
-
Tests fail callback URL.
Configuring Jenkins for Swarm integration
-
Configure a Jenkins project:
-
Make the build parameterized to accept these parameters (note that these are named to match up with the script that is called):
-
SWARM_BRANCH
-
branch id configured within the Swarm project
-
SWARM_CHANGE
-
changelist # to run tests against
-
SWARM_CHANGE_STATUS
-
whether change is shelved or submitted
-
SWARM_SUCCESS_URL
-
what to wget if the build succeeds
-
SWARM_FAILURE_URL
-
what to wget if the build fails
-
-
Select None for the Source Code Management section
-
Define a Built Trigger section:
-
Check
-
Enter a JIRA authentication token value (see
YOURTOKEN
below)
-
-
For the Build section, define an execute shell section to call your build script.
-
See below for an example build script.
-
Define any regular post-build actions you would like.
-
-
-
Create your own build script.
Use the example script provided below. Make sure you configure the same branch identifiers and depot paths within the script that you have configured for the project.
-
Configure your Swarm project to run automated tests with a URL like this:
http://jenkins.bnr.perforce.com/view/JENKINSTAB/job/YOURJENKINSBUILD/buildWithParameters?token=YOURTOKEN&cause=Automated%20test%20triggered%20for%20Swarm%20project%20{projectName},%20branch%20{branchName},%20review%20{review}&SWARM_BRANCH={branch}&SWARM_CHANGE={change}&SWARM_CHANGE_STATUS={status}&SWARM_SUCCESS_URL={pass}&SWARM_FAILURE_URL={fail}
Note
Swarm's
SWARM_SUCCESS_URL
andSWARM_FAILURE_URL
are composed automatically by Swarm, and include Swarm's own per-review authentication tokens.If your build script has access to the results of test execution, include a GET or POST parameter called
url
when calling theSWARM_SUCCESS_URL
orSWARM_FAILURE_URL
. Swarm uses the provided URL to link reviews to the test results.The example Jenkins script provided below does not demonstrate this capability.
Example Jenkins build script
The following is a Jenkins build script used during the development of Swarm:
#!/bin/bash
ME=jenkins-swarm-trigger
# specify branch identifiers and depot paths that correspond
# with the project configuration in Swarm.
declare -A branches
branches[main] = "//depot/project/..."
function usage
{
cat << USAGE >&2
$ME
This script is meant to be called by a triggered Jenkins build
from Swarm. It needs the following environment variables defined:
* JOB_NAME (Jenkins): name of the Jenkins build project
* WORKSPACE (Jenkins): workspace directory to be created
* BUILD_URL (Jenkins): URL of resulting build
* SWARM_BRANCH (Swarm): name of branch
* SWARM_CHANGE (Swarm): changelist to sync/unshelve
* SWARM_CHANGE_STATUS (Swarm): changelist is shelved or submitted
* ANT_TARGETS (Swarm): what Ant targets to call
* SWARM_FAILURE_URL (Swarm): URL to get upon build failure
* SWARM_SUCCESS_URL (Swarm): URL to get upon build success
USAGE
exit 5
}
function checkEnv
{
while [ ! -z "$1" ]
do
[ -z "${!1}" ] &&
exitFail "environment variable [$1] not defined"
shift
done
}
function checkChangeStatus
{
[ -z "$1" ] || [ -z "$2" ] &&
exitFail "specify change & status to checkChangeStatus"
local change="$1"
local status="$2"
echo "$ME: checking change [$change] is [$status]..."
p4 changes -s $status @$change,@$change 2> /dev/null |
head -n1 |
grep -q "^Change $change on" ||
exitFail "change [$change] does not appear to be [$status]"
return 0
}
function exitFail
{
[ ! -z "$1" ] &&
echo "$ME: error: $*"
echo "$ME: exiting with failure..."
[ ! -z "$SWARM_FAILURE_URL" ] &&
echo "$ME: reporting failure to [$SWARM_FAILURE_URL]" &&
curl -d url=$BUILD_URL -o - $SWARM_FAILURE_URL |
python -mjson.tool
exit 1
}
function exitGood
{
echo "$ME: exit with success..."
[ ! -z "$SWARM_SUCCESS_URL" ] &&
echo "$ME: reporting success to [$SWARM_SUCCESS_URL]" &&
curl -d url=$BUILD_URL -o - $SWARM_SUCCESS_URL |
python -mjson.tool
exit 0
}
function isNotSet
{
if [[ ! ${!1} && ${!1-_} ]]
then
return 1
fi
}
echo "$ME: checking inputs"
checkEnv JOB_NAME WORKSPACE BUILD_URL SWARM_BRANCH SWARM_CHANGE\
SWARM_CHANGE_STATUS
for v in JOB_NAME WORKSPACE BUILD_URL SWARM_BRANCH SWARM_CHANGE\
SWARM_CHANGE_STATUS ANT_TARGETS SWARM_SUCCESS_URL\
SWARM_FAILURE_URL
do
echo -e "$v =\t[${!v}]"
done
cd $WORKSPACE || exitFail
which p4 > /dev/null 2>&1
[ $? -ne 0 ] &&
exitFail "p4 not found in PATH"
which ant > /dev/null 2>&1
[ $? -ne 0 ] &&
exitFail "ant not found in PATH"
p4 -h > /dev/null 2>&1
[ $? -ne 0 ] &&
exitFail "trouble running p4"
p4 help > /dev/null 2>&1
[ $? -ne 0 ] &&
exitFail "trouble connecting to Perforce service"
echo "$ME: change in question:"
p4 describe -s @$SWARM_CHANGE | grep ^[^#]
checkChangeStatus $SWARM_CHANGE $SWARM_CHANGE_STATUS
# create the view
isNotSet branches[${SWARM_BRANCH}]
[ $? -ne 0 ] &&
exitFail "unknown branch [$SWARM_BRANCH]" ;;
p4branch = ${branches[${SWARM_BRANCH}]}
p4user=`p4 -ztag info | grep "^\.\.\. userName" | awk '{print $3}'`
p4client=$JOB_NAME
echo "$ME: creating client..."
cat << ! | p4 client -i
client: $p4client
Owner: $p4user
Description:
Jenkins build workspace for Swarm CI needs
Root: $WORKSPACE
Options: noallwrite clobber nocompress unlocked nomodtime rmdir
SubmitOptions: submitunchanged
LineEnd: local
View:
$p4branch/... //$JOB_NAME/...
!
[ $? -ne 0 ] &&
exitFail "trouble creating client"
echo "$ME: client defined:"
p4 client -o $p4client | grep ^[^#] | tr '\t' ' '\
| sed -e "s,^, ,"
# sync the files
echo "$ME: reverting any open files..."
p4 -c $p4client revert -k //... || exitFail
echo "$ME: purging workspace..."
(cd $WORKSPACE && rm -fr *)
echo "$ME: determining how to sync..."
case "$SWARM_CHANGE_STATUS" in
shelved)
echo "$ME: quietly force-syncing to head..."
p4 -c $p4client sync -qf || exitFail
echo "$ME: unshelving [$SWARM_CHANGE]..."
p4 -c $p4client unshelve -s $SWARM_CHANGE || exitFail
p4 -c $p4client resolve -am || exitFail
p4 -c $p4client resolve -ay || exitFail
;;
submitted)
echo "$ME: quietly force-syncing to @$SWARM_CHANGE..."
p4 -c $p4client sync -qf @$SWARM_CHANGE || exitFail
;;
*)
exitFail "unknown change status [$SWARM_CHANGE_STATUS]"
;;
esac
# call the build
[ ! -r build.xml ] &&
exitFail "build.xml not present"
echo "$ME: calling [ant $ANT_TARGETS]..."
ant $ANT_TARGETS
RC=$?
# report build result
if [ $RC -eq 0 ]
then
exitGood
else
exitFail "build returned non-zero exit status [$RC]"
fi
# shouldn't get here
exit 99