Skip to content

Commit 291a9a2

Browse files
committed
Signed-off-by: Michael Carroll <[email protected]>
1 parent 748de1c commit 291a9a2

File tree

8 files changed

+528
-0
lines changed

8 files changed

+528
-0
lines changed

.bazelversion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
8.2.1

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bazel-*

BUILD.bazel

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
load("@bazel_skylib//lib:selects.bzl", "selects")
2+
load("//osrf_testing_tools_cpp/bazel:defs.bzl", "test_runner_sh_test", "memory_test")
3+
4+
cc_library(
5+
name = "backward-cpp",
6+
srcs = [
7+
"osrf_testing_tools_cpp/src/memory_tools/vendor/bombela/backward-cpp/backward.cpp",
8+
"osrf_testing_tools_cpp/src/memory_tools/vendor/bombela/backward-cpp/backward.hpp"
9+
],
10+
includes = ["osrf_testing_tools_cpp/src"]
11+
)
12+
13+
cc_library(
14+
name = "memory_tools",
15+
srcs = glob(include = [
16+
"osrf_testing_tools_cpp/src/memory_tools/*.cpp",
17+
"osrf_testing_tools_cpp/src/memory_tools/*.hpp"
18+
],
19+
exclude = [
20+
"osrf_testing_tools_cpp/src/memory_tools/memory_tools.cpp"
21+
]),
22+
textual_hdrs = selects.with_or(
23+
{
24+
("@platforms//os:linux"): [
25+
"osrf_testing_tools_cpp/src/memory_tools/impl/linux.cpp",
26+
"osrf_testing_tools_cpp/src/memory_tools/impl/static_allocator.hpp",
27+
"osrf_testing_tools_cpp/src/memory_tools/impl/unix_common.cpp",
28+
"osrf_testing_tools_cpp/src/memory_tools/impl/unix_common.hpp",
29+
],
30+
}
31+
),
32+
hdrs = glob([
33+
"osrf_testing_tools_cpp/include/**/*.hpp"
34+
]),
35+
linkopts = ["-ldl"],
36+
includes = ["osrf_testing_tools_cpp/include"],
37+
deps = [":backward-cpp"],
38+
visibility = ["//visibility:public"]
39+
)
40+
41+
cc_binary(
42+
name = "libmemory_tools_interpose.so",
43+
srcs = ["osrf_testing_tools_cpp/src/memory_tools/memory_tools.cpp"],
44+
deps = [":memory_tools"],
45+
linkshared = True,
46+
)
47+
48+
cc_library(
49+
name = "test_runner_headers",
50+
hdrs = [
51+
"osrf_testing_tools_cpp/src/test_runner/execute_process.hpp",
52+
"osrf_testing_tools_cpp/src/test_runner/get_environment_variable.hpp",
53+
"osrf_testing_tools_cpp/src/test_runner/parse_environment_variable.hpp",
54+
"osrf_testing_tools_cpp/src/test_runner/starts_with.hpp",
55+
],
56+
includes = [
57+
"osrf_testing_tools_cpp/src",
58+
],
59+
)
60+
61+
cc_binary(
62+
name = "test_runner",
63+
srcs = [
64+
"osrf_testing_tools_cpp/src/test_runner/main.cpp",
65+
],
66+
deps = [
67+
":test_runner_headers",
68+
]
69+
)
70+
71+
cc_test(
72+
name = "test_parse_environment",
73+
srcs = [
74+
"osrf_testing_tools_cpp/test/test_runner/test_parse_environment_variable.cpp",
75+
],
76+
deps = [
77+
":test_runner_headers",
78+
"@googletest//:gtest_main"
79+
]
80+
)
81+
82+
cc_binary(
83+
name = "assert_env_vars_main",
84+
srcs = [
85+
"osrf_testing_tools_cpp/test/test_runner/assert_env_vars.cpp",
86+
],
87+
deps = [
88+
":test_runner_headers",
89+
"@googletest//:gtest_main"
90+
]
91+
)
92+
93+
test_runner_sh_test(
94+
name = "assert_env_vars",
95+
test_runner = ":test_runner",
96+
test_binary = ":assert_env_vars_main",
97+
test_runner_args = [
98+
"--env", "FOO=bar", "PING=pong",
99+
"--append-env", "FOO=baz"
100+
],
101+
test_args = [
102+
"--env", "FOO=bar:baz", "PING=pong"
103+
]
104+
)
105+
106+
cc_binary(
107+
name = "test_memory_tools_main",
108+
srcs = ["osrf_testing_tools_cpp/test/memory_tools/test_memory_tools.cpp"],
109+
deps = [
110+
":memory_tools",
111+
"@googletest//:gtest"
112+
],
113+
)
114+
115+
memory_test(
116+
name = "test_memory_tools",
117+
test_binary = ":test_memory_tools_main",
118+
)

MODULE.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module(
2+
name = "osrf_testing_tools_cpp",
3+
)
4+
5+
bazel_dep(name = "rules_license", version = "1.0.0")
6+
bazel_dep(name = "bazel_skylib", version = "1.7.1")
7+
bazel_dep(name = "platforms", version = "0.0.10")
8+
bazel_dep(name = "googletest", version = "1.16.0.bcr.1")

MODULE.bazel.lock

Lines changed: 262 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2+
3+
bzl_library(
4+
name = "defs",
5+
srcs = ["defs.bzl"],
6+
visibility = ["//visibility:public"],
7+
)

