From 879547517513fe66d9e3f822d39798e044a5da51 Mon Sep 17 00:00:00 2001 From: Franco Cipollone <53065142+francocipollone@users.noreply.github.com> Date: Wed, 1 Nov 2023 09:44:59 -0300 Subject: [PATCH] Adds some missing bindings for maliput plugin module. (#83) Signed-off-by: Franco Cipollone --- src/bindings/plugin_py.cc | 22 +++++++--- test/CMakeLists.txt | 1 + test/plugin/CMakeLists.txt | 9 ++++ test/plugin/plugin_test.py | 90 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 test/plugin/CMakeLists.txt create mode 100644 test/plugin/plugin_test.py diff --git a/src/bindings/plugin_py.cc b/src/bindings/plugin_py.cc index 7caa9db..762a0c4 100644 --- a/src/bindings/plugin_py.cc +++ b/src/bindings/plugin_py.cc @@ -1,7 +1,7 @@ // BSD 3-Clause License // -// Copyright (c) 2022, Woven Planet. All rights reserved. -// Copyright (c) 2020-2022, Toyota Research Institute. All rights reserved. +// Copyright (c) 2023, Woven by Toyota. +// All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -41,10 +42,21 @@ namespace bindings { namespace py = pybind11; PYBIND11_MODULE(plugin, m) { - py::class_(m, "MaliputPlugin") + py::enum_(m, "MaliputPluginType") + .value("kRoadNetworkLoader", plugin::MaliputPluginType::kRoadNetworkLoader) + .export_values(); + + auto maliput_plugin_type = py::class_(m, "MaliputPlugin") + .def(py::init()) + .def("GetId", &plugin::MaliputPlugin::GetId) + .def("GetType", &plugin::MaliputPlugin::GetType); + + py::class_(maliput_plugin_type, "Id") .def(py::init()) - .def("GetId", &plugin::MaliputPlugin::GetId) - .def("GetType", &plugin::MaliputPlugin::GetType); + .def(py::detail::hash(py::self)) + .def("string", &plugin::MaliputPlugin::Id::string) + .def("__eq__", &plugin::MaliputPlugin::Id::operator==) + .def("__repr__", [](const plugin::MaliputPlugin::Id& id) { return id.string(); }); py::class_(m, "MaliputPluginManager") .def(py::init<>()) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 561cbef..cf8eb05 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,4 +2,5 @@ find_package(ament_cmake_pytest REQUIRED) add_subdirectory(api) add_subdirectory(math) +add_subdirectory(plugin) add_subdirectory(utility) diff --git a/test/plugin/CMakeLists.txt b/test/plugin/CMakeLists.txt new file mode 100644 index 0000000..322064f --- /dev/null +++ b/test/plugin/CMakeLists.txt @@ -0,0 +1,9 @@ +# TODO(francocipollone): Improve this check by wrapping ament_add_pytest_test() function. +# When sanitizers are activated python scripts are disabled. +if (NOT ${SANITIZERS}) + ament_add_pytest_test(plugin_pytest + plugin_test.py + # Avoid pytest from importing the module stub + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) +endif() diff --git a/test/plugin/plugin_test.py b/test/plugin/plugin_test.py new file mode 100644 index 0000000..aff849f --- /dev/null +++ b/test/plugin/plugin_test.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +# BSD 3-Clause License +# +# Copyright (c) 2023, Woven by Toyota +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Unit tests for the maliput::plugin python binding""" + +import unittest + +from maliput.plugin import ( + MaliputPlugin, + MaliputPluginManager, + MaliputPluginType, +) + + +class TestMaliputPlugin(unittest.TestCase): + """ + Evaluates the maliput.plugin bindings for concrete classes or structs. + """ + + def test_plugin_entities(self): + """ + Tests the maliput.plugin module entities. + """ + import maliput.plugin + dut_type_entities = dir(maliput.plugin) + self.assertTrue('MaliputPluginType' in dut_type_entities) + self.assertTrue('MaliputPluginManager' in dut_type_entities) + self.assertTrue('MaliputPlugin' in dut_type_entities) + self.assertTrue('create_road_network' in dut_type_entities) + + def test_maliput_plugin_id(self): + """ + Tests the MaliputPlugin::Id class methods. + """ + dut = MaliputPlugin.Id('test_id') + self.assertEqual(dut.string(), 'test_id') + self.assertEqual(dut, dut) + self.assertNotEqual(dut, MaliputPlugin.Id('test_id2')) + + def test_maliput_plugin_methods(self): + """ + Tests the MaliputPlugin class methods. + """ + dut_type_methods = dir(MaliputPlugin) + self.assertTrue('GetId' in dut_type_methods) + self.assertTrue('GetType' in dut_type_methods) + + def test_maliput_plugin_manager_methods(self): + """ + Tests the MaliputPluginManager class methods. + """ + dut_type_methods = dir(MaliputPluginManager) + self.assertTrue('GetPlugin' in dut_type_methods) + self.assertTrue('AddPlugin' in dut_type_methods) + self.assertTrue('ListPlugins' in dut_type_methods) + + def test_maliput_plugin_type(self): + """ + Tests the MaliputPluginType enum. + """ + self.assertEqual(MaliputPluginType.kRoadNetworkLoader, MaliputPluginType.kRoadNetworkLoader)