1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 from __future__ import print_function
36
37
38
39
40 import os
41 import sys
42 import time
43 import unittest
44 import logging
45
46 import roslaunch
47 import rospkg
48 import rosgraph.roslogging
49
50 from rostest.rostestutil import createXMLRunner, printRostestSummary, \
51 xmlResultsFile, rostest_name_from_path
52 from rostest.rostest_parent import ROSTestLaunchParent
53
54 import rostest.runner
55
56 _NAME = 'rostest'
57
65
67
68 results_file_dir = os.path.dirname(results_file)
69 if not os.path.isdir(results_file_dir):
70 os.makedirs(results_file_dir)
71 with open(results_file, 'w') as f:
72 d = {'test': outname, 'test_file': test_file }
73 f.write("""<?xml version="1.0" encoding="UTF-8"?>
74 <testsuite tests="1" failures="1" time="1" errors="0" name="%(test)s">
75 <testcase name="test_ran" status="run" time="1" classname="Results">
76 <failure message="rostest file [%(test_file)s] does not exist" type=""/>
77 </testcase>
78 </testsuite>"""%d)
79
81 import roslaunch.rlutil
82
83 from optparse import OptionParser
84 parser = OptionParser(usage="usage: %prog [options] [package] <filename>", prog=_NAME)
85 parser.add_option("-t", "--text",
86 action="store_true", dest="text_mode", default=False,
87 help="Run with stdout output instead of XML output")
88 parser.add_option("--pkgdir", metavar="PKG_DIR",
89 dest="pkg_dir", default=None,
90 help="package dir")
91 parser.add_option("--package", metavar="PACKAGE",
92 dest="package", default=None,
93 help="package")
94 parser.add_option("--results-filename", metavar="RESULTS_FILENAME",
95 dest="results_filename", default=None,
96 help="results_filename")
97 (options, args) = parser.parse_args()
98 try:
99 args = roslaunch.rlutil.resolve_launch_arguments(args)
100 except roslaunch.core.RLException as e:
101 print(str(e), file=sys.stderr)
102 sys.exit(1)
103
104
105 logfile_name = configure_logging()
106 logger = logging.getLogger('rostest')
107 import roslaunch.core
108 roslaunch.core.add_printlog_handler(logger.info)
109 roslaunch.core.add_printerrlog_handler(logger.error)
110
111 logger.info('rostest starting with options %s, args %s'%(options, args))
112 if len(args) == 0:
113 parser.error("You must supply a test file argument to rostest.")
114 if len(args) != 1:
115 parser.error("rostest only accepts a single test file")
116
117
118 test_file = args[0]
119 if options.pkg_dir and options.package:
120
121
122 pkg_dir, pkg = options.pkg_dir, options.package
123 else:
124 pkg = rospkg.get_package_name(test_file)
125 r = rospkg.RosPack()
126 pkg_dir = r.get_path(pkg)
127
128 if options.results_filename:
129 outname = options.results_filename
130 if '.' in outname:
131 outname = outname[:outname.rfind('.')]
132 else:
133 outname = rostest_name_from_path(pkg_dir, test_file)
134
135
136 if not os.path.isfile(test_file):
137 results_file = xmlResultsFile(pkg, outname, True)
138 write_bad_filename_failure(test_file, results_file, outname)
139 parser.error("test file is invalid. Generated failure case result file in %s"%results_file)
140
141 try:
142 testCase = rostest.runner.createUnitTest(pkg, test_file)
143 suite = unittest.TestLoader().loadTestsFromTestCase(testCase)
144
145 if options.text_mode:
146 rostest.runner.setTextMode(True)
147 result = unittest.TextTestRunner(verbosity=2).run(suite)
148 else:
149 is_rostest = True
150 results_file = xmlResultsFile(pkg, outname, is_rostest)
151 xml_runner = createXMLRunner(pkg, outname, \
152 results_file=results_file, \
153 is_rostest=is_rostest)
154 result = xml_runner.run(suite)
155 finally:
156
157 test_parents = rostest.runner.getRostestParents()
158 for r in test_parents:
159 logger.info("finally rostest parent tearDown [%s]", r)
160 r.tearDown()
161 del test_parents[:]
162 from roslaunch.pmon import pmon_shutdown
163 logger.info("calling pmon_shutdown")
164 pmon_shutdown()
165 logger.info("... done calling pmon_shutdown")
166
167
168 config = rostest.runner.getConfig()
169 if config:
170 if config.config_errors:
171 print("\n[ROSTEST WARNINGS]"+'-'*62+'\n', file=sys.stderr)
172 for err in config.config_errors:
173 print(" * %s"%err, file=sys.stderr)
174 print('')
175
176
177 subtest_results = rostest.runner.getResults()
178 if not options.text_mode:
179 printRostestSummary(result, subtest_results)
180 else:
181 print("WARNING: overall test result is not accurate when --text is enabled")
182
183 if logfile_name:
184 print("rostest log file is in %s"%logfile_name)
185
186 if not result.wasSuccessful():
187 sys.exit(1)
188 elif subtest_results.num_errors or subtest_results.num_failures:
189 sys.exit(2)
190
191 if __name__ == '__main__':
192 rostestmain()
193