diff --git a/iceoryx_integration_test/CMakeLists.txt b/iceoryx_integration_test/CMakeLists.txt new file mode 100644 index 00000000000..a2aca9e032c --- /dev/null +++ b/iceoryx_integration_test/CMakeLists.txt @@ -0,0 +1,76 @@ +# Copyright 2020 Apex.AI, 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. + +cmake_minimum_required(VERSION 3.5) +project(iceoryx_integration_test) + +include(GNUInstallDirs) + +find_package(iceoryx_posh REQUIRED) +find_package(iceoryx_utils REQUIRED) +find_package(cpptoml REQUIRED) + + +# find dependencies +find_package(ament_cmake REQUIRED) +# uncomment the following section in order to fill in further dependencies +# manually. find_package( REQUIRED) + +add_executable(integrationtest src/integrationtest.cpp) +target_include_directories( + integrationtest PUBLIC $ + $) + +install(TARGETS integrationtest DESTINATION lib/${PROJECT_NAME}) + +# +# posh roudi daemon ########## +# +add_executable(iox-roudi src/roudi/roudi_main.cpp) +set_target_properties( + iox-roudi + PROPERTIES CXX_STANDARD_REQUIRED ON + POSITION_INDEPENDENT_CODE ON + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") + +target_link_libraries( + iox-roudi + PRIVATE iceoryx_utils::iceoryx_utils iceoryx_posh::iceoryx_posh_roudi + iceoryx_posh::iceoryx_posh_config) + +target_include_directories( + iox-roudi + PRIVATE $ + $ + $) + +install(TARGETS iox-roudi DESTINATION lib/${PROJECT_NAME}) + +# Install launch files. +install(DIRECTORY + launch + DESTINATION share/${PROJECT_NAME}/ +) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights uncomment + # the line when a copyright and license is not present in all source files + # set(ament_cmake_copyright_FOUND TRUE) the following line skips cpplint (only + # works in a git repo) uncomment the line when this package is not in a git + # repo set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +ament_package() diff --git a/iceoryx_integration_test/launch/iox-roudi.launch.py b/iceoryx_integration_test/launch/iox-roudi.launch.py new file mode 100644 index 00000000000..1b214205694 --- /dev/null +++ b/iceoryx_integration_test/launch/iox-roudi.launch.py @@ -0,0 +1,27 @@ +# Copyright 2020 Apex.AI, 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. + +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + ld = LaunchDescription() + roudi_node = Node( + package="iceoryx_integration_test", + executable="iox-roudi", + ) + + ld.add_action(roudi_node) + + return ld \ No newline at end of file diff --git a/iceoryx_integration_test/package.xml b/iceoryx_integration_test/package.xml new file mode 100644 index 00000000000..a4120f7190c --- /dev/null +++ b/iceoryx_integration_test/package.xml @@ -0,0 +1,22 @@ + + + + iceoryx_integration_test + 0.1.0 + TODO: Package description + dietrich.kroenke + TODO: License declaration + + ament_cmake + + iceoryx_posh + iceoryx_binding_c + iceoryx_introspection + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/iceoryx_integration_test/simple_roudi_test.py b/iceoryx_integration_test/simple_roudi_test.py new file mode 100644 index 00000000000..560145c69f6 --- /dev/null +++ b/iceoryx_integration_test/simple_roudi_test.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Apex.AI, 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 os +import sys +import unittest +import time +import subprocess + +import ament_index_python + +import launch +import launch.actions + +import launch_testing +import launch_testing.actions +from launch_testing.asserts import assertSequentialStdout + +import pytest + + +@pytest.mark.launch_test +def generate_test_description(): + + print("index: ", ament_index_python.get_package_prefix('iceoryx_integration_test')) + TEST_PROC_PATH = os.path.join( + ament_index_python.get_package_prefix('iceoryx_integration_test'), + # 'bin/iceoryx_integration_test', + # 'iox-roudi' + 'bin/iceoryx_integration_test/', + 'iox-roudi' + ) + + # This is necessary to get unbuffered output from the process under test + proc_env = os.environ.copy() + proc_env['PYTHONUNBUFFERED'] = '1' + + dut_process = launch.actions.ExecuteProcess( + cmd=[sys.executable, subprocess.run([TEST_PROC_PATH, '-l', 'debug'])], + env=proc_env, output='screen' + ) + + return launch.LaunchDescription([ + wait_for_roudi(), + dut_process, + # Start tests right away - no need to wait for anything + launch_testing.actions.ReadyToTest(), + ]), {'dut_process': dut_process} + + +def wait_for_roudi(): + print('wait_for_roudi') + +# These tests will run concurrently with the dut process. After all these tests are done, +# the launch system will shut down the processes that it started up +class TestGoodProcess(unittest.TestCase): + + def test_count_to_four(self, proc_output): + # This will match stdout from any process. In this example there is only one process + # running + time.sleep(1) + print('test_count_to_four') + proc_output.assertWaitFor('RouDi is ready for clients', timeout=10, stream='stdout') + # proc_output.assertWaitFor('Loop 2', timeout=10, stream='stdout') + # proc_output.assertWaitFor('Loop 3', timeout=10, stream='stdout') + # proc_output.assertWaitFor('Loop 4', timeout=10, stream='stdout') + + +@launch_testing.post_shutdown_test() +class TestProcessOutput(unittest.TestCase): + + def test_exit_code(self, proc_info): + time.sleep(1) + print('test_exit_code') + # Check that all processes in the launch (in this case, there's just one) exit + # with code 0 + # launch_testing.asserts.assertExitCodes(proc_info) + + def test_full_output(self, proc_output, dut_process): + time.sleep(1) + print('test_full_output') + # Using the SequentialStdout context manager asserts that the following stdout + # happened in the same order that it's checked + # with assertSequentialStdout(proc_output, dut_process) as cm: + # cm.assertInStdout('Starting Up') + # for n in range(4): + # cm.assertInStdout('Loop {}'.format(n)) + # if os.name != 'nt': + # # On Windows, process termination is always forced + # # and thus the last print in good_proc never makes it. + # cm.assertInStdout('Shutting Down') + + def test_out_of_order(self, proc_output, dut_process): + time.sleep(1) + print('test_out_of_order') + # This demonstrates that we notice out-of-order IO + # with self.assertRaisesRegex(AssertionError, "'Loop 2' not found"): + # with assertSequentialStdout(proc_output, dut_process) as cm: + # cm.assertInStdout('Loop 1') + # cm.assertInStdout('Loop 3') + # cm.assertInStdout('Loop 2') # This should raise diff --git a/iceoryx_integration_test/src/integrationtest.cpp b/iceoryx_integration_test/src/integrationtest.cpp new file mode 100644 index 00000000000..7fc5cdbf491 --- /dev/null +++ b/iceoryx_integration_test/src/integrationtest.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2020 by Apex.AI Inc. All rights reserved. +// +// 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. + +#include + +int main(int argc, char ** argv) +{ + (void) argc; + (void) argv; + + printf("hello world iceoryx_integration_test package\n"); + return 0; +} diff --git a/iceoryx_integration_test/src/roudi/roudi_main.cpp b/iceoryx_integration_test/src/roudi/roudi_main.cpp new file mode 100644 index 00000000000..f474e800920 --- /dev/null +++ b/iceoryx_integration_test/src/roudi/roudi_main.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2020 by Apex.AI Inc. All rights reserved. +// +// 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. + +#include "iceoryx_posh/iceoryx_posh_config.hpp" +#include "iceoryx_posh/iceoryx_posh_types.hpp" +#include "iceoryx_posh/internal/log/posh_logging.hpp" +#include "iceoryx_posh/roudi/iceoryx_roudi_app.hpp" +#include "iceoryx_posh/roudi/roudi_cmd_line_parser_config_file_option.hpp" +#include "iceoryx_posh/roudi/roudi_config_toml_file_provider.hpp" + +int main(int argc, char* argv[]) +{ + using iox::roudi::IceOryxRouDiApp; + + iox::config::CmdLineParserConfigFileOption cmdLineParser; + cmdLineParser.parse(argc, argv); + + iox::config::TomlRouDiConfigFileProvider configFileProvider(cmdLineParser); + + iox::RouDiConfig_t roudiConfig = + configFileProvider.parse() + .or_else([](iox::roudi::RouDiConfigFileParseError& parseResult) { + iox::LogFatal() << "Couldn't parse config file. Error: " + << iox::cxx::convertEnumToString(iox::roudi::ROUDI_CONFIG_FILE_PARSE_ERROR_STRINGS, + parseResult); + std::terminate(); + }) + .value(); + /// @todo Add debug print about used RouDi params e.g. TOML file + IceOryxRouDiApp roudi(cmdLineParser, roudiConfig); + + roudi.run(); + + return 0; +}