class TestGraph(unittest.TestCase): def setUp(self): rospy.init_node('test_graph') self.graph = Graph() def test_graph(self): flips = None while not flips: printtest("Waiting for flips") self.graph.update() flips = self.graph._local_gateway.flip_watchlist rospy.rostime.wallsleep(0.2) printtest("********************************************************************") printtest("* Local Gateway") printtest("********************************************************************") printtest("%s" % self.graph._local_gateway) self.assertEquals("5", str(len(flips))) # TODO: this is currently returning the base name, is should be returning the hash name self.assertEquals(len([flip for flip in flips if flip.gateway == "remote_gateway" and flip.rule.name == "/add_two_ints" and flip.rule.type == "service"]), 1) self.assertEquals(len([flip for flip in flips if flip.gateway == "remote_gateway" and flip.rule.name == "/chatter" and flip.rule.type == "publisher"]), 1) self.assertEquals(len([flip for flip in flips if flip.gateway == "remote_gateway" and flip.rule.name == "/chatter" and flip.rule.type == "subscriber"]), 1) self.assertEquals(len([flip for flip in flips if flip.gateway == "remote_gateway" and flip.rule.name == "/fibonacci" and flip.rule.type == "action_server"]), 1) self.assertEquals(len([flip for flip in flips if flip.gateway == "remote_gateway" and flip.rule.name == "/fibonacci" and flip.rule.type == "action_client"]), 1) printtest("********************************************************************") printtest("* Remote Gateway") printtest("********************************************************************") printtest("%s" % self.graph._remote_gateways) for remote_gateway in self.graph._remote_gateways: self.assertEquals("remote_gateway", rocon_gateway_utils.gateway_basename(remote_gateway.name)) def tearDown(self): pass
class TestGraph(unittest.TestCase): def setUp(self): rospy.init_node('test_graph') self.graph = Graph() def test_graph(self): flips = None while not flips: printtest("Waiting for flips") self.graph.update() flips = self.graph._local_gateway.flip_watchlist rospy.sleep(0.2) printtest( "********************************************************************" ) printtest("* Local Gateway") printtest( "********************************************************************" ) printtest("%s" % self.graph._local_gateway) self.assertEquals("1", str(len(flips))) # TODO: this is currently returning the base name, is should be returning the hash name self.assertEquals("remote_gateway", flips[0].gateway) self.assertEquals("publisher", flips[0].rule.type) self.assertEquals("/chatter", flips[0].rule.name) printtest( "********************************************************************" ) printtest("* Remote Gateway") printtest( "********************************************************************" ) printtest("%s" % self.graph._remote_gateways) for remote_gateway in self.graph._remote_gateways: self.assertEquals( "remote_gateway", rocon_utilities.gateway_basename(remote_gateway.name)) def tearDown(self): pass
class TestFlips(unittest.TestCase): def setUp(self): rospy.init_node('test_pullments') self.graph = Graph() def test_flip_all(self): print( "\n********************************************************************" ) print("* Flip All") print( "********************************************************************" ) try: samples.flip_all() except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when flipping all connections [%s]" % str(e)) flipped_interface = self._wait_for_flipped_interface() #print("%s" % self.graph._local_gateway) self.assertEquals("2", str(len(flipped_interface))) for remote_rule in flipped_interface: self.assertEquals("/chatter", remote_rule.remote_rule.rule.name) # Should probably assert rule.type and rule.node here as well. # Revert state try: samples.flip_all(cancel=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when unflipping all connections [%s]" % str(e)) self._assert_cleared_flipped_interface() def test_flip_tutorials(self): print( "\n********************************************************************" ) print("* Flip Tutorials") print( "********************************************************************" ) try: samples.flip_tutorials() except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when flipping tutorial connections.") flipped_interface = self._wait_for_flipped_interface() #print("%s" % self.graph._local_gateway) self.assertIn("/chatter", [ remote_rule.remote_rule.rule.name for remote_rule in flipped_interface ]) try: samples.flip_tutorials(cancel=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when unflipping tutorial connections.") self._assert_cleared_flipped_interface() def test_flip_regex_tutorials(self): print( "\n********************************************************************" ) print("* Flip Regex Tutorials") print( "********************************************************************" ) try: samples.flip_tutorials(regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when flipping tutorial connections.") flipped_interface = self._wait_for_flipped_interface() print("%s" % self.graph._local_gateway) self.assertIn("/chatter", [ remote_rule.remote_rule.rule.name for remote_rule in flipped_interface ]) try: samples.flip_tutorials(cancel=True, regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when unflipping tutorial connections.") self._assert_cleared_flipped_interface() def tearDown(self): pass ########################################################################## # Utility methods ########################################################################## def _wait_for_flipped_interface(self): flipped_interface = None while not flipped_interface: self.graph.update() flipped_interface = self.graph._local_gateway.flipped_connections rospy.sleep(0.2) return flipped_interface def _assert_cleared_flipped_interface(self): start_time = rospy.Time.now() while True: self.graph.update() flipped_interface = self.graph._local_gateway.flipped_connections if flipped_interface: result = "cleared" break else: rospy.sleep(0.2) if rospy.Time.now() - start_time > rospy.Duration(1.0): result = "timed out waiting for flipped interface to clear" break self.assertEqual("cleared", result)
class TestGraph(unittest.TestCase): def setUp(self): rospy.init_node('test_advertisements') self.graph = Graph() def test_advertise_all(self): print("\n********************************************************************") print("* Advertise All") print("********************************************************************") try: samples.advertise_all() except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when advertising all connections.") public_interface = self._wait_for_public_interface() #print("%s" % self.graph._local_gateway) self.assertEquals("2", str(len(public_interface))) for rule in public_interface: self.assertEquals("/chatter", rule.name) # Should probably assert rule.type and rule.node here as well. # Revert state try: samples.advertise_all(cancel=True) except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when unadvertising all connections.") self._assert_cleared_public_interface() def test_advertise_tutorials(self): print("\n********************************************************************") print("* Advertise Tutorials") print("********************************************************************") try: samples.advertise_tutorials() except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when advertising tutorial connections.") public_interface = self._wait_for_public_interface() #print("%s" % self.graph._local_gateway) self.assertIn("/chatter", [rule.name for rule in public_interface]) try: samples.advertise_tutorials(cancel=True) except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when unadvertising tutorial connections.") self._assert_cleared_public_interface() def test_advertise_regex_tutorials(self): print("\n********************************************************************") print("* Advertise Regex Tutorials") print("********************************************************************") try: samples.advertise_tutorials(regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when advertising tutorial connections.") public_interface = self._wait_for_public_interface() print("%s" % self.graph._local_gateway) self.assertIn("/chatter", [rule.name for rule in public_interface]) try: samples.advertise_tutorials(cancel=True, regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when unadvertising tutorial connections.") self._assert_cleared_public_interface() def tearDown(self): pass ########################################################################## # Utility methods ########################################################################## def _wait_for_public_interface(self): public_interface = None while not public_interface: self.graph.update() public_interface = self.graph._local_gateway.public_interface rospy.rostime.wallsleep(0.2) return public_interface def _assert_cleared_public_interface(self): start_time = rospy.Time.now() while True: self.graph.update() public_interface = self.graph._local_gateway.public_interface if public_interface: result = "cleared" break else: rospy.rostime.wallsleep(0.2) if rospy.Time.now() - start_time > rospy.Duration(2.0): result = "timed out waiting for public interface to clear" break self.assertEqual("cleared", result)
class GatewayGraph(Plugin): _deferred_fit_in_view = Signal() def __init__(self, context): super(GatewayGraph, self).__init__(context) self.initialised = False self.setObjectName('Gateway Graph') self._current_dotcode = None self._widget = QWidget() # factory builds generic dotcode items self.dotcode_factory = PydotFactory() # self.dotcode_factory = PygraphvizFactory() self.dotcode_generator = RosGraphDotcodeGenerator() self.dot_to_qt = DotToQtGenerator() self._graph = Graph() rospack = rospkg.RosPack() ui_file = os.path.join(rospack.get_path('rocon_gateway_graph'), 'ui', 'gateway_graph.ui') #ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ui', 'gateway_graph.ui') loadUi(ui_file, self._widget, {'InteractiveGraphicsView': InteractiveGraphicsView}) self._widget.setObjectName('GatewayGraphUi') if context.serial_number() > 1: self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number())) self._scene = QGraphicsScene() self._scene.setBackgroundBrush(Qt.white) self._widget.graphics_view.setScene(self._scene) self._widget.refresh_graph_push_button.setIcon( QIcon.fromTheme('view-refresh')) self._widget.refresh_graph_push_button.pressed.connect( self._update_gateway_graph) self._widget.graph_type_combo_box.insertItem(0, self.tr('Gateways'), GATEWAY_GATEWAY_GRAPH) self._widget.graph_type_combo_box.insertItem( 1, self.tr('Pulled Connections'), GATEWAY_PULLED_GRAPH) self._widget.graph_type_combo_box.insertItem( 2, self.tr('Flipped Connections'), GATEWAY_FLIPPED_GRAPH) self._widget.graph_type_combo_box.setCurrentIndex(0) self._widget.graph_type_combo_box.currentIndexChanged.connect( self._refresh_rosgraph) self.node_completionmodel = NamespaceCompletionModel( self._widget.filter_line_edit, False) completer = RepeatedWordCompleter(self.node_completionmodel, self) completer.setCompletionMode(QCompleter.PopupCompletion) completer.setWrapAround(True) completer.setCaseSensitivity(Qt.CaseInsensitive) self._widget.filter_line_edit.editingFinished.connect( self._refresh_rosgraph) self._widget.filter_line_edit.setCompleter(completer) self.topic_completionmodel = NamespaceCompletionModel( self._widget.topic_filter_line_edit, False) topic_completer = RepeatedWordCompleter(self.topic_completionmodel, self) topic_completer.setCompletionMode(QCompleter.PopupCompletion) topic_completer.setWrapAround(True) topic_completer.setCaseSensitivity(Qt.CaseInsensitive) self._widget.topic_filter_line_edit.editingFinished.connect( self._refresh_rosgraph) self._widget.topic_filter_line_edit.setCompleter(topic_completer) self._widget.namespace_cluster_check_box.clicked.connect( self._refresh_rosgraph) self._widget.watchlist_check_box.clicked.connect( self._refresh_rosgraph) self._widget.all_advertisements_check_box.clicked.connect( self._refresh_rosgraph) self._widget.highlight_connections_check_box.toggled.connect( self._redraw_graph_view) self._widget.auto_fit_graph_check_box.toggled.connect( self._redraw_graph_view) self._widget.fit_in_view_push_button.setIcon( QIcon.fromTheme('zoom-original')) self._widget.fit_in_view_push_button.pressed.connect(self._fit_in_view) self._widget.load_dot_push_button.setIcon( QIcon.fromTheme('document-open')) self._widget.load_dot_push_button.pressed.connect(self._load_dot) self._widget.save_dot_push_button.setIcon( QIcon.fromTheme('document-save-as')) self._widget.save_dot_push_button.pressed.connect(self._save_dot) self._widget.save_as_svg_push_button.setIcon( QIcon.fromTheme('document-save-as')) self._widget.save_as_svg_push_button.pressed.connect(self._save_svg) self._widget.save_as_image_push_button.setIcon( QIcon.fromTheme('image')) self._widget.save_as_image_push_button.pressed.connect( self._save_image) self._update_gateway_graph() self._deferred_fit_in_view.connect(self._fit_in_view, Qt.QueuedConnection) self._deferred_fit_in_view.emit() context.add_widget(self._widget) def save_settings(self, plugin_settings, instance_settings): instance_settings.set_value( 'graph_type_combo_box_index', self._widget.graph_type_combo_box.currentIndex()) instance_settings.set_value('filter_line_edit_text', self._widget.filter_line_edit.text()) instance_settings.set_value('topic_filter_line_edit_text', self._widget.topic_filter_line_edit.text()) instance_settings.set_value( 'namespace_cluster_check_box_state', self._widget.namespace_cluster_check_box.isChecked()) instance_settings.set_value( 'watchlist_check_box_state', self._widget.watchlist_check_box.isChecked()) instance_settings.set_value( 'all_advertisements_check_box_state', self._widget.all_advertisements_check_box.isChecked()) instance_settings.set_value( 'auto_fit_graph_check_box_state', self._widget.auto_fit_graph_check_box.isChecked()) instance_settings.set_value( 'highlight_connections_check_box_state', self._widget.highlight_connections_check_box.isChecked()) def restore_settings(self, plugin_settings, instance_settings): self._widget.graph_type_combo_box.setCurrentIndex( int(instance_settings.value('graph_type_combo_box_index', 0))) self._widget.filter_line_edit.setText( instance_settings.value('filter_line_edit_text', '')) self._widget.topic_filter_line_edit.setText( instance_settings.value('topic_filter_line_edit_text', '/')) self._widget.namespace_cluster_check_box.setChecked( instance_settings.value('namespace_cluster_check_box_state', True) in [True, 'true']) self._widget.watchlist_check_box.setChecked( instance_settings.value('watchlist_check_box_state', True) in [True, 'true']) self._widget.all_advertisements_check_box.setChecked( instance_settings.value('all_advertisements_check_box_state', False) in [False, 'false']) self._widget.auto_fit_graph_check_box.setChecked( instance_settings.value('auto_fit_graph_check_box_state', True) in [True, 'true']) self._widget.highlight_connections_check_box.setChecked( instance_settings.value('highlight_connections_check_box_state', True) in [True, 'true']) self.initialised = True self._refresh_rosgraph() def shutdown_plugin(self): pass def _update_gateway_graph(self): # re-enable controls customizing fetched ROS graph self._widget.graph_type_combo_box.setEnabled(True) self._widget.filter_line_edit.setEnabled(True) self._widget.topic_filter_line_edit.setEnabled(True) self._widget.namespace_cluster_check_box.setEnabled(True) self._widget.watchlist_check_box.setEnabled(True) self._widget.all_advertisements_check_box.setEnabled(True) self._graph.update() self.node_completionmodel.refresh(self._graph.gateway_nodes) self.topic_completionmodel.refresh(self._graph.flipped_nodes) self._refresh_rosgraph() def _refresh_rosgraph(self): if not self.initialised: return self._update_graph_view(self._generate_dotcode()) def _generate_dotcode(self): ns_filter = self._widget.filter_line_edit.text() topic_filter = self._widget.topic_filter_line_edit.text() graph_mode = self._widget.graph_type_combo_box.itemData( self._widget.graph_type_combo_box.currentIndex()) orientation = 'LR' if self._widget.namespace_cluster_check_box.isChecked(): namespace_cluster = 1 else: namespace_cluster = 0 hide_dead_end_topics = self._widget.watchlist_check_box.isChecked() show_all_advertisements = self._widget.all_advertisements_check_box.isChecked( ) return self.dotcode_generator.generate_dotcode( rosgraphinst=self._graph, ns_filter=ns_filter, topic_filter=topic_filter, graph_mode=graph_mode, show_all_advertisements=show_all_advertisements, hide_dead_end_topics=hide_dead_end_topics, cluster_namespaces_level=namespace_cluster, dotcode_factory=self.dotcode_factory, orientation=orientation, ) def _update_graph_view(self, dotcode): if dotcode == self._current_dotcode: return self._current_dotcode = dotcode self._redraw_graph_view() def _generate_tool_tip(self, url): if url is not None and ':' in url: item_type, item_path = url.split(':', 1) if item_type == 'node': tool_tip = 'Node:\n %s' % (item_path) service_names = rosservice.get_service_list(node=item_path) if service_names: tool_tip += '\nServices:' for service_name in service_names: try: service_type = rosservice.get_service_type( service_name) tool_tip += '\n %s [%s]' % (service_name, service_type) except rosservice.ROSServiceIOException as e: tool_tip += '\n %s' % (e) return tool_tip elif item_type == 'topic': topic_type, topic_name, _ = rostopic.get_topic_type(item_path) return 'Topic:\n %s\nType:\n %s' % (topic_name, topic_type) return url def _redraw_graph_view(self): self._scene.clear() if self._widget.highlight_connections_check_box.isChecked(): highlight_level = 3 else: highlight_level = 1 # layout graph and create qt items (nodes, edges) = self.dot_to_qt.dotcode_to_qt_items( self._current_dotcode, highlight_level=highlight_level, same_label_siblings=True) # if we wish to make special nodes, do that here (maybe subclass GraphItem, just like NodeItem does) for node_item in nodes.itervalues(): if node_item._label.text() == self._graph.local_gateway_name(): orange = QColor(232, 132, 3) node_item._default_color = orange node_item.set_color(orange) print "Local gateway: %s" % self._graph.local_gateway_name() self._scene.addItem(node_item) for edge_items in edges.itervalues(): for edge_item in edge_items: edge_item.add_to_scene(self._scene) self._scene.setSceneRect(self._scene.itemsBoundingRect()) if self._widget.auto_fit_graph_check_box.isChecked(): self._fit_in_view() def _load_dot(self, file_name=None): if file_name is None: file_name, _ = QFileDialog.getOpenFileName( self._widget, self.tr('Open graph from file'), None, self.tr('DOT graph (*.dot)')) if file_name is None or file_name == '': return try: fh = open(file_name, 'rb') dotcode = fh.read() fh.close() except IOError: return # disable controls customizing fetched ROS graph self._widget.graph_type_combo_box.setEnabled(False) self._widget.filter_line_edit.setEnabled(False) self._widget.topic_filter_line_edit.setEnabled(False) self._widget.namespace_cluster_check_box.setEnabled(False) self._widget.watchlist_check_box.setEnabled(False) self._widget.all_advertisements_check_box.setEnabled(False) self._update_graph_view(dotcode) def _fit_in_view(self): self._widget.graphics_view.fitInView(self._scene.itemsBoundingRect(), Qt.KeepAspectRatio) def _save_dot(self): file_name, _ = QFileDialog.getSaveFileName( self._widget, self.tr('Save as DOT'), 'rosgraph.dot', self.tr('DOT graph (*.dot)')) if file_name is None or file_name == '': return handle = QFile(file_name) if not handle.open(QIODevice.WriteOnly | QIODevice.Text): return handle.write(self._current_dotcode) handle.close() def _save_svg(self): file_name, _ = QFileDialog.getSaveFileName( self._widget, self.tr('Save as SVG'), 'rosgraph.svg', self.tr('Scalable Vector Graphic (*.svg)')) if file_name is None or file_name == '': return generator = QSvgGenerator() generator.setFileName(file_name) generator.setSize((self._scene.sceneRect().size() * 2.0).toSize()) painter = QPainter(generator) painter.setRenderHint(QPainter.Antialiasing) self._scene.render(painter) painter.end() def _save_image(self): file_name, _ = QFileDialog.getSaveFileName( self._widget, self.tr('Save as image'), 'rosgraph.png', self.tr('Image (*.bmp *.jpg *.png *.tiff)')) if file_name is None or file_name == '': return img = QImage((self._scene.sceneRect().size() * 2.0).toSize(), QImage.Format_ARGB32_Premultiplied) painter = QPainter(img) painter.setRenderHint(QPainter.Antialiasing) self._scene.render(painter) painter.end() img.save(file_name)
class TestPulls(unittest.TestCase): def setUp(self): print( "\n********************************************************************" ) print("* Pull Tests Setup") print( "********************************************************************" ) rospy.init_node('test_pulls') self.graph = Graph() def test_pull_all(self): print( "\n********************************************************************" ) print("* Pull All") print( "********************************************************************" ) try: samples.pull_all() except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when advertising all connections.") pulled_interface = self._wait_for_pulled_interface() rospy.loginfo(console.cyan + " - local gateway graph : \n%s" % self.graph._local_gateway + console.reset) self.assertEquals("5", str(len(pulled_interface))) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/add_two_ints" and remote_rule.rule.node.split(',')[0] == "/add_two_ints_server" and remote_rule.rule.type == "service" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/chatter" and remote_rule.rule.node.split(',')[0] == "/talker" and remote_rule.rule.type == "publisher" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/chatter" and remote_rule.rule.node.split(',')[0] == "/listener" and remote_rule.rule.type == "subscriber" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/fibonacci/server" and remote_rule.rule.node.split(',')[0] == "/fibonacci_server" and remote_rule.rule.type == "action_server" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/fibonacci/client" and remote_rule.rule.node.split(',')[0] == "/fibonacci_client" and remote_rule.rule.type == "action_client" ]), 1) # Revert state try: samples.pull_all(cancel=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when unadvertising all connections.") self._assert_cleared_pulled_interface() def test_pull_tutorials(self): print( "\n********************************************************************" ) print("* Pull Tutorials") print( "********************************************************************" ) try: samples.pull_tutorials() except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when advertising tutorial connections.") pulled_interface = self._wait_for_pulled_interface() rospy.loginfo(console.cyan + " - local gateway graph : \n%s" % self.graph._local_gateway + console.reset) self.assertEquals("5", str(len(pulled_interface))) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/add_two_ints" and remote_rule.rule.node.split(',')[0] == "/add_two_ints_server" and remote_rule.rule.type == "service" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/chatter" and remote_rule.rule.node.split(',')[0] == "/talker" and remote_rule.rule.type == "publisher" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/chatter" and remote_rule.rule.node.split(',')[0] == "/listener" and remote_rule.rule.type == "subscriber" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/fibonacci/server" and remote_rule.rule.node.split(',')[0] == "/fibonacci_server" and remote_rule.rule.type == "action_server" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/fibonacci/client" and remote_rule.rule.node.split(',')[0] == "/fibonacci_client" and remote_rule.rule.type == "action_client" ]), 1) try: samples.pull_tutorials(cancel=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when unadvertising tutorial connections." ) self._assert_cleared_pulled_interface() def test_pull_regex_tutorials(self): print( "\n********************************************************************" ) print("* Pull Regex Tutorials") print( "********************************************************************" ) try: samples.pull_tutorials(regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when advertising tutorial connections.") pulled_interface = self._wait_for_pulled_interface() rospy.loginfo(console.cyan + " - local gateway graph : \n%s" % self.graph._local_gateway + console.reset) self.assertEquals("5", str(len(pulled_interface))) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/add_two_ints" and remote_rule.rule.node.split(',')[0] == "/add_two_ints_server" and remote_rule.rule.type == "service" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/chatter" and remote_rule.rule.node.split(',')[0] == "/talker" and remote_rule.rule.type == "publisher" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/chatter" and remote_rule.rule.node.split(',')[0] == "/listener" and remote_rule.rule.type == "subscriber" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/fibonacci/server" and remote_rule.rule.node.split(',')[0] == "/fibonacci_server" and remote_rule.rule.type == "action_server" ]), 1) self.assertEquals( len([ remote_rule for remote_rule in pulled_interface if remote_rule.rule.name == "/fibonacci/client" and remote_rule.rule.node.split(',')[0] == "/fibonacci_client" and remote_rule.rule.type == "action_client" ]), 1) try: samples.pull_tutorials(cancel=True, regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when unadvertising tutorial connections." ) self._assert_cleared_pulled_interface() def tearDown(self): pass ########################################################################## # Utility methods ########################################################################## def _wait_for_pulled_interface(self): pulled_interface = None while not pulled_interface: self.graph.update() pulled_interface = self.graph._local_gateway.pulled_connections rospy.sleep(1.0) return pulled_interface def _assert_cleared_pulled_interface(self): start_time = rospy.Time.now() while True: self.graph.update() pulled_interface = self.graph._local_gateway.pulled_connections if not pulled_interface: result = "cleared" break else: rospy.sleep(0.2) if rospy.Time.now() - start_time > rospy.Duration(2.0): result = "timed out waiting for pulled interface to clear" break self.assertEqual("cleared", result)
class TestFlips(unittest.TestCase): @classmethod def setUpClass(cls): # Note this should be called only once by process. # We only run one process here, for all 3 tests rospy.init_node('test_pullments') @classmethod def tearDownClass(cls): # shutting down process here pass def setUp(self): self.graph = Graph() def test_flip_all(self): print(console.bold + "\n********************************************************************" + console.reset) print(console.bold + "* Flip All" + console.reset) print(console.bold + "********************************************************************" + console.reset) try: samples.flip_all() except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when flipping all connections [%s]" % str(e)) flipped_interface = self._wait_for_flipped_interface() rospy.loginfo(console.cyan + " - local gateway graph : \n%s" % self.graph._local_gateway + console.reset) self.assertEquals("5", str(len(flipped_interface))) self.assertEquals(len([flip for flip in flipped_interface if flip.remote_rule.rule.name == "/add_two_ints" and flip.remote_rule.rule.node.split(',')[0] == "/add_two_ints_server" and flip.remote_rule.rule.type == "service"]), 1) self.assertEquals(len([flip for flip in flipped_interface if flip.remote_rule.rule.name == "/chatter" and flip.remote_rule.rule.node.split(',')[0] == "/talker" and flip.remote_rule.rule.type == "publisher"]), 1) self.assertEquals(len([flip for flip in flipped_interface if flip.remote_rule.rule.name == "/chatter" and flip.remote_rule.rule.node.split(',')[0] == "/listener" and flip.remote_rule.rule.type == "subscriber"]), 1) self.assertEquals(len([flip for flip in flipped_interface if flip.remote_rule.rule.name == "/fibonacci/server" and flip.remote_rule.rule.node.split(',')[0] == "/fibonacci_server" and flip.remote_rule.rule.type == "action_server"]), 1) self.assertEquals(len([flip for flip in flipped_interface if flip.remote_rule.rule.name == "/fibonacci/client" and flip.remote_rule.rule.node.split(',')[0] == "/fibonacci_client" and flip.remote_rule.rule.type == "action_client"]), 1) result = self._wait_for_accepted_flipped_interface() self.assertTrue(result) # Revert state try: samples.flip_all(cancel=True) except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when unflipping all connections [%s]" % str(e)) self._assert_cleared_flipped_interface() def test_flip_tutorials(self): print(console.bold + "\n********************************************************************" + console.reset) print(console.bold + "* Flip Tutorials" + console.reset) print(console.bold + "********************************************************************" + console.reset) try: samples.flip_tutorials() except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when flipping tutorial connections.") flipped_interface = self._wait_for_flipped_interface() rospy.loginfo(console.cyan + " - local gateway graph : \n%s" % self.graph._local_gateway + console.reset) self.assertEquals("5", str(len(flipped_interface))) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/add_two_ints" and remote_rule.remote_rule.rule.node.split(',')[0] == "/add_two_ints_server" and remote_rule.remote_rule.rule.type == "service"]), 1) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/chatter" and remote_rule.remote_rule.rule.node.split(',')[0] == "/talker" and remote_rule.remote_rule.rule.type == "publisher"]), 1) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/chatter" and remote_rule.remote_rule.rule.node.split(',')[0] == "/listener" and remote_rule.remote_rule.rule.type == "subscriber"]), 1) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/fibonacci/server" and remote_rule.remote_rule.rule.node.split(',')[0] == "/fibonacci_server" and remote_rule.remote_rule.rule.type == "action_server"]), 1) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/fibonacci/client" and remote_rule.remote_rule.rule.node.split(',')[0] == "/fibonacci_client" and remote_rule.remote_rule.rule.type == "action_client"]), 1) result = self._wait_for_accepted_flipped_interface() self.assertTrue(result) try: samples.flip_tutorials(cancel=True) except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when unflipping tutorial connections.") self._assert_cleared_flipped_interface() def test_flip_regex_tutorials(self): print(console.bold + "\n********************************************************************" + console.reset) print(console.bold + "* Flip Regex Tutorials" + console.reset) print(console.bold + "********************************************************************" + console.reset) try: samples.flip_tutorials(regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when flipping tutorial connections.") flipped_interface = self._wait_for_flipped_interface() rospy.loginfo(console.cyan + " - local gateway graph : \n%s" % self.graph._local_gateway + console.reset) self.assertEquals("5", str(len(flipped_interface))) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/add_two_ints" and remote_rule.remote_rule.rule.node.split(',')[0] == "/add_two_ints_server" and remote_rule.remote_rule.rule.type == "service"]), 1) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/chatter" and remote_rule.remote_rule.rule.node.split(',')[0] == "/talker" and remote_rule.remote_rule.rule.type == "publisher"]), 1) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/chatter" and remote_rule.remote_rule.rule.node.split(',')[0] == "/listener" and remote_rule.remote_rule.rule.type == "subscriber"]), 1) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/fibonacci/server" and remote_rule.remote_rule.rule.node.split(',')[0] == "/fibonacci_server" and remote_rule.remote_rule.rule.type == "action_server"]), 1) self.assertEquals(len([remote_rule for remote_rule in flipped_interface if remote_rule.remote_rule.rule.name == "/fibonacci/client" and remote_rule.remote_rule.rule.node.split(',')[0] == "/fibonacci_client" and remote_rule.remote_rule.rule.type == "action_client"]), 1) result = self._wait_for_accepted_flipped_interface() self.assertTrue(result) try: samples.flip_tutorials(cancel=True, regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when unflipping tutorial connections.") self._assert_cleared_flipped_interface() def tearDown(self): pass ########################################################################## # Utility methods ########################################################################## def _wait_for_accepted_flipped_interface(self): result = False start_time = rospy.Time.now() while not result and (rospy.Time.now() - start_time) < rospy.Duration(5.0): rospy.sleep(0.1) self.graph.update() accepted = True flipped_interface = self.graph._local_gateway.flipped_connections if not flipped_interface: continue for remote_rule in flipped_interface: result = True if remote_rule.status != 'accepted': result = False break return result def _wait_for_flipped_interface(self): flipped_interface = None while not flipped_interface: self.graph.update() flipped_interface = self.graph._local_gateway.flipped_connections rospy.sleep(0.2) return flipped_interface def _assert_cleared_flipped_interface(self): start_time = rospy.Time.now() while True: self.graph.update() flipped_interface = self.graph._local_gateway.flipped_connections if not flipped_interface: result = "cleared" break else: rospy.sleep(0.2) if rospy.Time.now() - start_time > rospy.Duration(2.0): result = "timed out waiting for flipped interface to clear" break self.assertEqual("cleared", result)
class TestAdvertisements(unittest.TestCase): @classmethod def setUpClass(cls): # Note this should be called only once by process. # We only run one process here, for all 3 tests rospy.init_node('test_advertisements') @classmethod def tearDownClass(cls): # shutting down process here pass def setUp(self): try: self.graph = Graph() except Exception as exc: self.fail() def test_advertise_all(self): rospy.loginfo( console.cyan + "********************************************************************" + console.reset) rospy.loginfo(console.cyan + "* Advertise All" + console.reset) rospy.loginfo( console.cyan + "********************************************************************" + console.reset) try: samples.advertise_all() except GatewaySampleRuntimeError as e: self.fail("Runtime error caught when advertising all connections.") time.sleep(2) public_interface = self._wait_for_public_interface() rospy.loginfo(console.cyan + " - local gateway graph : \n%s" % self.graph._local_gateway + console.reset) self.assertEquals("5", str(len(public_interface))) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/add_two_ints" and rule.node == "/add_two_ints_server" and rule.type == "service" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/chatter" and rule.node == "/talker" and rule.type == "publisher" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/chatter" and rule.node == "/listener" and rule.type == "subscriber" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/fibonacci/server" and rule.node == "/fibonacci_server" and rule.type == "action_server" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/fibonacci/client" and rule.node == "/fibonacci_client" and rule.type == "action_client" ]), 1) # Revert state try: samples.advertise_all(cancel=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when unadvertising all connections.") self._assert_cleared_public_interface() def test_advertise_tutorials(self): rospy.loginfo( console.cyan + "********************************************************************" + console.reset) rospy.loginfo(console.cyan + "* Advertise Tutorials" + console.reset) rospy.loginfo( console.cyan + "********************************************************************" + console.reset) try: samples.advertise_tutorials() except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when advertising tutorial connections.") time.sleep(2) public_interface = self._wait_for_public_interface() rospy.loginfo(console.cyan + " - local gateway graph : \n%s" % self.graph._local_gateway + console.reset) self.assertEquals("5", str(len(public_interface))) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/add_two_ints" and rule.node == "/add_two_ints_server" and rule.type == "service" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/chatter" and rule.node == "/talker" and rule.type == "publisher" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/chatter" and rule.node == "/listener" and rule.type == "subscriber" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/fibonacci/server" and rule.node == "/fibonacci_server" and rule.type == "action_server" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/fibonacci/client" and rule.node == "/fibonacci_client" and rule.type == "action_client" ]), 1) try: samples.advertise_tutorials(cancel=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when unadvertising tutorial connections." ) self._assert_cleared_public_interface() def test_advertise_regex_tutorials(self): print( "\n********************************************************************" ) print("* Advertise Regex Tutorials") print( "********************************************************************" ) try: samples.advertise_tutorials(regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when advertising tutorial connections.") time.sleep(2) public_interface = self._wait_for_public_interface() print("%s" % self.graph._local_gateway) self.assertEquals("5", str(len(public_interface))) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/add_two_ints" and rule.node == "/add_two_ints_server" and rule.type == "service" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/chatter" and rule.node == "/talker" and rule.type == "publisher" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/chatter" and rule.node == "/listener" and rule.type == "subscriber" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/fibonacci/server" and rule.node == "/fibonacci_server" and rule.type == "action_server" ]), 1) self.assertEquals( len([ rule for rule in public_interface if rule.name == "/fibonacci/client" and rule.node == "/fibonacci_client" and rule.type == "action_client" ]), 1) try: samples.advertise_tutorials(cancel=True, regex_patterns=True) except GatewaySampleRuntimeError as e: self.fail( "Runtime error caught when unadvertising tutorial connections." ) self._assert_cleared_public_interface() def tearDown(self): pass ########################################################################## # Utility methods ########################################################################## def _wait_for_public_interface(self): public_interface = None while not public_interface: self.graph.update() public_interface = self.graph._local_gateway.public_interface rospy.rostime.wallsleep(0.2) return public_interface def _assert_cleared_public_interface(self): start_time = rospy.Time.now() while True: self.graph.update() rospy.loginfo(console.cyan + " - getting public interface" + console.reset) public_interface = self.graph._local_gateway.public_interface rospy.loginfo(console.cyan + " - public interface: \n" + console.reset + "%s" % public_interface) if not public_interface: result = "cleared" break else: rospy.rostime.wallsleep(0.2) if rospy.Time.now() - start_time > rospy.Duration(10.0): result = "timed out waiting for public interface to clear" break self.assertEqual("cleared", result)