Start porting our test scripts to Python. Add ctest support.
[metze/wireshark/wip.git] / test / test.py
1 #!/usr/bin/env python
2 #
3 # Wireshark tests
4 # By Gerald Combs <gerald@wireshark.org>
5 #
6 # Ported from a set of Bash scripts which were copyright 2005 Ulf Lamping
7 #
8 # SPDX-License-Identifier: GPL-2.0-or-later
9 #
10 '''Main test script'''
11
12 # To do:
13 # - Avoid printing Python tracebacks when we assert? It looks like we'd need
14 #   to override unittest.TextTestResult.addFailure().
15
16 import argparse
17 import config
18 import os.path
19 import sys
20 import unittest
21
22 def find_test_ids(suite, all_ids):
23     if hasattr(suite, '__iter__'):
24         for s in suite:
25             find_test_ids(s, all_ids)
26     else:
27         all_ids.append(suite.id())
28
29 def dump_failed_output(suite):
30     if hasattr(suite, '__iter__'):
31         for s in suite:
32             dump_failures = getattr(s, 'dump_failures', None)
33             if dump_failures:
34                 dump_failures()
35             else:
36                 dump_failed_output(s)
37
38 def main():
39     parser = argparse.ArgumentParser(description='Wireshark unit tests')
40     cap_group = parser.add_mutually_exclusive_group()
41     cap_group.add_argument('-e', '--enable-capture', action='store_true', help='Enable capture tests')
42     cap_group.add_argument('-E', '--disable-capture', action='store_true', help='Disable capture tests')
43     cap_group.add_argument('-i', '--capture-interface', nargs=1, default=None, help='Capture interface index or name')
44     parser.add_argument('-p', '--program-path', nargs=1, default=os.path.curdir, help='Path to Wireshark executables.')
45     list_group = parser.add_mutually_exclusive_group()
46     list_group.add_argument('-l', '--list', action='store_true', help='List tests. One of "all" or a full or partial test name.')
47     list_group.add_argument('--list-suites', action='store_true', help='List all suites.')
48     list_group.add_argument('--list-cases', action='store_true', help='List all suites and cases.')
49     parser.add_argument('-v', '--verbose', action='store_const', const=2, default=1, help='Verbose tests.')
50     parser.add_argument('tests_to_run', nargs='*', metavar='test', default=['all'], help='Tests to run. One of "all" or a full or partial test name. Default is "all".')
51     args = parser.parse_args()
52
53     if args.enable_capture:
54         config.setCanCapture(True)
55     elif args.disable_capture:
56         config.setCanCapture(False)
57
58     if args.capture_interface:
59         config.setCaptureInterface(args.capture_interface[0])
60
61     all_tests = unittest.defaultTestLoader.discover(os.path.dirname(__file__), pattern='suite_*.py')
62
63     all_ids = []
64     find_test_ids(all_tests, all_ids)
65
66     run_ids = []
67     for tid in all_ids:
68         for ttr in args.tests_to_run:
69             ttrl = ttr.lower()
70             if ttrl == 'all':
71                 run_ids = all_ids
72                 break
73             if ttrl in tid.lower():
74                 run_ids.append(tid)
75
76     if not run_ids:
77         print('No tests found. You asked for:\n  ' + '\n  '.join(args.tests_to_run))
78         parser.print_usage()
79         sys.exit(1)
80
81     if args.list:
82         print('\n'.join(run_ids))
83         sys.exit(0)
84
85     if args.list_suites:
86         suites = set()
87         for rid in run_ids:
88             rparts = rid.split('.')
89             suites |= {rparts[0]}
90         print('\n'.join(list(suites)))
91         sys.exit(0)
92
93     if args.list_cases:
94         cases = set()
95         for rid in run_ids:
96             rparts = rid.split('.')
97             cases |= {'.'.join(rparts[:2])}
98         print('\n'.join(list(cases)))
99         sys.exit(0)
100
101     program_path = args.program_path[0]
102     if not config.setProgramPath(program_path):
103         print('One or more required executables not found at {}\n'.format(program_path))
104         parser.print_usage()
105         sys.exit(1)
106
107     run_suite = unittest.defaultTestLoader.loadTestsFromNames(run_ids)
108     runner = unittest.TextTestRunner(verbosity=args.verbose)
109     test_result = runner.run(run_suite)
110
111     dump_failed_output(run_suite)
112
113     if test_result.errors:
114         sys.exit(2)
115
116     if test_result.failures:
117         sys.exit(1)
118
119 if __name__ == '__main__':
120     main()