port python2.x code to python3.x
[tools/itest-core.git] / itest / main.py
1 import os
2 import sys
3 import argparse
4
5 try:
6     import unittest2 as unittest
7     from unittest2 import TextTestResult
8 except ImportError:
9     import unittest
10     from unittest import TextTestResult
11
12 from itest import conf
13 from itest.utils import makedirs
14 from itest.loader import TestLoader
15 from itest import __version__
16
17
18 ENVIRONMENT_VARIABLE = "ITEST_ENV_PATH"
19
20
21 def find_test_project_from_cwd():
22     '''
23     Returns test project root directory or None
24     '''
25     path = os.getcwd()
26     while 1:
27         name = os.path.join(path, 'settings.py')
28         if os.path.exists(name):
29             return path
30
31         if path == '/':
32             return
33         path = os.path.dirname(path)
34
35
36 class TestProgram(unittest.TestProgram):
37
38     def parseArgs(self, argv):
39         if len(argv) > 1 and argv[1].lower() == 'discover':
40             self._do_discovery(argv[2:])
41             return
42
43         parser = argparse.ArgumentParser()
44         parser.add_argument('-V', '--version', action='version',
45                             version=__version__)
46         parser.add_argument('-q', '--quiet', action='store_true',
47                             help="minimal output")
48         parser.add_argument('-v', '--verbose', action='count',
49                             help="verbose output")
50         parser.add_argument('-f', '--failfast', action='store_true',
51                             help="stop on the first failure")
52         parser.add_argument('-c', '--catch', action='store_true',
53                             help="catch ctrl-c and display results")
54         parser.add_argument('-b', '--buffer', action='store_true',
55                             help="buffer stdout and stderr during test runs")
56         parser.add_argument('tests', nargs='*')
57         parser.add_argument('--test-project-path',
58                             default=os.environ.get(ENVIRONMENT_VARIABLE),
59                             help='set test project path where settings.py '
60                             'locate. [%s]' % ENVIRONMENT_VARIABLE)
61         parser.add_argument('--test-workspace', type=os.path.abspath,
62                             help='set test workspace path')
63         parser.add_argument('--with-xunit', action='store_true',
64                             help='provides test resutls in standard XUnit XML '
65                             'format')
66         parser.add_argument('--xunit-file',
67                             type=os.path.abspath, default='xunit.xml',
68                             help='Path to xml file to store the xunit report.'
69                             'Default is xunit.xml in the working directory')
70
71         opts = parser.parse_args()
72
73         # super class options
74         if opts.quiet:
75             self.verbosity = 0
76         elif opts.verbose:
77             # default verbosity is 1
78             self.verbosity = opts.verbose + 1
79         self.failfast = opts.failfast
80         self.catchbreak = opts.catch
81         self.buffer = opts.buffer
82
83         # additional options
84         if opts.with_xunit:
85             if not os.access(os.path.dirname(opts.xunit_file), os.W_OK):
86                 print("Permission denied:", opts.xunit_file, file=sys.stderr)
87                 sys.exit(1)
88             from itest.result import XunitTestResult
89             self.testRunner.resultclass = XunitTestResult
90             self.testRunner.resultclass.xunit_file = opts.xunit_file
91         else:
92             self.testRunner.resultclass = TextTestResult
93
94         if opts.test_project_path:
95             conf.load_settings(opts.test_project_path)
96         else:
97             conf.load_settings(find_test_project_from_cwd())
98
99         conf.settings.verbosity = self.verbosity
100
101         if opts.test_workspace:
102             conf.settings.WORKSPACE = opts.test_workspace
103         makedirs(conf.settings.WORKSPACE)
104
105         # copy from super class
106         if len(opts.tests) == 0 and self.defaultTest is None:
107             # createTests will load tests from self.module
108             self.testNames = None
109         elif len(opts.tests) > 0:
110             self.testNames = opts.tests
111             if __name__ == '__main__':
112                 # to support python -m unittest ...
113                 self.module = None
114         else:
115             self.testNames = (self.defaultTest,)
116         self.createTests()
117
118
119 class TextTestRunner(unittest.TextTestRunner):
120
121     def __init__(self, stream=None, descriptions=True, verbosity=1,
122                  failfast=False, buffer=False, resultclass=None):
123         if stream is None:
124             stream = sys.stderr
125         super(TextTestRunner, self).__init__(stream, descriptions, verbosity,
126                                              failfast, buffer, resultclass)
127
128
129 def main():
130     import logging
131     logging.basicConfig()
132     TestProgram(testLoader=TestLoader(), testRunner=TextTestRunner)