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 | |
---|
13 | """Recipe commands for tools commonly used in Mono projects.""" |
---|
14 | |
---|
15 | from glob import glob |
---|
16 | import logging |
---|
17 | import os |
---|
18 | import posixpath |
---|
19 | import shlex |
---|
20 | import tempfile |
---|
21 | |
---|
22 | from bitten.build import CommandLine |
---|
23 | from bitten.util import xmlio |
---|
24 | |
---|
25 | log = logging.getLogger('bitten.build.monotools') |
---|
26 | |
---|
27 | __docformat__ = 'restructuredtext en' |
---|
28 | |
---|
29 | |
---|
30 | def _parse_suite(element): |
---|
31 | for child in element.children('results'): |
---|
32 | testcases = list(child.children('test-case')) |
---|
33 | if testcases: |
---|
34 | yield element, testcases |
---|
35 | |
---|
36 | for xmlsuite in child.children('test-suite'): |
---|
37 | for suite in _parse_suite(xmlsuite): |
---|
38 | yield suite |
---|
39 | |
---|
40 | |
---|
41 | def _get_cases(fileobj): |
---|
42 | for testsuite in xmlio.parse(fileobj).children('test-suite'): |
---|
43 | for suite in _parse_suite(testsuite): |
---|
44 | yield suite |
---|
45 | |
---|
46 | |
---|
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 | """ |
---|
55 | assert file_, 'Missing required attribute "file"' |
---|
56 | try: |
---|
57 | total, failed = 0, 0 |
---|
58 | results = xmlio.Fragment() |
---|
59 | for path in glob(ctxt.resolve(file_)): |
---|
60 | fileobj = file(path, 'r') |
---|
61 | try: |
---|
62 | for suite, testcases in _get_cases(fileobj): |
---|
63 | for testcase in testcases: |
---|
64 | test = xmlio.Element('test') |
---|
65 | test.attr['fixture'] = suite.attr['name'] |
---|
66 | if 'time' in testcase.attr: |
---|
67 | test.attr['duration'] = testcase.attr['time'] |
---|
68 | if testcase.attr['executed'] == 'True': |
---|
69 | if testcase.attr['success'] != 'True': |
---|
70 | test.attr['status'] = 'failure' |
---|
71 | failure = list(testcase.children('failure')) |
---|
72 | if failure: |
---|
73 | stacktraceNode = list(failure[0].children('stack-trace')) |
---|
74 | if stacktraceNode: |
---|
75 | test.append(xmlio.Element('traceback')[ |
---|
76 | stacktraceNode[0].gettext() |
---|
77 | ]) |
---|
78 | failed += 1 |
---|
79 | else: |
---|
80 | test.attr['status'] = 'success' |
---|
81 | else: |
---|
82 | test.attr['status'] = 'ignore' |
---|
83 | |
---|
84 | results.append(test) |
---|
85 | total += 1 |
---|
86 | finally: |
---|
87 | fileobj.close() |
---|
88 | if failed: |
---|
89 | ctxt.error('%d of %d test%s failed' % (failed, total, |
---|
90 | total != 1 and 's' or '')) |
---|
91 | ctxt.report('test', results) |
---|
92 | except IOError, e: |
---|
93 | log.warning('Error opening NUnit results file (%s)', e) |
---|
94 | except xmlio.ParseError, e: |
---|
95 | log.warning('Error parsing NUnit results file (%s)', e) |
---|
96 | |
---|
97 | |
---|