11 from __future__
import print_function
16 from urlparse
import urlparse
23 from loggers
import printlog, printlogerr
24 from test_parent
import RoconTestLaunchParent
30 _DEFAULT_TEST_PORT = 22422
31 _results = rosunit.junitxml.Result(
'rocon_test', 0, 0, 0)
41 _results.accumulate(results)
65 global _test_parents, _config
66 _test_parents.append(runner)
67 _config = runner.config
80 Provides configuration details for a rocon test launch configuration 81 associated with a single master. 83 :param launcher: a roslaunch test configuration 84 :type launcher: :class:`rocon_launch.RosLaunchConfiguration` 90 self.
configuration = roslaunch.parent.load_config_default([launcher.path], launcher.port)
96 Function that becomes TestCase.setUp() 98 For each launcher representing a launch on a single master in the rocon 99 launcher, this makes sure there is an entity that is to be the 'parent' 100 who will later be responsible for shutting everything down. 102 This could be prone to problems if someone puts multiple test launchers in 103 rocon launcher with the same master port (untested). 109 for rocon_launch_configuration
in self.rocon_launch_configurations:
110 config = rocon_launch_configuration.configuration
111 launcher = rocon_launch_configuration.launcher
112 o = urlparse(config.master.uri)
113 if o.port
not in uuids.keys():
114 uuids[o.port] = roslaunch.core.generate_run_id()
116 rocon_launch_configuration.parent = roslaunch.parent.ROSLaunchParent(
125 rocon_launch_configuration.parent._load_config()
126 rocon_launch_configuration.parent.start()
127 printlog(
"Launch Parent - type ...............ROSLaunchParent")
129 rocon_launch_configuration.parent = RoconTestLaunchParent(uuids[o.port], config, [launcher.path], port=o.port)
130 rocon_launch_configuration.parent.setUp()
135 printlog(
"Launch Parent - type ...............ROSTestLaunchParent")
136 printlog(
"Launch Parent - run id..............%s" % rocon_launch_configuration.parent.run_id)
137 printlog(
"Launch Parent - launcher............%s" % rocon_launch_configuration.launcher.path)
138 printlog(
"Launch Parent - port................%s" % o.port)
140 printlog(
"Launch Parent - tests...............no")
142 printlog(
"Launch Parent - tests...............yes")
147 Function that becomes TestCase.tearDown() 149 for rocon_launch_configuration
in self.rocon_launch_configurations:
150 config = rocon_launch_configuration.configuration
151 parent = rocon_launch_configuration.parent
152 launcher = rocon_launch_configuration.launcher
154 raw_input(
"Press Enter to continue...")
156 printlog(
"Tear Down - launcher..........................%s" % launcher.path)
158 printlog(
"Tear Down - tests..............................%s" % [test.test_name
for test
in config.tests])
161 printlog(
"Tear Down - run id............................%s" % parent.run_id)
169 print(
"Duplicate tests named [%s] in rostest suite" % test_name)
170 self.fail(
"Duplicate tests named [%s] in rostest suite" % test_name)
176 print(message, file=sys.stderr)
183 Test function generator that takes in a roslaunch Test object and 184 returns a class instance method that runs the test. TestCase 185 setUp() is responsible for ensuring that the rest of the roslaunch 186 state is correct and tearDown() is responsible for tearing 187 everything down cleanly. 189 :param test: ros test to run 190 :type test: :class:`.RoconTestLaunchConfiguration` 191 :returns: function object to run testObj 200 parent = test_launch_configuration.parent
201 self.assert_(parent
is not None,
"ROSTestParent initialization failed")
202 test_name = test.test_name
203 printlog(
" name..............................%s" % test_name)
208 unused_succeeded, failed = parent.launch()
209 self.assert_(
not failed,
"Test Fixture Nodes %s failed to launch" % failed)
213 test_file = rosunit.xml_results_file(test_pkg, test_name,
False)
214 printlog(
" test results file.................%s", test_file)
215 if os.path.exists(test_file):
217 printlog(
" clear old test results file.......done")
223 XML_OUTPUT_FLAG =
'--gtest_output=xml:' 224 test.args =
"%s %s%s" % (test.args, XML_OUTPUT_FLAG, test_file)
226 test.output =
'screen' 227 test.args = test.args +
" --text" 230 printlog(
"Running test %s" % test_name)
231 timeout_failure =
False 233 parent.run_test(test)
234 except roslaunch.launch.RLTestTimeoutException
as unused_e:
236 timeout_failure =
True 240 if not timeout_failure:
241 printlog(
"test finished [%s]" % test_name)
245 if not _text_mode
or timeout_failure:
246 if not timeout_failure:
247 self.assert_(os.path.isfile(test_file),
"test [%s] did not generate test results" % test_name)
248 printlog(
"test [%s] results are in [%s]", test_name, test_file)
249 results = rosunit.junitxml.read(test_file, test_name)
250 test_fail = results.num_errors
or results.num_failures
253 if test.retry > 0
and test_fail:
255 printlog(
"test [%s] failed, retrying. Retries left: %s" % (test_name, test.retry))
261 printlog(
"test [%s] results summary: %s errors, %s failures, %s tests",
262 test_name, results.num_errors, results.num_failures, results.num_tests)
269 printlog(
"test done [%s]", test_name)
275 Constructs the python unit test class. 277 @param rocon_launcher : absolute path to the rocon test launcher 278 @param launchers : list of individual launcher configurations (name, path, port etc) in rocon_launcher 279 @return unittest.TestCase : unit test class 281 rocon_launch_configurations = []
282 for launcher
in launchers:
285 classdict = {
'setUp': setUp,
'tearDown': tearDown,
286 'rocon_launch_configurations': rocon_launch_configurations,
287 'test_file': rocon_launcher}
291 for rocon_launch_configuration
in rocon_launch_configurations:
292 config = rocon_launch_configuration.configuration
293 for test
in config.tests:
297 rp = rospkg.RosPack()
298 cmd = roslib.packages.find_node(test.package, test.type, rp)
300 err_msg =
"Test node [%s/%s] does not exist or is not executable" % (test.package, test.type)
301 except rospkg.ResourceNotFound:
302 err_msg =
"Package [%s] for test node [%s/%s] does not exist" % (test.package, test.package, test.type)
304 test_name =
'test%s' % (test.test_name)
306 classdict[test_name] =
fail_runner(test.test_name, err_msg)
307 elif test_name
in test_names:
310 classdict[test_name] =
rocon_test_runner(test, rocon_launch_configuration, launcher.package)
311 test_names.append(test_name)
314 return type(
'RoconTest', (unittest.TestCase,), classdict)
def create_unit_rocon_test(rocon_launcher, launchers)
def fail_duplicate_runner(test_name)
generate test failure if tests with same name in launch file
def fail_runner(test_name, message)
def _accumulate_results(results)
def printlogerr(msg, args)
def _add_rocon_test_parent(runner)
def __init__(self, launcher)
def rocon_test_runner(test, test_launch_configuration, test_pkg)
def get_rocon_test_parents()