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 with_statement
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 roslib.packages
48 import roslib.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.baretest
55 import rostest.runner
56
57 _NAME = 'rostest'
58
66
68
69 results_file_dir = os.path.dirname(results_file)
70 if not os.path.isdir(results_file_dir):
71 os.makedirs(results_file_dir)
72 with open(results_file, 'w') as f:
73 d = {'test': outname, 'test_file': test_file }
74 f.write("""<?xml version="1.0" encoding="UTF-8"?>
75 <testsuite tests="1" failures="1" time="1" errors="0" name="%(test)s">
76 <testcase name="test_ran" status="run" time="1" classname="Results">
77 <failure message="rostest file [%(test_file)s] does not exist" type=""/>
78 </testcase>
79 </testsuite>"""%d)
80
82 import roslaunch.rlutil
83
84
85 logfile_name = configure_logging()
86 logger = logging.getLogger('rostest')
87 import roslaunch.core
88 roslaunch.core.add_printlog_handler(logger.info)
89 roslaunch.core.add_printerrlog_handler(logger.error)
90
91 from optparse import OptionParser
92 parser = OptionParser(usage="usage: %prog [options] [package] <filename>", prog=_NAME)
93 parser.add_option("-t", "--text",
94 action="store_true", dest="text_mode", default=False,
95 help="Run with stdout output instead of XML output")
96 parser.add_option("--bare",
97 action="store_true", dest="bare", default=False,
98 help="Run bare gtest-compatible executable instead of rostest")
99 parser.add_option("--bare-limit", metavar="TIME_LIMIT",
100 dest="bare_limit", default=60,
101 help="Set time limit for --bare executable")
102 parser.add_option("--bare-name", metavar="TEST_NAME",
103 dest="bare_name", default=None,
104 help="Test name for --bare executable")
105 parser.add_option("--pkgdir", metavar="PKG_DIR",
106 dest="pkg_dir", default=None,
107 help="package dir")
108 parser.add_option("--package", metavar="PACKAGE",
109 dest="package", default=None,
110 help="package")
111 (options, args) = parser.parse_args()
112 try:
113 if options.bare:
114
115 pass
116 else:
117 args = roslaunch.rlutil.resolve_launch_arguments(args)
118 except roslaunch.core.RLException, e:
119 print >> sys.stderr, str(e)
120 sys.exit(1)
121
122 logger.info('rostest starting with options %s, args %s'%(options, args))
123 if len(args) == 0:
124 parser.error("You must supply a test file argument to rostest.")
125 if len(args) != 1 and not options.bare:
126 parser.error("rostest only accepts a single test file")
127
128
129 test_file = args[0]
130 if options.pkg_dir and options.package:
131
132
133 pkg_dir, pkg = options.pkg_dir, options.package
134 else:
135 pkg_dir, pkg = roslib.packages.get_dir_pkg(test_file)
136
137 outname = rostest_name_from_path(pkg_dir, test_file)
138
139
140 if not options.bare and not os.path.isfile(test_file):
141 results_file = xmlResultsFile(pkg, outname, True)
142 write_bad_filename_failure(test_file, results_file, outname)
143 parser.error("test file is invalid. Generated failure case result file in %s"%results_file)
144
145 try:
146 if options.bare:
147
148 time_limit = float(options.bare_limit) if options.bare_limit else None
149 testCase = rostest.baretest.BareTestCase(test_file, args[1:],
150 rostest.runner.getResults(), retry=0,
151 time_limit=time_limit, test_name=options.bare_name,
152 package=pkg)
153 suite = unittest.TestSuite()
154 suite.addTest(testCase)
155
156
157 if options.bare_name:
158 outname = options.bare_name
159 else:
160 testCase = rostest.runner.createUnitTest(pkg, test_file)
161 suite = unittest.TestLoader().loadTestsFromTestCase(testCase)
162
163 if options.text_mode:
164 rostest.runner.setTextMode(True)
165 result = unittest.TextTestRunner(verbosity=2).run(suite)
166 else:
167 is_rostest = True
168 results_file = xmlResultsFile(pkg, outname, is_rostest)
169 xml_runner = createXMLRunner(pkg, outname, \
170 results_file=results_file, \
171 is_rostest=is_rostest)
172 result = xml_runner.run(suite)
173 finally:
174
175 test_parents = rostest.runner.getRostestParents()
176 for r in test_parents:
177 logger.info("finally rostest parent tearDown [%s]", r)
178 r.tearDown()
179 del test_parents[:]
180 from roslaunch.pmon import pmon_shutdown
181 logger.info("calling pmon_shutdown")
182 pmon_shutdown()
183 logger.info("... done calling pmon_shutdown")
184
185
186 config = rostest.runner.getConfig()
187 if config:
188 if config.config_errors:
189 print >> sys.stderr, "\n[ROSTEST WARNINGS]"+'-'*62+'\n'
190 for err in config.config_errors:
191 print >> sys.stderr, " * %s"%err
192 print ''
193
194
195 subtest_results = rostest.runner.getResults()
196 if not options.text_mode:
197 printRostestSummary(result, subtest_results)
198 else:
199 print "WARNING: overall test result is not accurate when --text is enabled"
200
201 if logfile_name:
202 print "rostest log file is in %s"%logfile_name
203
204 if not result.wasSuccessful():
205 sys.exit(1)
206 elif subtest_results.num_errors or subtest_results.num_failures:
207 sys.exit(2)
208
209 if __name__ == '__main__':
210 rostestmain()
211