Skip to content

Commit b051dc6

Browse files
authored
Add cfg = _test_arg_transition in configurations/cc_test/defs.bzl (#367)
Question for the bazel experts: Does configurations/cc_test work as intended without the added `cfg = _test_arg_transition` in defs.bzl? This PR changes mytest.cc to send `argv` to stdout. Without the added `cfg = _test_arg_transition` in defs.bzl, `new arg` does not appear in the output. See below. The other changes are optional, they just make this example more complete. Not being very familiar with the bazel mechanisms, it took me a while to figure out the two tricks to 1. ensure that `args` are handled correctly, and 2. the non-transitioned test is not run. ________ **WITHOUT** the added `cfg = _test_arg_transition` in defs.bzl ``` bazel test :all --test_output=all ``` ``` MYTEST ARGV[0]: /usr/local/google/home/rwgk/.cache/bazel/_bazel_rwgk/bfd421ff56c7e52ce2de56579817e14d/sandbox/linux-sandbox/9/execroot/__main__/bazel-out/k8-fastbuild/bin/my-test.runfiles/__main__/my-test MYTEST ARGV[1]: x MYTEST ARGV[2]: y MYTEST ARGV[3]: z ``` ________ **WITH** the added `cfg = _test_arg_transition` in defs.bzl (i.e. this PR as is) ``` MYTEST ARGV[0]: /usr/local/google/home/rwgk/.cache/bazel/_bazel_rwgk/bfd421ff56c7e52ce2de56579817e14d/sandbox/linux-sandbox/4/execroot/__main__/bazel-out/k8-fastbuild-ST-54535d7cadf4/bin/my-test.runfiles/__main__/my-test MYTEST ARGV[1]: x MYTEST ARGV[2]: y MYTEST ARGV[3]: z MYTEST ARGV[4]: new arg ```
1 parent ca3f576 commit b051dc6

File tree

4 files changed

+57
-10
lines changed

4 files changed

+57
-10
lines changed

configurations/cc_test/BUILD

+5
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@ load(":defs.bzl", "test_arg_cc_test")
33
test_arg_cc_test(
44
name = "my-test",
55
srcs = ["mytest.cc"],
6+
args = [
7+
"x",
8+
"y",
9+
"z",
10+
],
611
)

configurations/cc_test/README.md

+28-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,33 @@
11
### Example showing how to use [Starlark configuration](https://bazel.build/extending/config) to write a
22
`cc_test` wrapper with a starlark transition
33

4-
the `test_arg_cc_test` macro in `defs.bzl` defines a wrapper for basically a cc_test that has been transitioned.
4+
the `test_arg_cc_test` macro in `defs.bzl` defines a wrapper for basically a `cc_test` that has been transitioned.
55
This allows, e.g., the test itself to select attribute values based on the value of that transition. There is some
66
light magic in the `transition_rule` implementation that allows dependents of the `test_arg_cc_test` macros to
7-
treat the targets it creates the exact same as a regular cc test.
7+
treat the targets it creates the exact same as a regular `cc_test`.
8+
9+
To run this example:
10+
11+
```
12+
$ bazel test :all --test_output=all
13+
```
14+
15+
```
16+
==================== Test output for //:my-test:
17+
18+
################################################################################
19+
MYTEST ARGV[0]: .../bazel-out/k8-fastbuild-ST-54535d7cadf4/bin/my-test.runfiles/__main__/my-test
20+
MYTEST ARGV[1]: x
21+
MYTEST ARGV[2]: y
22+
MYTEST ARGV[3]: z
23+
MYTEST ARGV[4]: new arg
24+
################################################################################
25+
26+
================================================================================
27+
```
28+
29+
Known limitation:
30+
31+
`bazel test :all --test_output=all --test_arg=a` does not work as expected (`--test_arg=a` is ignored).
32+
This could be fixed with the approach shown under in the ../read_attr_in_transition example,
33+
but it is omitted here to not make this example overly complex.

configurations/cc_test/defs.bzl

+11-4
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ def _test_transition_rule_impl(ctx):
2222
outputs = [executable_dst],
2323
command = "cp %s %s" % (executable_src.path, executable_dst.path),
2424
)
25-
runfiles = ctx.attr.actual_test[0][DefaultInfo].default_runfiles
25+
runfiles = ctx.attr.actual_test[DefaultInfo].default_runfiles
2626
return [DefaultInfo(runfiles = runfiles, executable = executable_dst)]
2727

2828
transition_rule_test = rule(
29+
cfg = _test_arg_transition,
2930
implementation = _test_transition_rule_impl,
3031
attrs = {
31-
"actual_test": attr.label(cfg = _test_arg_transition, executable = True),
32+
"actual_test": attr.label(cfg = "target", executable = True),
3233
"_allowlist_function_transition": attr.label(
3334
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
3435
),
@@ -37,9 +38,15 @@ transition_rule_test = rule(
3738
)
3839

3940
def test_arg_cc_test(name, **kwargs):
40-
cc_test_name = name + "_native_test"
41+
# Prepend leading underscore (_) to mark the native test as internal.
42+
cc_test_name = "_" + name + "_native_test"
4143
transition_rule_test(
4244
name = name,
45+
# bazel test picks up the args from the transitioned test.
46+
args = kwargs.pop("args", None),
4347
actual_test = ":%s" % cc_test_name,
4448
)
45-
native.cc_test(name = cc_test_name, **kwargs)
49+
50+
# The native test is built as usual, but mark as "manual" so that blaze test :all
51+
# does not run it.
52+
native.cc_test(name = cc_test_name, tags = kwargs.pop("tags", []) + ["manual"], **kwargs)

configurations/cc_test/mytest.cc

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
// a trivially passing test
1+
#include <iostream>
2+
#include <string>
23

3-
int main() {
4-
return 0;
5-
}
4+
int main(int argc, const char* argv[]) {
5+
// Send argv to stdout.
6+
std::string divider(80, '#');
7+
std::cout << '\n' << divider << '\n';
8+
for (int i = 0; i < argc; i++) {
9+
std::cout << "MYTEST ARGV[" << i << "]: " << argv[i] << '\n';
10+
}
11+
std::cout << divider << '\n' << '\n';
12+
13+
return 0; // This test always passes.
14+
}

0 commit comments

Comments
 (0)