From 9035b2326be65ac1d4fd2ad942c839d777cbf4a7 Mon Sep 17 00:00:00 2001 From: Emerson Knapp Date: Wed, 22 Feb 2023 16:35:39 -0800 Subject: [PATCH] Add schema checking test Signed-off-by: Emerson Knapp --- rosidl_generator_tests/CMakeLists.txt | 7 ++ rosidl_generator_tests/package.xml | 4 ++ .../test_type_hash.py | 67 +++++++++++++++++++ rosidl_generator_type_hash/CMakeLists.txt | 2 +- rosidl_pycommon/rosidl_pycommon/__init__.py | 6 +- rosidl_runtime_c/CMakeLists.txt | 1 + 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 rosidl_generator_tests/test/rosidl_generator_type_hash/test_type_hash.py diff --git a/rosidl_generator_tests/CMakeLists.txt b/rosidl_generator_tests/CMakeLists.txt index b428bfc7b..4f6ffc44d 100644 --- a/rosidl_generator_tests/CMakeLists.txt +++ b/rosidl_generator_tests/CMakeLists.txt @@ -19,9 +19,11 @@ find_package(ament_cmake REQUIRED) if(BUILD_TESTING) find_package(ament_cmake_gtest REQUIRED) + find_package(ament_cmake_pytest REQUIRED) find_package(ament_lint_auto REQUIRED) find_package(rosidl_cmake REQUIRED) find_package(rosidl_generator_cpp REQUIRED) + find_package(rosidl_generator_type_hash REQUIRED) find_package(rosidl_runtime_c REQUIRED) find_package(rosidl_runtime_cpp REQUIRED) find_package(test_interface_files REQUIRED) @@ -30,6 +32,7 @@ if(BUILD_TESTING) rosidl_generate_interfaces(${PROJECT_NAME} ${test_interface_files_MSG_FILES} ${test_interface_files_SRV_FILES} + ${test_interface_files_ACTION_FILES} ADD_LINTER_TESTS SKIP_INSTALL ) @@ -108,6 +111,10 @@ if(BUILD_TESTING) ${c_generator_target} rosidl_runtime_c::rosidl_runtime_c ) + + ament_add_pytest_test(test_hash_generator test/rosidl_generator_type_hash + ENV GENERATED_TEST_FILE_DIR=${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_type_hash/${PROJECT_NAME} + ) endif() ament_package() diff --git a/rosidl_generator_tests/package.xml b/rosidl_generator_tests/package.xml index 06b3a47ba..af92997c2 100644 --- a/rosidl_generator_tests/package.xml +++ b/rosidl_generator_tests/package.xml @@ -18,12 +18,16 @@ ament_cmake + action_msgs ament_cmake_gtest ament_lint_auto ament_lint_common + ament_index_python + python3-jsonschema rosidl_cmake rosidl_generator_c rosidl_generator_cpp + rosidl_generator_type_hash rosidl_runtime_c rosidl_runtime_cpp test_interface_files diff --git a/rosidl_generator_tests/test/rosidl_generator_type_hash/test_type_hash.py b/rosidl_generator_tests/test/rosidl_generator_type_hash/test_type_hash.py new file mode 100644 index 000000000..653e5b0b0 --- /dev/null +++ b/rosidl_generator_tests/test/rosidl_generator_type_hash/test_type_hash.py @@ -0,0 +1,67 @@ +# Copyright 2023 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +from pathlib import Path + +from ament_index_python import get_package_share_directory +import jsonschema + + +def test_type_hash(): + """Test all rosidl_generator_type_hash output files against defined schemas.""" + schema_dir = Path(get_package_share_directory('rosidl_generator_type_hash')) / 'resource' + resolver = jsonschema.validators.RefResolver( + base_uri=f'{schema_dir.as_uri()}/', + referrer=True, + ) + + generated_files_dir = Path(os.environ['GENERATED_TEST_FILE_DIR']) + validated_sha256 = 0 + validated_json_in = 0 + validated_json = 0 + for namespace in generated_files_dir.iterdir(): + for p in namespace.iterdir(): + assert p.is_file() + assert p.suffix == '.json' + with p.open('r') as f: + instance = json.load(f) + subsuffix = p.with_suffix('').suffix + if subsuffix == '.sha256': + jsonschema.validate( + instance=instance, + schema={'$ref': 'TypeVersionHash.schema.json'}, + resolver=resolver, + ) + validated_sha256 += 1 + elif subsuffix == '.in': + jsonschema.validate( + instance=instance, + schema={'$ref': 'TypeDescriptionIn.schema.json'}, + resolver=resolver, + ) + validated_json_in += 1 + elif subsuffix == '': + jsonschema.validate( + instance=instance, + schema={'$ref': 'TypeDescription.schema.json'}, + resolver=resolver, + ) + validated_json += 1 + else: + assert False, 'Unknown file type to validate' + assert validated_sha256, 'Needed to validate at least one of each type of file.' + assert validated_json_in, 'Needed to validate at least one of each type of file.' + assert validated_json, 'Needed to validate at least one of each type of file.' diff --git a/rosidl_generator_type_hash/CMakeLists.txt b/rosidl_generator_type_hash/CMakeLists.txt index 45061e95e..7f1a0c29b 100644 --- a/rosidl_generator_type_hash/CMakeLists.txt +++ b/rosidl_generator_type_hash/CMakeLists.txt @@ -22,6 +22,6 @@ install( DESTINATION lib/${PROJECT_NAME} ) install( - DIRECTORY cmake + DIRECTORY cmake resource DESTINATION share/${PROJECT_NAME} ) diff --git a/rosidl_pycommon/rosidl_pycommon/__init__.py b/rosidl_pycommon/rosidl_pycommon/__init__.py index 02f68afc6..bcfbd454a 100644 --- a/rosidl_pycommon/rosidl_pycommon/__init__.py +++ b/rosidl_pycommon/rosidl_pycommon/__init__.py @@ -226,7 +226,7 @@ def _expand_type_hash(variable_name, hash_string, indent=0): hash_length = 32 bytes_per_line = 8 - indent_str = ' ' * indent + indent_str = ' ' * (indent + 2) pattern = re.compile('RIHS(\d+)_([0-9a-f]{64})') match = pattern.match(hash_string) if not match: @@ -237,6 +237,8 @@ def _expand_type_hash(variable_name, hash_string, indent=0): for i in range(hash_length): if i % bytes_per_line == 0: result += f'\n{indent_str} ' - result += f'0x{value[i * 2:i * 2 + 2]}, ' + result += f'0x{value[i * 2:i * 2 + 2]},' + if i % bytes_per_line != bytes_per_line - 1: + result += ' ' result += f'\n{indent_str}}}}};\n' return result diff --git a/rosidl_runtime_c/CMakeLists.txt b/rosidl_runtime_c/CMakeLists.txt index 5da904f1c..202a76f7e 100644 --- a/rosidl_runtime_c/CMakeLists.txt +++ b/rosidl_runtime_c/CMakeLists.txt @@ -30,6 +30,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC ament_target_dependencies(${PROJECT_NAME} "rcutils" "rosidl_typesupport_interface") +target_link_libraries(${PROJECT_NAME} m) if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_OPTIONS -Wall -Wextra -Wpedantic)