Skip to content

Commit

Permalink
pass linting
Browse files Browse the repository at this point in the history
Signed-off-by: Brian Chen <brian.chen@openrobotics.org>
  • Loading branch information
ihasdapie committed Aug 24, 2022
1 parent 0a94fa5 commit 8bae776
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 97 deletions.
24 changes: 14 additions & 10 deletions rclpy/rclpy/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,18 +235,18 @@ def __init__(

if start_parameter_services:
self._parameter_service = ParameterService(self)

if enable_service_introspection:
self.declare_parameters(
namespace='',
parameters=[
(_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_CLIENT_PARAMETER, #noqa E501
(_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_CLIENT_PARAMETER, # noqa E501
True, ParameterDescriptor()),
(_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_SERVICE_PARAMETER, #noqa E501
(_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_SERVICE_PARAMETER, # noqa E501
True, ParameterDescriptor()),
(_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_SERVICE_EVENT_CONTENT_PARAMETER, #noqa E501
(_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_SERVICE_EVENT_CONTENT_PARAMETER, # noqa E501
True, ParameterDescriptor()),
(_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_CLIENT_EVENT_CONTENT_PARAMETER, #noqa E501
(_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_CLIENT_EVENT_CONTENT_PARAMETER, # noqa E501
True, ParameterDescriptor())
])
self.add_post_set_parameters_callback(self._configure_service_introspection)
Expand Down Expand Up @@ -1598,25 +1598,29 @@ def create_subscription(

def _configure_service_introspection(self, parameters: List[Parameter]):
for param in parameters:
if param.name == _rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_CLIENT_PARAMETER:
if param.name == \
_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_CLIENT_PARAMETER: # noqa: E501
for srv in self.clients:
_rclpy.service_introspection.configure_client_events(
srv.handle.pointer,
self.handle.pointer,
param.value)
elif param.name == _rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_SERVICE_PARAMETER:
elif param.name == \
_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_SERVICE_PARAMETER: # noqa: E501
for cli in self.services:
ret = _rclpy.service_introspection.configure_service_events(
_rclpy.service_introspection.configure_service_events(
cli.handle.pointer,
self.handle.pointer,
param.value)
elif param.name == _rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_SERVICE_EVENT_CONTENT_PARAMETER:
elif param.name == \
_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_SERVICE_EVENT_CONTENT_PARAMETER: # noqa E501
for srv in self.services:
_rclpy.service_introspection.configure_service_message_payload(
srv.handle.pointer,
param.value)

elif param.name == _rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_CLIENT_EVENT_CONTENT_PARAMETER:
elif param.name == \
_rclpy.service_introspection.RCL_SERVICE_INTROSPECTION_PUBLISH_CLIENT_EVENT_CONTENT_PARAMETER: # noqa E501
for cli in self.clients:
_rclpy.service_introspection.configure_client_message_payload(
cli.handle.pointer,
Expand Down
1 change: 0 additions & 1 deletion rclpy/src/rclpy/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ Client::Client(
rmw_qos_profile_t pyqos_service_event_pub, Clock & clock)
: node_(node)
{

auto srv_type = static_cast<rosidl_service_type_support_t *>(
common_get_type_support(pysrv_type));
if (nullptr == srv_type) {
Expand Down
3 changes: 2 additions & 1 deletion rclpy/src/rclpy/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ class Client : public Destroyable, public std::enable_shared_from_this<Client>
py::object pyqos_service_event_pub, Clock & clock)
: Client(
node, std::move(pysrv_type), service_name, std::move(pyqos),
pyqos_service_event_pub.is_none() ? rcl_publisher_get_default_options().qos : pyqos_service_event_pub.cast<rmw_qos_profile_t>(),
pyqos_service_event_pub.is_none() ?
rcl_publisher_get_default_options().qos : pyqos_service_event_pub.cast<rmw_qos_profile_t>(),
clock) {}

~Client() = default;
Expand Down
3 changes: 2 additions & 1 deletion rclpy/src/rclpy/service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ class Service : public Destroyable, public std::enable_shared_from_this<Service>
Clock & clock)
: Service(
node, std::move(pysrv_type), std::move(service_name), std::move(pyqos_srv_profile),
pyqos_service_event_pub.is_none() ? rcl_publisher_get_default_options().qos : pyqos_service_event_pub.cast<rmw_qos_profile_t>(),
pyqos_service_event_pub.is_none() ?
rcl_publisher_get_default_options().qos : pyqos_service_event_pub.cast<rmw_qos_profile_t>(),
clock) {}

Service(
Expand Down
10 changes: 5 additions & 5 deletions rclpy/src/rclpy/service_introspection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "service_introspection.hpp"
#include <rcl/node.h>
#include <cstddef>

#include "service_introspection.hpp"
#include "rcl/service_introspection.h"
#include "rcl/client.h"
#include "rcl/node.h"
#include "rcl/service.h"

namespace rclpy
{

#include <cstdio>
void
define_service_introspection(py::module_ module)
{
Expand All @@ -44,7 +44,7 @@ define_service_introspection(py::module_ module)
*>(clt), reinterpret_cast<rcl_node_t *>(node), opt);
});
m2.def(
"configure_service_message_payload", [](size_t srv, bool opt){
"configure_service_message_payload", [](size_t srv, bool opt) {
return rcl_service_introspection_configure_server_service_event_message_payload(
reinterpret_cast<rcl_service_t *>(srv), opt);
});
Expand All @@ -63,4 +63,4 @@ define_service_introspection(py::module_ module)
RCL_SERVICE_INTROSPECTION_PUBLISH_SERVICE_EVENT_CONTENT_PARAMETER;
m2.attr("RCL_SERVICE_INTROSPECTION_TOPIC_POSTFIX") = RCL_SERVICE_INTROSPECTION_TOPIC_POSTFIX;
}
} // namespace rclpy
} // namespace rclpy
4 changes: 2 additions & 2 deletions rclpy/src/rclpy/service_introspection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ namespace rclpy
void
define_service_introspection(py::module_ module);

} // namespace rclpy
#endif // RCLPY__SERVICE_INTROSPECTION_HPP_
} // namespace rclpy
#endif // RCLPY__SERVICE_INTROSPECTION_HPP_
214 changes: 137 additions & 77 deletions rclpy/test/test_service_introspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,111 +12,171 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import platform
import time
from typing import List
import unittest

import rclpy
import rclpy.executors
from rclpy.parameter import Parameter
from rclpy.parameter_client import AsyncParameterClient

from test_msgs.srv import BasicTypes
from service_msgs.msg import ServiceEventInfo

import rclpy
from test_msgs.srv import BasicTypes


class TestClient(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.context = rclpy.context.Context()
rclpy.init(context=cls.context)
cls.node = rclpy.create_node(
'TestClient', context=cls.context, enable_service_introspection=True)
class TestServiceEvents(unittest.TestCase):

@classmethod
def tearDownClass(cls):
cls.node.destroy_node()
rclpy.shutdown(context=cls.context)
def setUp(self):
self.context = rclpy.context.Context()
rclpy.init(context=self.context)
self.node = rclpy.create_node(
'TestClient', context=self.context, enable_service_introspection=True)
self.executor = rclpy.executors.SingleThreadedExecutor(context=self.context)
self.executor.add_node(self.node)
self.srv = self.node.create_service(BasicTypes, 'test_service', self.srv_callback)
self.cli = self.node.create_client(BasicTypes, 'test_service')
self.sub = self.node.create_subscription(BasicTypes.Event, 'test_service/_service_event',
self.sub_callback, 10)
self.event_messages: List[BasicTypes.Event] = []

def test_service_introspection_nominal(self):
event_messages = []
def tearDown(self):
self.node.destroy_node()
rclpy.shutdown(context=self.context)

def callback(msg):
event_messages.append(msg)
def sub_callback(self, msg):
self.event_messages.append(msg)

def srv_callback(req, resp):
resp.bool_value = not req.bool_value
resp.int64_value = req.int64_value
return resp
def srv_callback(self, req, resp):
resp.bool_value = not req.bool_value
resp.int64_value = req.int64_value
return resp

srv = self.node.create_service(BasicTypes, 'test_service', callback=srv_callback)
cli = self.node.create_client(BasicTypes, 'test_service')
sub = self.node.create_subscription(BasicTypes.Event, 'test_service/_service_event',
callback, 10)
def test_service_introspection_nominal(self):
req = BasicTypes.Request()
req.bool_value = False
req.int64_value = 12345

future = cli.call_async(req)
executor = rclpy.executors.SingleThreadedExecutor(context=self.context)
rclpy.spin_until_future_complete(self.node, future, executor=executor)

# Wait for the service event to be published (this screams flaky...)
# for i in range(10):
rclpy.spin_once(self.node, executor=executor)
rclpy.spin_once(self.node, executor=executor)
rclpy.spin_once(self.node, executor=executor)
rclpy.spin_once(self.node, executor=executor)
rclpy.spin_once(self.node, executor=executor)
rclpy.spin_once(self.node, executor=executor)
rclpy.spin_once(self.node, executor=executor)

self.assertEqual(len(event_messages), 4)
self.assertEqual(event_messages[0].info.event_type, ServiceEventInfo.REQUEST_SENT)
self.assertEqual(event_messages[1].info.event_type, ServiceEventInfo.REQUEST_RECEIVED)
self.assertEqual(event_messages[2].info.event_type, ServiceEventInfo.RESPONSE_SENT)
self.assertEqual(event_messages[3].info.event_type, ServiceEventInfo.RESPONSE_RECEIVED)
self.assertEqual(event_messages[0].request[0].bool_value, False)
self.assertEqual(event_messages[0].request[0].int64_value, 12345)
self.assertEqual(event_messages[3].response[0].bool_value, True)
self.assertEqual(event_messages[3].response[0].int64_value, 12345)
future = self.cli.call_async(req)
self.executor.spin_until_future_complete(future)

# Wait for the service event messages to be published (this screams flaky...)
for _ in range(10):
self.executor.spin_once(0.1)

self.assertEqual(len(self.event_messages), 4)
result_dict = {}
for msg in self.event_messages:
result_dict[msg.info.event_type] = msg
self.assertEqual(
set(result_dict.keys()),
{ServiceEventInfo.REQUEST_SENT, ServiceEventInfo.REQUEST_RECEIVED,
ServiceEventInfo.RESPONSE_SENT, ServiceEventInfo.RESPONSE_RECEIVED})
self.assertEqual(result_dict[ServiceEventInfo.REQUEST_SENT].request[0].int64_value, 12345)
self.assertEqual(result_dict[ServiceEventInfo.REQUEST_SENT].request[0].bool_value, False)
self.assertEqual(result_dict[ServiceEventInfo.RESPONSE_SENT].response[0].bool_value, True)
self.assertEqual(
result_dict[ServiceEventInfo.RESPONSE_RECEIVED].response[0].int64_value, 12345)

def test_enable_disable_service_events(self):
event_messages = []

def callback(msg):
event_messages.append(msg)

def srv_callback(req, resp):
resp.bool_value = not req.bool_value
resp.int64_value = req.int64_value
return resp

executor = rclpy.executors.SingleThreadedExecutor(context=self.context)
srv = self.node.create_service(BasicTypes, 'test_service', callback=srv_callback)
cli = self.node.create_client(BasicTypes, 'test_service')
sub = self.node.create_subscription(BasicTypes.Event, 'test_service/_service_event',
callback, 10)
req = BasicTypes.Request()
req.bool_value = False
req.int64_value = 12345

self.node.set_parameters([
Parameter('publish_service_events', Parameter.Type.BOOL, False),
Parameter('publish_client_events', Parameter.Type.BOOL, False), ])

future = cli.call_async(req)
for i in range(4):
rclpy.spin_once(self.node, executor=executor)
self.assertEqual(len(event_messages), 2)


Parameter('publish_client_events', Parameter.Type.BOOL, False)])
future = self.cli.call_async(req)
self.executor.spin_until_future_complete(future)
for _ in range(10):
self.executor.spin_once(0.1)
self.assertEqual(len(self.event_messages), 0)

self.event_messages = []
result_dict = {}
self.node.set_parameters([
Parameter('publish_service_events', Parameter.Type.BOOL, True),
Parameter('publish_client_events', Parameter.Type.BOOL, False)])
future = self.cli.call_async(req)
self.executor.spin_until_future_complete(future)
for _ in range(10):
self.executor.spin_once(0.1)
self.assertEqual(len(self.event_messages), 2)
for msg in self.event_messages:
result_dict[msg.info.event_type] = msg
self.assertEqual(
set(result_dict.keys()),
{ServiceEventInfo.REQUEST_RECEIVED, ServiceEventInfo.RESPONSE_SENT})
self.assertEqual(len(result_dict[ServiceEventInfo.REQUEST_RECEIVED].response), 0)
self.assertEqual(len(result_dict[ServiceEventInfo.RESPONSE_SENT].response), 1)
self.assertEqual(result_dict[ServiceEventInfo.RESPONSE_SENT].response[0].bool_value, True)

self.event_messages = []
result_dict = {}
self.node.set_parameters([
Parameter('publish_service_events', Parameter.Type.BOOL, False),
Parameter('publish_client_events', Parameter.Type.BOOL, True)])
future = self.cli.call_async(req)
self.executor.spin_until_future_complete(future)
for _ in range(10):
self.executor.spin_once(0.1)
self.assertEqual(len(self.event_messages), 2)
for msg in self.event_messages:
result_dict[msg.info.event_type] = msg
self.assertEqual(
set(result_dict.keys()),
{ServiceEventInfo.REQUEST_SENT, ServiceEventInfo.RESPONSE_RECEIVED})
self.assertEqual(len(result_dict[ServiceEventInfo.REQUEST_SENT].response), 0)
self.assertEqual(len(result_dict[ServiceEventInfo.RESPONSE_RECEIVED].response), 1)
self.assertEqual(result_dict[ServiceEventInfo.REQUEST_SENT].request[0].bool_value, False)

def test_enable_disable_service_event_payload(self):
pass
req = BasicTypes.Request()
req.bool_value = False
req.int64_value = 12345

self.node.set_parameters([
Parameter('publish_service_content', Parameter.Type.BOOL, False),
Parameter('publish_client_content', Parameter.Type.BOOL, False)])
future = self.cli.call_async(req)
self.executor.spin_until_future_complete(future)
for _ in range(10):
self.executor.spin_once(0.1)
self.assertEqual(len(self.event_messages), 4)
for i in self.event_messages:
self.assertEqual(len(i.request), 0)
self.assertEqual(len(i.response), 0)

self.event_messages = []
self.node.set_parameters([
Parameter('publish_service_content', Parameter.Type.BOOL, True),
Parameter('publish_client_content', Parameter.Type.BOOL, False)])
future = self.cli.call_async(req)
self.executor.spin_until_future_complete(future)
for _ in range(10):
self.executor.spin_once(0.1)
self.assertEqual(len(self.event_messages), 4)
for i in self.event_messages:
if i.info.event_type == ServiceEventInfo.REQUEST_RECEIVED:
self.assertEqual(len(i.request), 1)
elif (i.info.event_type == ServiceEventInfo.RESPONSE_SENT):
self.assertEqual(len(i.response), 1)
else:
self.assertEqual(len(i.request) + len(i.response), 0)

self.event_messages = []
self.node.set_parameters([
Parameter('publish_service_content', Parameter.Type.BOOL, False),
Parameter('publish_client_content', Parameter.Type.BOOL, True)])
future = self.cli.call_async(req)
self.executor.spin_until_future_complete(future)
for _ in range(10):
self.executor.spin_once(0.1)
self.assertEqual(len(self.event_messages), 4)
for i in self.event_messages:
if i.info.event_type == ServiceEventInfo.REQUEST_SENT:
self.assertEqual(len(i.request), 1)
elif (i.info.event_type == ServiceEventInfo.RESPONSE_RECEIVED):
self.assertEqual(len(i.response), 1)
else:
self.assertEqual(len(i.request) + len(i.response), 0)


if __name__ == '__main__':
Expand Down

0 comments on commit 8bae776

Please sign in to comment.