Mercurial > bitten > bitten-test
changeset 269:51580a463e3e
Add `<c:cppunit>` recipe command, based on patch by Chandler Carruth and examples by Akos Maroy.
author | cmlenz |
---|---|
date | Fri, 07 Oct 2005 10:44:20 +0000 |
parents | 4a6545360c23 |
children | 76bfc58fc394 |
files | ChangeLog bitten/build/ctools.py bitten/build/javatools.py bitten/build/tests/__init__.py bitten/build/tests/ctools.py |
diffstat | 5 files changed, 163 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -9,14 +9,14 @@ * Improvements to the build status presentation in Trac. * Changes to the build recipe format. See the documentation on the web site for details. - * New recipe commands: <sh:pipe>, <c:configure>, <java:ant>, - <java:junit>, and <x:transform>. Various improvements to the - existing commands. + * New recipe commands: <sh:pipe>, <c:configure>, <c:cppunit>, + <java:ant>, <java:junit>, and <x:transform>. Various improvements to + the existing commands. * Recipe commands and command attributes in recipes can now reference slave configuration values. * The names of the master and slaves scripts have changed: `bittend` is now `bitten-master`, `bitten` is now `bitten-slave`. - * The build master can now handle multiple Trac environments (projects). + * The build master can now handle multiple Trac environments. * The build slave now by default removes any working directories when done. * Build configurations can now be completely deleted.
--- a/bitten/build/ctools.py +++ b/bitten/build/ctools.py @@ -55,3 +55,64 @@ returncode = shtools.execute(ctxt, executable='make', args=args) if returncode != 0: ctxt.error('make failed (%s)' % cmdline.returncode) + +def cppunit(ctxt, file_=None, srcdir=None): + """Collect CppUnit XML data.""" + assert file_, 'Missing required attribute "file"' + + try: + fileobj = file(ctxt.resolve(file_), 'r') + try: + total, failed = 0, 0 + results = xmlio.Fragment() + for group in xmlio.parse(fileobj): + if group.name not in ('FailedTests', 'SuccessfulTests'): + continue + for child in group.children(): + test = xmlio.Element('test') + name = child.children('Name').next().gettext() + if '::' in name: + parts = name.split('::') + test.attr['fixture'] = '::'.join(parts[:-1]) + name = parts[-1] + test.attr['name'] = name + + for location in child.children('Location'): + for file_elem in location.children('File'): + filepath = file_elem.gettext() + if srcdir is not None: + filepath = posixpath.join(srcdir, filepath) + test.attr['file'] = filepath + break + for line_elem in location.children('Line'): + test.attr['line'] = line_elem.gettext() + break + break + + if child.name == 'FailedTest': + for message in child.children('Message'): + test.append(xmlio.Element('traceback')[ + message.gettext() + ]) + test.attr['status'] = 'failure' + failed += 1 + else: + test.attr['status'] = 'success' + + results.append(test) + total += 1 + + if failed: + ctxt.error('%d of %d test%s failed' % (failed, total, + total != 1 and 's' or '')) + + ctxt.report('test', results) + + finally: + fileobj.close() + + except IOError, e: + log.warning('Error opening CppUnit results file (%s)', e) + except xmlio.ParseError, e: + print e + log.warning('Error parsing CppUnit results file (%s)', e)
--- a/bitten/build/javatools.py +++ b/bitten/build/javatools.py @@ -7,12 +7,12 @@ # you should have received as part of this distribution. The terms # are also available at http://bitten.cmlenz.net/wiki/License. +from glob import glob import logging import os -import tempfile +import posixpath import shlex -import posixpath -from glob import glob +import tempfile from bitten.build import CommandLine from bitten.util import xmlio @@ -91,7 +91,7 @@ test.attr['fixture'] = testcase.attr['classname'] if 'time' in testcase.attr: test.attr['duration'] = testcase.attr['time'] - if srcdir: + if srcdir is not None: cls = testcase.attr['classname'].split('.') test.attr['file'] = posixpath.join(srcdir, *cls) + \ '.java'
--- a/bitten/build/tests/__init__.py +++ b/bitten/build/tests/__init__.py @@ -9,12 +9,13 @@ import unittest -from bitten.build.tests import api, config, pythontools, xmltools +from bitten.build.tests import api, config, ctools, pythontools, xmltools def suite(): suite = unittest.TestSuite() suite.addTest(api.suite()) suite.addTest(config.suite()) + suite.addTest(ctools.suite()) suite.addTest(pythontools.suite()) suite.addTest(xmltools.suite()) return suite
new file mode 100644 --- /dev/null +++ b/bitten/build/tests/ctools.py @@ -0,0 +1,92 @@ +# -*- coding: iso8859-1 -*- +# +# Copyright (C) 2005 Christopher Lenz <cmlenz@gmx.de> +# All rights reserved. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at http://bitten.cmlenz.net/wiki/License. + +import os +import shutil +import tempfile +import unittest + +from bitten.build import ctools +from bitten.recipe import Context, Recipe + + +class CppUnitTestCase(unittest.TestCase): + + def setUp(self): + self.basedir = os.path.realpath(tempfile.mkdtemp()) + self.ctxt = Context(self.basedir) + + def tearDown(self): + shutil.rmtree(self.basedir) + + def test_missing_param_file(self): + self.assertRaises(AssertionError, ctools.cppunit, self.ctxt) + + def test_empty_summary(self): + cppunit_xml = file(self.ctxt.resolve('cppunit.xml'), 'w') + cppunit_xml.write("""<?xml version="1.0" encoding='utf-8' ?> +<TestRun> + <FailedTests> + <FailedTest id="2"> + <Name>HelloTest::secondTest</Name> + <FailureType>Assertion</FailureType> + <Location> + <File>HelloTest.cxx</File> + <Line>95</Line> + </Location> + <Message>assertion failed +- Expression: 2 == 3 +</Message> + </FailedTest> + </FailedTests> + <SuccessfulTests> + <Test id="1"> + <Name>HelloTest::firstTest</Name> + </Test> + <Test id="3"> + <Name>HelloTest::thirdTest</Name> + </Test> + </SuccessfulTests> + <Statistics> + <Tests>3</Tests> + <FailuresTotal>1</FailuresTotal> + <Errors>0</Errors> + <Failures>1</Failures> + </Statistics> +</TestRun>""") + cppunit_xml.close() + ctools.cppunit(self.ctxt, file_='cppunit.xml') + type, category, generator, xml = self.ctxt.output.pop() + self.assertEqual(Recipe.REPORT, type) + self.assertEqual('test', category) + + tests = list(xml.children) + self.assertEqual(3, len(tests)) + self.assertEqual('HelloTest', tests[0].attr['fixture']) + self.assertEqual('secondTest', tests[0].attr['name']) + self.assertEqual('failure', tests[0].attr['status']) + self.assertEqual('HelloTest.cxx', tests[0].attr['file']) + self.assertEqual('95', tests[0].attr['line']) + + self.assertEqual('HelloTest', tests[1].attr['fixture']) + self.assertEqual('firstTest', tests[1].attr['name']) + self.assertEqual('success', tests[1].attr['status']) + + self.assertEqual('HelloTest', tests[2].attr['fixture']) + self.assertEqual('thirdTest', tests[2].attr['name']) + self.assertEqual('success', tests[2].attr['status']) + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(CppUnitTestCase, 'test')) + return suite + +if __name__ == '__main__': + unittest.main(defaultTest='suite')