Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default ROS_HOME and ROS_LOG_DIR env vars in ros2_cpp_test #100

Merged
merged 13 commits into from
May 7, 2023
Merged
2 changes: 2 additions & 0 deletions ros2/cc_defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def _ros2_cpp_exec(target, name, ros2_package_name = None, set_up_ament = False,
target_impl = name + "_impl"
tags = kwargs.pop("tags", [])
visibility = kwargs.pop("visibility", None)
size = kwargs.pop("size", None)
lalten marked this conversation as resolved.
Show resolved Hide resolved
_ros2_cc_target(cc_binary, "cpp", target_impl, ros2_package_name, tags = ["manual"], **kwargs)

is_test = target == cc_test
Expand All @@ -92,6 +93,7 @@ def _ros2_cpp_exec(target, name, ros2_package_name = None, set_up_ament = False,
sh_target = native.sh_test if is_test else native.sh_binary
sh_target(
name = name,
size = size,
lalten marked this conversation as resolved.
Show resolved Hide resolved
srcs = [launcher],
data = [target_impl],
tags = tags,
Expand Down
10 changes: 10 additions & 0 deletions ros2/launch.sh.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

set -o errexit -o nounset -o pipefail

if [[ ! -z "${BAZEL_TEST:-}" ]]; then
bazel_test_output_dir="${TEST_UNDECLARED_OUTPUTS_DIR:-${TEST_TMPDIR}}"
if [[ -z "${ROS_HOME:-}" ]]; then
export ROS_HOME="${bazel_test_output_dir}"
fi
if [[ -z "${ROS_LOG_DIR:-}" ]]; then
export ROS_LOG_DIR="${bazel_test_output_dir}"
fi
fi

ament_prefix_path="{{ament_prefix_path}}"
if [ -z "${ament_prefix_path}" ]; then
unset AMENT_PREFIX_PATH
Expand Down
2 changes: 2 additions & 0 deletions ros2/py_defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def _ros2_py_exec(target, name, srcs, main, set_up_ament, **kwargs):
target_impl = name + "_impl"
tags = kwargs.pop("tags", [])
visibility = kwargs.pop("visibility", None)
size = kwargs.pop("size", None)
target(name = target_impl, srcs = srcs, main = main, tags = ["manual"], **kwargs)

is_test = target == py_test
Expand Down Expand Up @@ -41,6 +42,7 @@ def _ros2_py_exec(target, name, srcs, main, set_up_ament, **kwargs):
sh_target = native.sh_test if is_test else native.sh_binary
sh_target(
name = name,
size = size,
srcs = [launcher],
data = [target_impl_symlink],
tags = tags,
Expand Down
11 changes: 7 additions & 4 deletions ros2/pytest_wrapper.py.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ def finalize_coverage_session(coverage_session: coverage.Coverage) -> None:


def main() -> None:
test_outputs_dir = os.environ.get('TEST_UNDECLARED_OUTPUTS_DIR')
if test_outputs_dir:
os.environ['ROS_HOME'] = test_outputs_dir
os.environ['ROS_LOG_DIR'] = test_outputs_dir
bazel_test_output_dir = os.environ.get('TEST_UNDECLARED_OUTPUTS_DIR')
if bazel_test_output_dir is None:
bazel_test_output_dir = os.environ.get('TEST_TMPDIR')
if 'ROS_HOME' not in os.environ:
os.environ['ROS_HOME'] = bazel_test_output_dir
if 'ROS_LOG_DIR' not in os.environ:
os.environ['ROS_LOG_DIR'] = bazel_test_output_dir

with contextlib.ExitStack() as stack:
if 'ROS_DOMAIN_ID' not in os.environ:
Expand Down
11 changes: 7 additions & 4 deletions ros2/test.py.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ sys.argv = sys.argv[:1] + [
LAUNCH_FILE,
] + sys.argv[1:]

test_outputs_dir = os.environ.get('TEST_UNDECLARED_OUTPUTS_DIR')
if test_outputs_dir:
os.environ['ROS_HOME'] = test_outputs_dir
os.environ['ROS_LOG_DIR'] = test_outputs_dir
bazel_test_output_dir = os.environ.get('TEST_UNDECLARED_OUTPUTS_DIR')
if bazel_test_output_dir is None:
bazel_test_output_dir = os.environ.get('TEST_TMPDIR')
if 'ROS_HOME' not in os.environ:
os.environ['ROS_HOME'] = bazel_test_output_dir
if 'ROS_LOG_DIR' not in os.environ:
os.environ['ROS_LOG_DIR'] = bazel_test_output_dir

with contextlib.ExitStack() as stack:
if 'ROS_DOMAIN_ID' not in os.environ:
Expand Down
9 changes: 9 additions & 0 deletions ros2/test/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
""" Defines tests.
"""

load("@com_github_mvukov_rules_ros2//ros2:cc_defs.bzl", "ros2_cpp_test")
load(
"@com_github_mvukov_rules_ros2//ros2:interfaces.bzl",
"py_ros2_interface_library",
Expand Down Expand Up @@ -45,3 +46,11 @@ py_test(
":py_test_action",
],
)

ros2_cpp_test(
name = "test_rclcpp",
size = "small",
srcs = ["test_rclcpp.cpp"],
set_up_ament = True,
deps = ["@ros2_rclcpp//:rclcpp"],
)
32 changes: 32 additions & 0 deletions ros2/test/launch_pytest/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
load("@com_github_mvukov_rules_ros2//ros2:py_defs.bzl", "ros2_py_test")
load("@com_github_mvukov_rules_ros2//ros2:test.bzl", "ros2_test")
load("@rules_cc//cc:defs.bzl", "cc_binary")

Expand All @@ -9,7 +10,38 @@ cc_binary(

ros2_test(
name = "launch_pytest_test",
size = "small",
launch_file = "launch_pytest_test.py",
nodes = [":hello"],
use_pytest = True,
)

ros2_test(
name = "ros2_test_pytest_rclpy_init_test",
size = "small",
launch_file = "rclpy_init_test.py",
nodes = [":hello"],
use_pytest = True,
deps = ["@ros2_rclpy//:rclpy"],
)

ros2_test(
name = "ros2_test_launch_testing_rclpy_init_test",
size = "small",
launch_file = "rclpy_init_test.py",
nodes = [":hello"],
use_pytest = False,
deps = ["@ros2_rclpy//:rclpy"],
)

ros2_py_test(
name = "ros2_py_test_rclpy_init_test",
size = "small",
srcs = ["rclpy_init_test.py"],
main = "rclpy_init_test.py",
set_up_ament = True,
deps = [
"@ros2_launch//:launch_pytest",
"@ros2_rclpy//:rclpy",
],
)
31 changes: 31 additions & 0 deletions ros2/test/launch_pytest/rclpy_init_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Test rclpy.init() in different test drivers.

What is tested here is that ROS_HOME (or ROS_LOG_DIR) is set.
If it is not set, rclpy.init() will fail to initialize.

It makes sense to test this for each test driver because each uses a different
wrapper to set the environment vars.
"""
import launch
import launch_testing.actions
import launch_testing.markers
import rclpy


def test_rclpy_init():
"""This will run when using ros2_test with pytest as test driver."""
rclpy.init()


@launch_testing.markers.keep_alive
def generate_test_description():
"""This will run when using ros2_test with launch_testing as test driver."""
rclpy.init()
return launch.LaunchDescription([
launch_testing.actions.ReadyToTest(),
])


if __name__ == '__main__':
"""This will run when using ros2_py_test."""
test_rclpy_init()
28 changes: 28 additions & 0 deletions ros2/test/test_rclcpp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2023 Laurenz Altenmueller
//
// 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 <cstdlib>

#include <rclcpp/rclcpp.hpp>

int main(int argc, char** argv) {
// If neither $ROS_HOME nor $ROS_LOG_DIR are set to a valid directory,
// rclcpp:init() will fail with these errors:
// clang-format off
// 'rcutils_expand_user failed, at external/ros2_rcl_logging/rcl_logging_interface/src/logging_dir.c:81' // NOLINT
// 'Failed to get logging directory, at external/ros2_rcl_logging/rcl_logging_spdlog/src/rcl_logging_spdlog.cpp:83' // NOLINT
// clang-format on
rclcpp::init(argc, argv);
return rclcpp::shutdown() ? EXIT_SUCCESS : EXIT_FAILURE;
}