1# -*- coding: utf-8 -*-
2
3import argparse
4import functools
5import os
6import sys
7import unittest
8from fnmatch import fnmatchcase
9
10import system_tests
11
12
13class MyTestLoader(unittest.TestLoader):
14    testNamePatterns = None
15
16    def getTestCaseNames(self, testCaseClass):
17        """
18        Customize this code to allow you to filter test methods through testNamePatterns.
19        """
20        def shouldIncludeMethod(attrname):
21            if not attrname.startswith(self.testMethodPrefix):
22                return False
23            testFunc = getattr(testCaseClass, attrname)
24            if not callable(testFunc):
25                return False
26            return self.testNamePatterns is None or \
27                 any(fnmatchcase(attrname, pattern) for pattern in self.testNamePatterns)
28
29        testFnNames = list(filter(shouldIncludeMethod, dir(testCaseClass)))
30        if self.sortTestMethodsUsing:
31            testFnNames.sort(key=functools.cmp_to_key(self.sortTestMethodsUsing))
32        return testFnNames
33
34
35if __name__ == '__main__':
36    parser = argparse.ArgumentParser(description="The system test suite")
37    parser.add_argument(
38        "--config_file",
39        type=str,
40        nargs=1,
41        help="Path to the suite's configuration file",
42        default=['suite.conf']
43    )
44    parser.add_argument(
45        "--verbose", "-v",
46        action='count',
47        help="verbosity level",
48        default=1
49    )
50    parser.add_argument(
51        "--debug",
52        help="enable debugging output",
53        action='store_true'
54    )
55    parser.add_argument(
56        "dir_or_file",
57        help="root directory under which the testsuite searches for tests or a"
58        "single file which tests are run (defaults to the config file's"
59        "location)",
60        default=None,
61        type=str,
62        nargs='?'
63    )
64
65    args          = parser.parse_args()
66    if 'VERBOSE' in os.environ:
67        args.verbose = 2
68    conf_file     = args.config_file[0]
69    DEFAULT_ROOT  = os.path.abspath(os.path.dirname(conf_file))
70    system_tests.set_debug_mode(args.debug)
71    system_tests.configure_suite(conf_file)
72
73    testLoader = MyTestLoader()
74    testLoader.testMethodPrefix = ''
75    testLoader.testNamePatterns = ['test*', '*test']
76    if args.dir_or_file is None or os.path.isdir(args.dir_or_file):
77        discovered_tests = testLoader.discover(
78            args.dir_or_file or DEFAULT_ROOT
79        )
80    elif os.path.isfile(args.dir_or_file):
81        discovered_tests = testLoader.discover(
82            os.path.dirname(args.dir_or_file),
83            pattern=os.path.split(args.dir_or_file)[1],
84        )
85    else:
86        print(
87            "WARNING: Invalid search location, falling back to {!s}"
88            .format(DEFAULT_ROOT),
89            file=sys.stderr
90        )
91        discovered_tests = testLoader.discover(
92            DEFAULT_ROOT
93        )
94
95    test_res = unittest.runner.TextTestRunner(verbosity=args.verbose)\
96                              .run(discovered_tests)
97
98    sys.exit(0 if len(test_res.failures) + len(test_res.errors) == 0 else 1)
99