c06a03a827f5580c49eb43ff386ab3b70c1c8429
[rusty/samba.git] / lib / subunit / filters / subunit-filter
1 #!/usr/bin/env python
2 #  subunit: extensions to python unittest to get test results from subprocesses.
3 #  Copyright (C) 2008  Robert Collins <robertc@robertcollins.net>
4 #            (C) 2009  Martin Pool
5 #
6 #  Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
7 #  license at the users choice. A copy of both licenses are available in the
8 #  project source as Apache-2.0 and BSD. You may not use this file except in
9 #  compliance with one of these two licences.
10 #  
11 #  Unless required by applicable law or agreed to in writing, software
12 #  distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
13 #  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14 #  license you chose for the specific language governing permissions and
15 #  limitations under that license.
16 #
17
18 """Filter a subunit stream to include/exclude tests.
19
20 The default is to strip successful tests.
21
22 Tests can be filtered by Python regular expressions with --with and --without,
23 which match both the test name and the error text (if any).  The result
24 contains tests which match any of the --with expressions and none of the
25 --without expressions.  For case-insensitive matching prepend '(?i)'.
26 Remember to quote shell metacharacters.
27 """
28
29 from optparse import OptionParser
30 import sys
31 import unittest
32 import re
33
34 from subunit import (
35     DiscardStream,
36     ProtocolTestCase,
37     TestProtocolClient,
38     )
39 from subunit.test_results import TestResultFilter
40
41 parser = OptionParser(description=__doc__)
42 parser.add_option("--error", action="store_false",
43     help="include errors", default=False, dest="error")
44 parser.add_option("-e", "--no-error", action="store_true",
45     help="exclude errors", dest="error")
46 parser.add_option("--failure", action="store_false",
47     help="include failures", default=False, dest="failure")
48 parser.add_option("-f", "--no-failure", action="store_true",
49     help="include failures", dest="failure")
50 parser.add_option("--no-passthrough", action="store_true",
51     help="Hide all non subunit input.", default=False, dest="no_passthrough")
52 parser.add_option("-s", "--success", action="store_false",
53     help="include successes", dest="success")
54 parser.add_option("--no-skip", action="store_true",
55     help="exclude skips", dest="skip")
56 parser.add_option("--no-success", action="store_true",
57     help="exclude successes", default=True, dest="success")
58 parser.add_option("-m", "--with", type=str,
59     help="regexp to include (case-sensitive by default)",
60     action="append", dest="with_regexps")
61 parser.add_option("--without", type=str,
62     help="regexp to exclude (case-sensitive by default)",
63     action="append", dest="without_regexps")
64
65 (options, args) = parser.parse_args()
66
67
68 def _compile_re_from_list(l):
69     return re.compile("|".join(l), re.MULTILINE)
70
71
72 def _make_regexp_filter(with_regexps, without_regexps):
73     """Make a callback that checks tests against regexps.
74
75     with_regexps and without_regexps are each either a list of regexp strings,
76     or None.
77     """
78     with_re = with_regexps and _compile_re_from_list(with_regexps)
79     without_re = without_regexps and _compile_re_from_list(without_regexps)
80
81     def check_regexps(test, outcome, err, details):
82         """Check if this test and error match the regexp filters."""
83         test_str = str(test) + outcome + str(err) + str(details)
84         if with_re and not with_re.search(test_str):
85             return False
86         if without_re and without_re.search(test_str):
87             return False
88         return True
89     return check_regexps
90
91
92 regexp_filter = _make_regexp_filter(options.with_regexps,
93         options.without_regexps)
94 result = TestProtocolClient(sys.stdout)
95 result = TestResultFilter(result, filter_error=options.error,
96     filter_failure=options.failure, filter_success=options.success,
97     filter_skip=options.skip,
98     filter_predicate=regexp_filter)
99 if options.no_passthrough:
100     passthrough_stream = DiscardStream()
101 else:
102     passthrough_stream = None
103 test = ProtocolTestCase(sys.stdin, passthrough=passthrough_stream)
104 test.run(result)
105 sys.exit(0)