Continuous Integration

From CDOT Wiki
Revision as of 21:43, 10 December 2010 by Minooz (talk | contribs) (Requirements)
Jump to: navigation, search

Continuous Integration Project for NexJ Express Code


Overview

Currently, NexJ has a Mercurial Repository (Internal) in which, the NexJ Express Server (Core) code is maintained with all its histories. NexJ is planning to share a Core Repository with the Open Source Community by creating a Repository (External) that will be kept in sync with the Internal Repository.


Requirements

Continuous Integration System

  1. Hudson
  2. Cruise Control
  3. Buildbot
  4. Apache Continuum
  5. Maven
  6. Anthill

Version Control Tool

  1. Mercurial
  2. CVS
  3. SVN
  4. Git

Scripting

A new ant script is created e.g. buildHudson.xml that triggers the target(assign1.test) of main build file(build.xml) of the project. See below:
<project name="assign1" basedir="." default="myTarget">
  <target name="assign1.build.call">
    <!-- Call the target that does everything -->
    <ant antfile="build.xml" target="assign1.test"/>
   </target>
  <target name="myTarget.check" depends="assign1.build.call">
    <echo>The assign1.build was called!</echo>
  </target>
</project>

Challenges

  • 1- I was receiving an error message while trying to do a new build on Hudson. It didn't let to clone the project on Hudson workspace. The error message is "Access is denied". So I had to delete the project and create a new one. Apparently one of the reasons is that Hudson doesn't let you queue the jobs. So, if you interrupt a job that is scheduled, you'll get the error message.
  • 2- To run a bash script to build the project, there are 2 ways:
Execute Windows Batch Command:
D:\cygwin\bin\bash /home/HudsonPrac/buildHudson.sh
Invoke an Ant Script
<project name="assign1" basedir=".">
	<target name="myTarget" >
		<exec executable="D:\cygwin\bin\bash" newenvironment="false">
		<arg value="/home/HudsonPrac/buildHudson.sh"/>
		</exec>
	</target>
</project>
  • 3- Since the bash script is running in Windows platform through Cygwin, there are some conflicts,

so the PATH was changed to: PATH=/usr/bin:$PATH Read more about some conflicts here

  • 4- If there was an error applying a patch to a repository e.g. hg import patch12.patch , there might be a problem with line numbers merging issue. So, there will be an error created with this message: "Hunk #1 Failed". There are some ways to remove the hunks manually or just ignore that patch, if the later versions are fixed.
By "hunk" I mean a "snippet of change", i.e. a part of the "diff". TortoiseHg uses this terminology and so does darcs. – Deniz Dogan
For Hunk Failed message, first we need to make sure it's not applied before. Second thing to check is that bases are the same. All the revisions before that new changeset even with failed build should be applied before applying the successfully built change-set.
  • 5- If there is an uncommited message, the script can not work properly, e.g. Rev is 18+. So, error should be displayed for the uncommited change-sets.
  • 6- To run JUnit Tests from command line:
add the JUnit installation directory and the junit.jar file and also QTjava to the CLASSPATH. e.g. CLASSPATH=".;D:\cygwin\home\java\junit3.0.1\junit.jar;C:\Program Files\java\jre6\lib\ext\QTjava"
to run a sample AllTests class go to the installation directory and run: java junit.textui.TestRunner junit.samples.AllTests
to run NexJ AllTests do:
build the model: go to ws/core/build/ run ant or ant -f build_JUnitTest.xml
from command line: go to ws/out/core/ run java junit.textui.TestRunner nexj.core.AllTests (getting error IOExcpetion) so we just ran one test file java junit.textui.TestRunner nexj.core.util.MathUtilTest (We did some changes to core/test/nexj/core/util to practice with it) Or we can run the ant target for test: ant -f build_JUnitTest.xml test
  • 7- Bugs after implementation at NexJ
Working with remote repository; getting tip and log from remote repository is not as simple as moving to local repo and get all the information we need.
NexJ Internal repo has several branches, and when cloning and pulling, we just needed to mention it as a default branch, to not to confuse revision numbers and latest changesets.
Since the decimal part of the revision number will keep changing from computer to computer, it was preferred to use the global hex chagesetID (GUID).
So, the first big change was adding this command to get the list of latest changesets up to the tip:
hg log ${IntDir} -r ${PrevRev}: -b default --template '{node}\n'
This number will also be added to the commit summary while importing the patch from Internal repo