| 1 | # -*- coding: utf-8 -*- |
---|
| 2 | # |
---|
| 3 | # Copyright (C) 2005-2007 Christopher Lenz <cmlenz@gmx.de> |
---|
| 4 | # Copyright (C) 2006 Matthew Good <matt@matt-good.net> |
---|
| 5 | # Copyright (C) 2007-2010 Edgewall Software |
---|
| 6 | # Copyright (C) 2009 Grzegorz Sobanski <silk@boktor.net> |
---|
| 7 | # All rights reserved. |
---|
| 8 | # |
---|
| 9 | # This software is licensed as described in the file COPYING, which |
---|
| 10 | # you should have received as part of this distribution. The terms |
---|
| 11 | # are also available at http://bitten.edgewall.org/wiki/License. |
---|
| 12 | |
---|
1 | 13 | """Recipe commands for tools commonly used in Mono projects.""" |
---|
| 14 | |
---|
1 | 15 | from glob import glob |
---|
1 | 16 | import logging |
---|
1 | 17 | import os |
---|
1 | 18 | import posixpath |
---|
1 | 19 | import shlex |
---|
1 | 20 | import tempfile |
---|
| 21 | |
---|
1 | 22 | from bitten.build import CommandLine |
---|
1 | 23 | from bitten.util import xmlio |
---|
| 24 | |
---|
1 | 25 | log = logging.getLogger('bitten.build.monotools') |
---|
| 26 | |
---|
1 | 27 | __docformat__ = 'restructuredtext en' |
---|
| 28 | |
---|
| 29 | |
---|
1 | 30 | def _parse_suite(element): |
---|
10 | 31 | for child in element.children('results'): |
---|
5 | 32 | testcases = list(child.children('test-case')) |
---|
5 | 33 | if testcases: |
---|
3 | 34 | yield element, testcases |
---|
| 35 | |
---|
7 | 36 | for xmlsuite in child.children('test-suite'): |
---|
4 | 37 | for suite in _parse_suite(xmlsuite): |
---|
2 | 38 | yield suite |
---|
| 39 | |
---|
| 40 | |
---|
1 | 41 | def _get_cases(fileobj): |
---|
7 | 42 | for testsuite in xmlio.parse(fileobj).children('test-suite'): |
---|
6 | 43 | for suite in _parse_suite(testsuite): |
---|
3 | 44 | yield suite |
---|
| 45 | |
---|
| 46 | |
---|
1 | 47 | def nunit(ctxt, file_=None): |
---|
| 48 | """Extract test results from a NUnit XML report. |
---|
| 49 | |
---|
| 50 | :param ctxt: the build context |
---|
| 51 | :type ctxt: `Context` |
---|
| 52 | :param file\_: path to the NUnit XML test results; may contain globbing |
---|
| 53 | wildcards for matching multiple results files |
---|
| 54 | """ |
---|
5 | 55 | assert file_, 'Missing required attribute "file"' |
---|
4 | 56 | try: |
---|
4 | 57 | total, failed = 0, 0 |
---|
4 | 58 | results = xmlio.Fragment() |
---|
8 | 59 | for path in glob(ctxt.resolve(file_)): |
---|
4 | 60 | fileobj = file(path, 'r') |
---|
4 | 61 | try: |
---|
7 | 62 | for suite, testcases in _get_cases(fileobj): |
---|
6 | 63 | for testcase in testcases: |
---|
3 | 64 | test = xmlio.Element('test') |
---|
3 | 65 | test.attr['fixture'] = suite.attr['name'] |
---|
3 | 66 | if 'time' in testcase.attr: |
---|
3 | 67 | test.attr['duration'] = testcase.attr['time'] |
---|
3 | 68 | if testcase.attr['executed'] == 'True': |
---|
3 | 69 | if testcase.attr['success'] != 'True': |
---|
1 | 70 | test.attr['status'] = 'failure' |
---|
1 | 71 | failure = list(testcase.children('failure')) |
---|
1 | 72 | if failure: |
---|
1 | 73 | stacktraceNode = list(failure[0].children('stack-trace')) |
---|
1 | 74 | if stacktraceNode: |
---|
1 | 75 | test.append(xmlio.Element('traceback')[ |
---|
1 | 76 | stacktraceNode[0].gettext() |
---|
1 | 77 | ]) |
---|
1 | 78 | failed += 1 |
---|
1 | 79 | else: |
---|
2 | 80 | test.attr['status'] = 'success' |
---|
2 | 81 | else: |
---|
0 | 82 | test.attr['status'] = 'ignore' |
---|
| 83 | |
---|
3 | 84 | results.append(test) |
---|
3 | 85 | total += 1 |
---|
3 | 86 | finally: |
---|
4 | 87 | fileobj.close() |
---|
4 | 88 | if failed: |
---|
1 | 89 | ctxt.error('%d of %d test%s failed' % (failed, total, |
---|
1 | 90 | total != 1 and 's' or '')) |
---|
4 | 91 | ctxt.report('test', results) |
---|
0 | 92 | except IOError, e: |
---|
0 | 93 | log.warning('Error opening NUnit results file (%s)', e) |
---|
0 | 94 | except xmlio.ParseError, e: |
---|
0 | 95 | log.warning('Error parsing NUnit results file (%s)', e) |
---|
| 96 | |
---|
| 97 | |
---|