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