Tuesday, November 20, 2007

Hudson embraces Python

A few months ago I started using Hudson for my XBMC TV.com scripts that are written in Python. The Hudson continuous integration server will retrieve the latest sources from subversion, package the sources into a zip file, run a few unit tests, analyze the source using pylint and then display the outcome in a easy navigated web-ui. You can see the result at http://hudson.ramfelt.se where the latest build is always accessible.

Python unit tests
Hudson supports JUnit report files, but unfortunately the py-unit framework does not support outputting the unit test results to an XML file. But thanks to
Sebastian Rittau, there is a unit test runner that will write the result into an XML file that can be parsed as a JUnit file. Using the xmlrunner.py when running my tests I can produce XML files that can be read by Hudson. So now for every commit or forced build the tests are executed and shown in a nice graph.


The python code looks like this:
suite = unittest.TestSuite([
unittest.TestLoader().loadTestsFromTestCase(ShowTestCase),
unittest.TestLoader().loadTestsFromTestCase(VideoTestCase),
])
if __name__ == '__main__':
runner = xmlrunner.XmlTestRunner(sys.stdout)
runner.run(suite)


In Hudson you must enable JUnit report files by checking the
"Publish JUnit test result report" and enter the path to the XML reports.


Python code analysis
Hudson supports the common Java analyzers such as PMD, FindBugs, CPD, checkstyle, etc. It didn't have any support for pylint, but thanks to a great plugin it was very easy to write a parser for pylint reports. Using this plugin, Hudson can now analyze my python files and show a nice trend graph on how many issues there are and for long. It will also produce a report for each file with code snippets to show where the issue is.



Ant target to create the pylint file (important that the pylint output is parseable)
<target name="report-pylint" depends="report-prepare">
<exec dir="${src.python}" executable="${pylint.binary}" output="${report.pylint}">
<env key="PYTHONPATH" path="${build.bin}:${build.bin}/lib/"/>
<arg line="-f parseable -i y TVcom.py tvguicontroller.py tvweb.py tv.py settingsmanager.py --output-format=parseable --ignore-comments=y --min-similarity-lines=4 --disable-msg=R0903 --disable-msg=C0301"/>
</exec>
</target>


Configuring the Violation plugin in Hudson looks like this:



Verification tests
I've also set up Hudson to run the verification tests when ever a build has been completed for the main XBMC TV Script job. This verification job will crawl through the www.tv.com web using the crawling sources to verify that there is no crashes because www.tv.com have changed the html format. This job takes a long time, up too 3-5 hours, and the result will be displayed in a nice trend graph as other unit tests. At the same time I can continue develop the next version and even build a new version while Hudson is running the verification job.


I must say that Hudson is a great CI tool, which works with Java, Python and C#. My favorite languages.