Swarm 2014.1: User Guide

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.

  1. Visit your project page.

  2. Project Edit button Click Edit. The Edit Project page is displayed.

  3. The Enable Automated Tests checkbox Click the Enable checkbox next to Automated Tests to display the Automated Tests configuration fields:

    The Automated Tests configuration fields

  4. 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

  1. Configure a Jenkins project:

    1. 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

    2. Select None for the Source Code Management section

    3. Define a Built Trigger section:

      1. Check Trigger builds remotely (e.g., from scripts)

      2. Enter a JIRA authentication token value (see YOURTOKEN below)

    4. 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.

  2. 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.

  3. 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 and SWARM_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 the SWARM_SUCCESS_URL or SWARM_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
0 matching pages