-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix bond handling during nodelet unloading (#51)
* add test whether bond breaking on unload works (tests #50) * disable callback for broken bond when we are breaking it This avoids the nodelet::LoaderROS::unload() method to be called twice for the same nodelet, causing an error output. * use AsyncSpinner for nodelet load in order for the shutdown procedure to work During shutdown, the bonds still need to communicate their status in order for the nodelet to properly/cleanly/quickly unload. This requires the node to spin. * add test whether LoaderROS::unload() is called twice (tests #50)
- Loading branch information
1 parent
6b6db1c
commit 6dcff94
Showing
8 changed files
with
153 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
log4j.logger.ros=DEBUG |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<launch> | ||
<env name="ROSCONSOLE_CONFIG_FILE" value="$(find test_nodelet)/debug_logging.conf"/> | ||
<test test-name="test_bond_break_on_shutdown" pkg="test_nodelet" type="test_bond_break_on_shutdown.py" /> | ||
</launch> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#!/usr/bin/env python | ||
|
||
import roslib; roslib.load_manifest('test_nodelet') | ||
import rospy | ||
import unittest | ||
import rostest | ||
import signal | ||
import subprocess | ||
import time | ||
|
||
from nodelet.srv import * | ||
|
||
class TestBondBreakOnShutdown(unittest.TestCase): | ||
def test_bond_break_on_shutdown(self): | ||
''' | ||
Test that the bond is broken cleanly when closing a nodelet loader (#50). | ||
This relies on a debug message printed by the bondcpp package in case | ||
of error. | ||
''' | ||
|
||
# start nodelet manager | ||
proc_manager = subprocess.Popen(["rosrun", "nodelet", "nodelet", "manager", "__name:=nodelet_manager"], | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
bufsize=-1 | ||
) | ||
|
||
# wait for nodelet manager to be ready | ||
try: | ||
rospy.wait_for_service('/nodelet_manager/load_nodelet', timeout=2) | ||
except: | ||
self.fail("Could not determine that nodelet manager has started") | ||
|
||
# load a nodelet | ||
proc_nodelet = subprocess.Popen(["rosrun", "nodelet", "nodelet", "load", "test_nodelet/Plus", "nodelet_manager", "__name:=test"], | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
bufsize=-1 | ||
) | ||
|
||
# wait for it to be ready | ||
try: | ||
rospy.wait_for_service('test/get_loggers', timeout=2) | ||
except: | ||
self.fail("Could not determine that nodelet has started") | ||
time.sleep(1) | ||
|
||
# stop the nodelet loader via signal (similar to roslaunch killing it) | ||
proc_nodelet.send_signal(signal.SIGINT) | ||
(n_out, n_err) = proc_nodelet.communicate() | ||
|
||
# stop the nodelet manager, too | ||
proc_manager.send_signal(signal.SIGINT) | ||
(m_out, m_err) = proc_manager.communicate() | ||
|
||
# check that nodelet unloaded and there was no error with bond breaking | ||
self.assertIn('Unloading nodelet /test from manager nodelet_manager', n_out) | ||
self.assertNotIn('Bond failed to break on destruction', m_out) | ||
self.assertNotIn('Bond failed to break on destruction', n_out) | ||
|
||
if __name__ == '__main__': | ||
rospy.init_node('test_bond_break_on_shutdown') | ||
rostest.unitrun('test_bond_break_on_shutdown', 'test_bond_break_on_shutdown', TestBondBreakOnShutdown) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<launch> | ||
<test test-name="unload_called_twice" pkg="test_nodelet" type="test_unload_called_twice.py" /> | ||
</launch> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#!/usr/bin/env python | ||
|
||
import roslib; roslib.load_manifest('test_nodelet') | ||
import rospy | ||
import unittest | ||
import rostest | ||
import signal | ||
import subprocess | ||
import time | ||
|
||
from nodelet.srv import * | ||
|
||
class TestUnloadCalledTwice(unittest.TestCase): | ||
def test_unload_called_twice(self): | ||
''' | ||
Test that when a nodelet loader is stopped and requests unloading, | ||
the unload() call in LoaderROS is not run twice (#50). | ||
''' | ||
|
||
# start nodelet manager | ||
proc_manager = subprocess.Popen(["rosrun", "nodelet", "nodelet", "manager", "__name:=nodelet_manager"], | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
bufsize=-1 | ||
) | ||
|
||
# wait for nodelet manager to be ready | ||
try: | ||
rospy.wait_for_service('/nodelet_manager/load_nodelet', timeout=2) | ||
except: | ||
self.fail("Could not determine that nodelet manager has started") | ||
|
||
# load nodelet | ||
proc_nodelet = subprocess.Popen(["rosrun", "nodelet", "nodelet", "load", "test_nodelet/Plus", "nodelet_manager", "__name:=test"], | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE | ||
) | ||
|
||
# wait for nodelet to be ready | ||
try: | ||
rospy.wait_for_service('test/get_loggers', timeout=2) | ||
except: | ||
self.fail("Could not determine that nodelet has started") | ||
time.sleep(1) | ||
|
||
# stop the nodelet loader via signal (similar to roslaunch killing it) | ||
proc_nodelet.send_signal(signal.SIGINT) | ||
(n_out, n_err) = proc_nodelet.communicate() | ||
|
||
# stop the nodelet manager, too | ||
proc_manager.send_signal(signal.SIGINT) | ||
(m_out, m_err) = proc_manager.communicate() | ||
|
||
# check that nodelet unloaded and that LoaderROS::unload() does not | ||
# complain about nodelet not being found (an indication that it was called | ||
# again after the nodelet was already unloaded) | ||
self.assertIn('Unloading nodelet /test from manager nodelet_manager', n_out) | ||
self.assertNotIn('Failed to find nodelet with name', m_err) | ||
|
||
if __name__ == '__main__': | ||
rospy.init_node('test_unload_called_twice') | ||
rostest.unitrun('test_unload_called_twice', 'test_unload_called_twice', TestUnloadCalledTwice) |