osrf_testing_tools_cpp/bazel/defs.bzl

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
def _test_runner_sh_test_impl(ctx):
2+
script_content = """#!/bin/sh
3+
# Script to execute {runner_label} with arguments.
4+
5+
set -e # Exit immediately if a command exits with a non-zero status.
6+
7+
RUNNER_PATH="{runner_path_prefix}/{runner_short_path}"
8+
TEST_PATH="{test_path_prefix}/{test_short_path}"
9+
RUNNER_ARGS=({test_runner_args_string})
10+
TEST_ARGS=({test_args_string})
11+
12+
echo "Executing: $RUNNER_PATH" "${{RUNNER_ARGS[@]}}" "-- $TEST_PATH ${{TEST_ARGS[@]}}"
13+
"$RUNNER_PATH" "${{RUNNER_ARGS[@]}}" -- $TEST_PATH "${{TEST_ARGS[@]}}"
14+
""".format(
15+
runner_label = ctx.attr.test_runner_binary,
16+
runner_path_prefix = ctx.attr.test_runner_binary.label.package if ctx.attr.test_runner_binary.label.package else ".",
17+
runner_short_path = ctx.attr.test_runner_binary.label.name,
18+
test_path_prefix = ctx.attr.test_binary.label.package if ctx.attr.test_binary.label.package else ".",
19+
test_short_path = ctx.attr.test_binary.label.name,
20+
test_runner_args_string = " ".join(["'{}'".format(arg) for arg in ctx.attr.test_runner_args]),
21+
test_args_string = " ".join(["'{}'".format(arg) for arg in ctx.attr.test_args]),
22+
)
23+
24+
print(script_content)
25+
26+
script_name = "{}_runner.sh".format(ctx.attr.name)
27+
ctx.actions.write(
28+
output = ctx.outputs.executable,
29+
content = script_content,
30+
is_executable = True,
31+
)
32+
33+
# The runfiles need to include the actual test_runner binary
34+
runfiles = ctx.runfiles(files = [ctx.executable.test_runner_binary, ctx.executable.test_binary])
35+
36+
return [DefaultInfo(
37+
files = depset([ctx.outputs.executable]),
38+
runfiles = runfiles,
39+
)]
40+
41+
_test_runner_sh_test = rule(
42+
implementation = _test_runner_sh_test_impl,
43+
attrs = {
44+
"test_runner_binary": attr.label(
45+
doc = "The test runner binary.",
46+
mandatory = True,
47+
executable = True,
48+
cfg = "exec", # Compile for execution platform
49+
),
50+
"test_binary": attr.label(
51+
doc = "The binary target to be tested.",
52+
mandatory = True,
53+
executable = True,
54+
cfg = "exec", # Compile for execution platform
55+
),
56+
"test_runner_args": attr.string_list(
57+
doc = "A list of arguments to pass to the test_runner.",
58+
default = [],
59+
),
60+
"test_args": attr.string_list(
61+
doc = "A list of arguments to pass to the test.",
62+
default = [],
63+
),
64+
},
65+
executable = True, # Signifies that this rule outputs an executable (the script)
66+
test = True, # Signifies that this rule can be run as a test
67+
)
68+
69+
def test_runner_sh_test(name, test_runner, test_binary, test_runner_args = [], test_args = [], **kwargs):
70+
"""
71+
Generates an sh_test that executes the given test_runner binary with specified arguments.
72+
73+
Args:
74+
name: The name of the sh_test.
75+
test_runner: The label of the cc_binary or other executable target.
76+
args: A list of strings representing the arguments to pass to the test_runner.
77+
**kwargs: Additional arguments to pass to the underlying sh_test rule.
78+
"""
79+
script_name = "{}_generated_script".format(name)
80+
81+
# Using the internal rule to generate the script
82+
_test_runner_sh_test(
83+
name = script_name,
84+
test_runner_binary = test_runner,
85+
test_runner_args = test_runner_args,
86+
test_binary = test_binary,
87+
test_args = test_args,
88+
# Ensure the generated script itself is not the test directly,
89+
# but is used by the native.sh_test
90+
testonly = True, # Mark as testonly if the script itself isn't meant for release
91+
tags = kwargs.pop("tags", []) + ["manual"], # Usually you don't run this rule directly
92+
)
93+
94+
# Create the sh_test rule using the generated script
95+
native.sh_test(
96+
name = name,
97+
srcs = [":" + script_name],
98+
data = [test_runner, test_binary],
99+
)
100+
101+
def memory_test(name, test_binary, **kwargs):
102+
script_name = "{}_generated_script".format(name)
103+
104+
memory_tools = Label("//:libmemory_tools_interpose.so")
105+
test_runner = Label("//:test_runner")
106+
test_runner_args = ["--env", "LD_PRELOAD=./libmemory_tools_interpose.so"]
107+
108+
# Using the internal rule to generate the script
109+
_test_runner_sh_test(
110+
name = script_name,
111+
test_runner_binary = test_runner,
112+
test_runner_args = test_runner_args,
113+
test_binary = test_binary,
114+
# Ensure the generated script itself is not the test directly,
115+
# but is used by the native.sh_test
116+
testonly = True, # Mark as testonly if the script itself isn't meant for release
117+
tags = kwargs.pop("tags", []) + ["manual"], # Usually you don't run this rule directly
118+
)
119+
120+
# Create the sh_test rule using the generated script
121+
native.sh_test(
122+
name = name,
123+
srcs = [":" + script_name],
124+
data = [test_runner, test_binary, memory_tools],
125+
)

osrf_testing_tools_cpp/test/memory_tools/test_memory_tools.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,9 @@ TEST(TestMemoryTools, test_static_allocation_alignment) {
255255
ASSERT_TRUE(allocator.deallocate(memory));
256256
}
257257
}
258+
259+
int main(int argc, char * argv[])
260+
{
261+
::testing::InitGoogleTest(&argc, argv);
262+
return RUN_ALL_TESTS();
263+
}

0 commit comments

Comments
 (0)