Skip to content

Commit

Permalink
- Code style fixes
Browse files Browse the repository at this point in the history
- Added test for incompatible_qos events

Signed-off-by: Jaison Titus <[email protected]>
  • Loading branch information
jaisontj committed Nov 22, 2019
1 parent 348e77f commit b37d9ce
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 12 deletions.
1 change: 1 addition & 0 deletions rclpy/rclpy/qos_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class QoSSubscriptionEventType(IntEnum):
RCL_SUBSCRIPTION_LIVELINESS_CHANGED = 1
RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS = 2


"""
Payload type for Subscription Deadline callback.
Expand Down
16 changes: 8 additions & 8 deletions rclpy/src/rclpy/_rclpy_qos_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,10 @@ _requested_incompatible_qos_to_py_object(_qos_event_callback_data_t * data)
{
rmw_requested_incompatible_qos_status_t * actual_data = &data->requested_incompatible_qos;
PyObject * args = Py_BuildValue(
"iii",
actual_data->total_count,
actual_data->total_count_change,
actual_data->last_policy_id);
"iii",
actual_data->total_count,
actual_data->total_count_change,
actual_data->last_policy_id);
if (!args) {
return NULL;
}
Expand Down Expand Up @@ -211,10 +211,10 @@ _offered_incompatible_qos_to_py_object(_qos_event_callback_data_t * data)
{
rmw_offered_incompatible_qos_status_t * actual_data = &data->offered_incompatible_qos;
PyObject * args = Py_BuildValue(
"iii",
actual_data->total_count,
actual_data->total_count_change,
actual_data->last_policy_id);
"iii",
actual_data->total_count,
actual_data->total_count_change,
actual_data->last_policy_id);
if (!args) {
return NULL;
}
Expand Down
76 changes: 72 additions & 4 deletions rclpy/test/test_qos_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
from rclpy.qos_event import QoSLivelinessChangedInfo
from rclpy.qos_event import QoSLivelinessLostInfo
from rclpy.qos_event import QoSOfferedDeadlineMissedInfo
from rclpy.qos_event import QoSOfferedIncompatibleQoSInfo
from rclpy.qos_event import QoSPublisherEventType
from rclpy.qos_event import QoSRequestedDeadlineMissedInfo
from rclpy.qos_event import QoSRequestedIncompatibleQoSInfo
from rclpy.qos_event import QoSSubscriptionEventType
from rclpy.qos_event import SubscriptionEventCallbacks

Expand All @@ -47,6 +49,7 @@ def test_publisher_constructor(self):
callbacks = PublisherEventCallbacks()
liveliness_callback = Mock()
deadline_callback = Mock()
incompatible_qos_callback = Mock()

# No arg
publisher = self.node.create_publisher(EmptyMsg, 'test_topic', 10)
Expand All @@ -66,18 +69,26 @@ def test_publisher_constructor(self):
self.assertEqual(len(publisher.event_handlers), 1)
self.node.destroy_publisher(publisher)

# Arg with both callbacks
# Arg with two callbacks
callbacks.liveliness = liveliness_callback
publisher = self.node.create_publisher(
EmptyMsg, 'test_topic', 10, event_callbacks=callbacks)
self.assertEqual(len(publisher.event_handlers), 2)
self.node.destroy_publisher(publisher)

# Arg with three callbacks
callbacks.incompatible_qos = incompatible_qos_callback
publisher = self.node.create_publisher(
EmptyMsg, 'test_topic', 10, event_callbacks=callbacks)
self.assertEqual(len(publisher.event_handlers), 3)
self.node.destroy_publisher(publisher)

def test_subscription_constructor(self):
callbacks = SubscriptionEventCallbacks()
liveliness_callback = Mock()
deadline_callback = Mock()
message_callback = Mock()
incompatible_qos_callback = Mock()

# No arg
subscription = self.node.create_subscription(EmptyMsg, 'test_topic', message_callback, 10)
Expand All @@ -97,13 +108,20 @@ def test_subscription_constructor(self):
self.assertEqual(len(subscription.event_handlers), 1)
self.node.destroy_subscription(subscription)

# Arg with both callbacks
# Arg with two callbacks
callbacks.liveliness = liveliness_callback
subscription = self.node.create_subscription(
EmptyMsg, 'test_topic', message_callback, 10, event_callbacks=callbacks)
self.assertEqual(len(subscription.event_handlers), 2)
self.node.destroy_subscription(subscription)

# Arg with three callbacks
callbacks.incompatible_qos = incompatible_qos_callback
subscription = self.node.create_subscription(
EmptyMsg, 'test_topic', message_callback, 10, event_callbacks=callbacks)
self.assertEqual(len(subscription.event_handlers), 3)
self.node.destroy_subscription(subscription)

def _create_event_handle(self, parent_entity, event_type):
with parent_entity.handle as parent_capsule:
event_capsule = _rclpy.rclpy_create_event(event_type, parent_capsule)
Expand All @@ -120,6 +138,8 @@ def test_publisher_event_create_destroy(self):
publisher, QoSPublisherEventType.RCL_PUBLISHER_OFFERED_DEADLINE_MISSED)
self._do_create_destroy(
publisher, QoSPublisherEventType.RCL_PUBLISHER_LIVELINESS_LOST)
self._do_create_destroy(
publisher, QoSPublisherEventType.RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS)
self.node.destroy_publisher(publisher)

def test_subscription_event_create_destroy(self):
Expand All @@ -129,14 +149,16 @@ def test_subscription_event_create_destroy(self):
subscription, QoSSubscriptionEventType.RCL_SUBSCRIPTION_LIVELINESS_CHANGED)
self._do_create_destroy(
subscription, QoSSubscriptionEventType.RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED)
self._do_create_destroy(
subscription, QoSSubscriptionEventType.RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS)
self.node.destroy_subscription(subscription)

def test_call_publisher_rclpy_event_apis(self):
# Go through the exposed apis and ensure that things don't explode when called
# Make no assumptions about being able to actually receive the events
publisher = self.node.create_publisher(EmptyMsg, 'test_topic', 10)
wait_set = _rclpy.rclpy_get_zero_initialized_wait_set()
_rclpy.rclpy_wait_set_init(wait_set, 0, 0, 0, 0, 0, 2, self.context.handle)
_rclpy.rclpy_wait_set_init(wait_set, 0, 0, 0, 0, 0, 3, self.context.handle)

deadline_event_handle = self._create_event_handle(
publisher, QoSPublisherEventType.RCL_PUBLISHER_OFFERED_DEADLINE_MISSED)
Expand All @@ -150,11 +172,20 @@ def test_call_publisher_rclpy_event_apis(self):
liveliness_event_index = _rclpy.rclpy_wait_set_add_entity('event', wait_set, capsule)
self.assertIsNotNone(liveliness_event_index)

incompatible_qos_event_handle = self._create_event_handle(
publisher, QoSPublisherEventType.RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS)
with incompatible_qos_event_handle as capsule:
incompatible_qos_event_index = _rclpy.rclpy_wait_set_add_entity(
'event', wait_set, capsule)
self.assertIsNotNone(incompatible_qos_event_index)

# We live in our own namespace and have created no other participants, so
# there can't be any of these events.
_rclpy.rclpy_wait(wait_set, 0)
self.assertFalse(_rclpy.rclpy_wait_set_is_ready('event', wait_set, deadline_event_index))
self.assertFalse(_rclpy.rclpy_wait_set_is_ready('event', wait_set, liveliness_event_index))
self.assertFalse(_rclpy.rclpy_wait_set_is_ready(
'event', wait_set, incompatible_qos_event_index))

# Calling take data even though not ready should provide me an empty initialized message
# Tests data conversion utilities in C side
Expand Down Expand Up @@ -182,14 +213,28 @@ def test_call_publisher_rclpy_event_apis(self):
except NotImplementedError:
pass

try:
with incompatible_qos_event_handle as event_capsule, \
publisher.handle as publisher_capsule:
event_data = _rclpy.rclpy_take_event(
event_capsule,
publisher_capsule,
QoSPublisherEventType.RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS)
self.assertIsInstance(event_data, QoSOfferedIncompatibleQoSInfo)
self.assertEqual(event_data.total_count, 0)
self.assertEqual(event_data.total_count_change, 0)
self.assertEqual(event_data.last_policy_id, 0)
except NotImplementedError:
pass

self.node.destroy_publisher(publisher)

def test_call_subscription_rclpy_event_apis(self):
# Go through the exposed apis and ensure that things don't explode when called
# Make no assumptions about being able to actually receive the events
subscription = self.node.create_subscription(EmptyMsg, 'test_topic', Mock(), 10)
wait_set = _rclpy.rclpy_get_zero_initialized_wait_set()
_rclpy.rclpy_wait_set_init(wait_set, 0, 0, 0, 0, 0, 2, self.context.handle)
_rclpy.rclpy_wait_set_init(wait_set, 0, 0, 0, 0, 0, 3, self.context.handle)

deadline_event_handle = self._create_event_handle(
subscription, QoSSubscriptionEventType.RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED)
Expand All @@ -203,11 +248,20 @@ def test_call_subscription_rclpy_event_apis(self):
liveliness_event_index = _rclpy.rclpy_wait_set_add_entity('event', wait_set, capsule)
self.assertIsNotNone(liveliness_event_index)

incompatible_qos_event_handle = self._create_event_handle(
subscription, QoSSubscriptionEventType.RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS)
with incompatible_qos_event_handle as capsule:
incompatible_qos_event_index = _rclpy.rclpy_wait_set_add_entity(
'event', wait_set, capsule)
self.assertIsNotNone(incompatible_qos_event_index)

# We live in our own namespace and have created no other participants, so
# there can't be any of these events.
_rclpy.rclpy_wait(wait_set, 0)
self.assertFalse(_rclpy.rclpy_wait_set_is_ready('event', wait_set, deadline_event_index))
self.assertFalse(_rclpy.rclpy_wait_set_is_ready('event', wait_set, liveliness_event_index))
self.assertFalse(_rclpy.rclpy_wait_set_is_ready(
'event', wait_set, incompatible_qos_event_index))

# Calling take data even though not ready should provide me an empty initialized message
# Tests data conversion utilities in C side
Expand Down Expand Up @@ -237,4 +291,18 @@ def test_call_subscription_rclpy_event_apis(self):
except NotImplementedError:
pass

try:
with incompatible_qos_event_handle as event_capsule, \
subscription.handle as parent_capsule:
event_data = _rclpy.rclpy_take_event(
event_capsule,
parent_capsule,
QoSSubscriptionEventType.RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS)
self.assertIsInstance(event_data, QoSRequestedIncompatibleQoSInfo)
self.assertEqual(event_data.total_count, 0)
self.assertEqual(event_data.total_count_change, 0)
self.assertEqual(event_data.last_policy_id, 0)
except NotImplementedError:
pass

self.node.destroy_subscription(subscription)

0 comments on commit b37d9ce

Please sign in to comment.