world leader in high performance signal processing
Trace: » set_up_cruisecontrol

cruisecontrol – a framework for continuous testing

What is cruisecontrol

cruisecontrol is a framework for a continuous build and testing process. It includes, but is not limited to, plugins for email notification, Ant, and SVN, etc.
We use cruisecontrol 2 main modules:

  • the build loop: core of the system, it triggers build cycles then notifies various listeners (users) using various publishing techniques. The trigger can be internal (scheduled or upon changes in a SCM) or external. It is configured in a xml file which maps the build cycles to certain tasks, thanks to a system of plugins. Depending on configuration, it may produce build artifacts.
  • the legacy reporting allows the users to browse the results of the builds and access the artifacts

Cruisecontrol finds bugs during development process, not at the last stage of testing.
Main page: http://cruisecontrol.sourceforge.net/index.html

Before doing the following steps, it is needed that you have good knowledge of cruisecontrol already, and have read the articles on its main page.

Set up cruisecontrol

  • Download cruisecontrol-xxx-2.x.zip from the website. CruiseControl homepage
  • cd /home/test/work, unzip the zip package.
    unzip cruisecontrol-xxx-2.x.zip
  • Follow the instructions in page: http://cruisecontrol.sourceforge.net/gettingstarted.html to build and install cruisecontrol.
  • cd /home/test/work/cruise/checkouts/. Check out the project svn source tree here, for example uclinux-dist project.
  • cd /home/test/work/cruise/, copy and edit config.xml, build-uclinux-dist.xml, checkouts/uclinux-dist/build.xml to fit into this testing.
    config.xml:
    <cruisecontrol>
        <project name="uclinux-dist" buildafterfailed="true">
            <plugin name="gforge"
             classname="org.gforge.cruisecontrol.publishers.GForgeSOAPExternalPublisher"
             host="blackfin.uclinux.org/" ssl="false"
            />
    
            <listeners>
                <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
            </listeners>
    
            <bootstrappers>
                <svnbootstrapper localWorkingCopy="checkouts/${project.name}" />
                <svnbootstrapper localWorkingCopy="checkouts/${project.name}/linux-2.6.x" />
            </bootstrappers>
    
            <modificationset quietperiod="10">
                <svn localWorkingCopy="checkouts/${project.name}"/>
                <svn localWorkingCopy="checkouts/${project.name}/linux-2.6.x" />
            </modificationset>
    
            <schedule interval="60">
                <ant anthome="/home/test/work/cruise/apache-ant-1.6.0" buildfile="build-uclinux-dist.xml" target="build" uselogger="true" usedebug="false" />
                
            </schedule>
    
            <log dir="logs/${project.name}"/>
    
            <publishers>
                <htmlemail mailhost="10.99.22.20"
                  returnaddress="grace.pan@analog.com"                
                  buildresultsurl="http://10.99.22.164:8080/cruisecontrol/buildresults/${project.name}"
                  skipusers="true" spamwhilebroken="true"
                  css="/home/test/work/cruise/reporting/jsp/webcontent/css/cruisecontrol.css"
                  xsldir="/home/test/work/cruise/reporting/jsp/webcontent/xsl"
                  logdir="logs/${project.name}">
                  <always address="uclinux-dist-test-notify@blackfin.uclinux.org"/>
                  <failure address="uclinux-dist-test-notify@blackfin.uclinux.org"/>
                </htmlemail>
                <artifactspublisher dest="logs/${project.name}" dir="test_scripts/${project.name}/logs/thisrun/test_summary"/>
                <ftppublisher destDir="cruisecontrol/${project.name}"
                              srcDir="logs/${project.name}"
                              targetHost="blackfin.uclinux.org"
                              targetUser="test"
                              targetPasswd=""/>
                <gforge projectId="17"
                         cruisecontrolId="5"
                         hash="JzL5PCUxfHCEBzNS6FLkAG9Rp0k="
                 />
    
         </publishers>
    
        </project>
    </cruisecontrol>

    build-uclinux-dist.xml

    <project name="build-uclinux-dist"
             default="build"
             basedir="checkouts/uclinux-dist">
      <target  name="build">
             <ant antfile="build.xml" target="build"/>
      </target>
    </project>

    checkouts/uclinux-dist/build.xml

    <!-- build the release -->
    <project name="uclinux-dist" default="build">
    
       <target name="build" >
            <exec dir="" executable="/bin/sh" os="Linux, Solaris, Mac OS X" >
                <arg value="../../test_scripts/uclinux-dist/run_kernel_test"/> //Here is the real script we need to run.
            </exec>
        </target>
    
    </project>
  • mkdir /home/test/work/cruise/test_scripts/uclinux-dist/, copy run_kernel_test over as the startup script from uclinux-dist source tree subfolder testsuites/test_scripts.
  • cd /home/test/work/cruise/, run ./main/bin/cruisecontrol.sh . It would use the config.xml in that folder to read the config params. The output is:
    Using Cruise Control at /home/test/work/cruise/main
    /usr/lib/jvm/java/bin/java -cp /usr/lib/jvm/java/lib/tools.jar:/home/test/work/cruise/main/dist/cruisecontrol.jar:/home/test/work/cruise/main/lib/log4j.jar:/home/test/work/cruise/main/lib/jdom.jar:/home/test/work/cruise/main/lib/ant/ant.jar:/home/test/work/cruise/main/lib/ant/ant-launcher.jar:/home/test/work/cruise/main/lib/xercesImpl-2.8.0.jar:/home/test/work/cruise/main/lib/xml-apis-2.8.0.jar:/home/test/work/cruise/main/lib/xmlrpc-2.0.1.jar:/home/test/work/cruise/main/lib/xalan-2.7.0.jar:/home/test/work/cruise/main/lib/serializer-2.7.0.jar:/home/test/work/cruise/main/lib/jakarta-oro-2.0.3.jar:/home/test/work/cruise/main/lib/mail.jar:/home/test/work/cruise/main/lib/junit.jar:/home/test/work/cruise/main/lib/activation.jar:/home/test/work/cruise/main/lib/commons-net-1.1.0.jar:/home/test/work/cruise/main/lib/starteam-sdk.jar:/home/test/work/cruise/main/lib/mx4j.jar:/home/test/work/cruise/main/lib/mx4j-tools.jar:/home/test/work/cruise/main/lib/mx4j-remote.jar:/home/test/work/cruise/main/lib/smack.jar:/home/test/work/cruise/main/lib/comm.jar:/home/test/work/cruise/main/lib/commons-logging.jar:/home/test/work/cruise/main/lib/x10.jar:/home/test/work/cruise/main/lib/fast-md5.jar:/home/test/work/cruise/main/lib/maven-embedder-2.0.3-dep.jar:/home/test/work/cruise/main/lib/axis.jar:/home/test/work/cruise/main/lib/jaxrpc.jar:/home/test/work/cruise/main/lib/wsdl4j-1.5.1.jar:/home/test/work/cruise/main/lib/commons-codec-1.3.jar:/home/test/work/cruise/main/lib/commons-discovery-0.2.jar:/home/test/work/cruise/main/lib/commons-httpclient-3.0-rc3.jar:/home/test/work/cruise/main/lib/crimson.jar:/home/test/work/cruise/main/lib/saaj.jar:/home/test/work/cruise/main/lib/gforge-external-publisher.jar:. -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder CruiseControl
    [cc]Jun-21 17:48:59 Main          - CruiseControl Version 2.5 Compiled on June 1 2007 1205
    [cc]Jun-21 17:48:59 LConfigManager- reading settings from config file [/home/test/work/cruise/config.xml]
    [cc]Jun-21 17:48:59 trolController- projectName = [uclinux-dist]
    [cc]Jun-21 17:48:59 trolController- No previously serialized project found [/home/test/work/cruise/uclinux-dist.ser], forcing a build.
    [cc]Jun-21 17:48:59 LConfigManager- using settings from config file [/home/test/work/cruise/config.xml]
    [cc]Jun-21 17:48:59 Project       - Project uclinux-dist starting
    [cc]Jun-21 17:48:59 Project       - Project uclinux-dist:  idle
    [cc]Jun-21 17:48:59 Project       - Project uclinux-dist started
    [cc]Jun-21 17:48:59 Project       - Project uclinux-dist:  in build queue
    [cc]Jun-21 17:48:59 BuildQueue    - BuildQueue started
  • The log files would be saved at test_scripts/uclinux-dist/logs and a part of it would be stored at logs/uclinux-dist/ which is needed by ftp publisher to upload to ftp server.
  • Add gforge jars if the result need to be reported to gfore website, like gforge-external-publisher.jar, and saaj.jar, etc.

Log of cruisecontrol

CruiseControl would generate log file of xml format,actually it is resulted from ANT system. Log20070615145327.xml:

<?xml version="1.0" encoding="UTF-8"?>

<cruisecontrol>
  <modifications>
    <modification type="svn">
        <file action="modified">
        <revision>5394</revision>
        <filename>/trunk/lib/ffmpeg/ffmpeg-svn-8891/libavutil/common.h</filename>
      </file>
      <date>06/12/2007 19:26:33</date>
      <user>mmh</user>
      <comment><![CDATA[[#3265] adding blackfin specific read_time profile support]]></comment>
      <revision>5394</revision>
    </modification>
    ….
 </modifications>
  <info>
    <property name="projectname" value="uclinux-dist" />
    <property name="lastbuild" value="20070612175012" />
    ……
    <property name="logdir" value="/home/test/work/cruise/logs/uclinux-dist" />
    <property name="logfile" value="log20070615145327.xml" />
  </info>
  <build time="20 minutes 1 second">
    <target name="build" time="20 minutes 1 second">
      <task location="/home/test/work/cruise/build-uclinux-dist.xml:5: " name="ant" time="20 minutes 1 second">
      <target name="build" time="20 minutes 0 seconds">
          <task location="/home/test/work/cruise/checkouts/uclinux-dist/build.xml:5: " name="exec" time="20 minutes 0 seconds">
            <message priority="info"><![CDATA[Here is the difference between lastrun and thisrun test results:]]></message>
            <message priority="info" />
            ……
            <message priority="info"><![CDATA[Building kernel that now fail, but passed before:]]></message>
         </task>
        </target>
      </task>
    </target>
  </build>
</cruisecontrol>

From the log file, it is seen 3 parts: modifications, info, build. So we can judge which check-in results in changes of the test log.
And it would be translated into HTML file by the xsl scripts under /home/test/work/cruise/reporting/jsp/webcontent/xsl, which could be read by Browsers or sent out as email.

Modify cruisecontrol

  • Since the original cruisecontrol doesn't know how to judge our testing results and give out notification, we add result judgement in cruise/main/src/net/sourceforge/cruisecontrol/util/XMLLogHelper.java:
    public boolean isBuildSuccessful() {
              String filename = "/home/test/work/cruise/test_scripts/uclinux-dist/logs/thisrun/test_summary/test_results";
              FileReader fr = null;
              try {
                fr = new FileReader(filename);
                BufferedReader br = new BufferedReader(fr);
                String line = null;
                String result = null;
                line = br.readLine();
                while (line != null) {
                    result = line.trim();
                    if (result.equals("success")) {
                        return true;
                    } else if (result.equals("failed")) {
                        return false;
                    } 
                }
                br.close();
                fr.close();
                } catch (IOException e) {
                e.printStackTrace();
                }
               return (log.getChild("build").getAttribute("error") == null);
        }
  • Add build.xsl to deal with <build> element of build log.

The xsl scripts to translate the xml log into html doesn't take much care of the <build> part in log, while we need it handled and shown in email, so create build.xsl according to the template of errors.xsl under cruise/reporting/jsp/webcontent/xsl. And then add it to buildresults.xsl :

 <xsl:import href=“build.xsl”/>
 …
 <p><xsl:apply-templates select=“$cruisecontrol.list” mode=“build” /></p> 

Complete Table of Contents/Topics