Skip to content

Commit

Permalink
Add cfg = _test_arg_transition in configurations/cc_test/defs.bzl (#…
Browse files Browse the repository at this point in the history
…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
```
  • Loading branch information
rwgk authored Dec 8, 2023
1 parent ca3f576 commit b051dc6
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 10 deletions.
5 changes: 5 additions & 0 deletions configurations/cc_test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ load(":defs.bzl", "test_arg_cc_test")
test_arg_cc_test(
name = "my-test",
srcs = ["mytest.cc"],
args = [
"x",
"y",
"z",
],
)
30 changes: 28 additions & 2 deletions configurations/cc_test/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
### Example showing how to use [Starlark configuration](https://bazel.build/extending/config) to write a
`cc_test` wrapper with a starlark transition

the `test_arg_cc_test` macro in `defs.bzl` defines a wrapper for basically a cc_test that has been transitioned.
the `test_arg_cc_test` macro in `defs.bzl` defines a wrapper for basically a `cc_test` that has been transitioned.
This allows, e.g., the test itself to select attribute values based on the value of that transition. There is some
light magic in the `transition_rule` implementation that allows dependents of the `test_arg_cc_test` macros to
treat the targets it creates the exact same as a regular cc test.
treat the targets it creates the exact same as a regular `cc_test`.

To run this example:

```
$ bazel test :all --test_output=all
```

```
==================== Test output for //:my-test:
################################################################################
MYTEST ARGV[0]: .../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
################################################################################
================================================================================
```

Known limitation:

`bazel test :all --test_output=all --test_arg=a` does not work as expected (`--test_arg=a` is ignored).
This could be fixed with the approach shown under in the ../read_attr_in_transition example,
but it is omitted here to not make this example overly complex.
15 changes: 11 additions & 4 deletions configurations/cc_test/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ def _test_transition_rule_impl(ctx):
outputs = [executable_dst],
command = "cp %s %s" % (executable_src.path, executable_dst.path),
)
runfiles = ctx.attr.actual_test[0][DefaultInfo].default_runfiles
runfiles = ctx.attr.actual_test[DefaultInfo].default_runfiles
return [DefaultInfo(runfiles = runfiles, executable = executable_dst)]

transition_rule_test = rule(
cfg = _test_arg_transition,
implementation = _test_transition_rule_impl,
attrs = {
"actual_test": attr.label(cfg = _test_arg_transition, executable = True),
"actual_test": attr.label(cfg = "target", executable = True),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
Expand All @@ -37,9 +38,15 @@ transition_rule_test = rule(
)

def test_arg_cc_test(name, **kwargs):
cc_test_name = name + "_native_test"
# Prepend leading underscore (_) to mark the native test as internal.
cc_test_name = "_" + name + "_native_test"
transition_rule_test(
name = name,
# bazel test picks up the args from the transitioned test.
args = kwargs.pop("args", None),
actual_test = ":%s" % cc_test_name,
)
native.cc_test(name = cc_test_name, **kwargs)

# The native test is built as usual, but mark as "manual" so that blaze test :all
# does not run it.
native.cc_test(name = cc_test_name, tags = kwargs.pop("tags", []) + ["manual"], **kwargs)
17 changes: 13 additions & 4 deletions configurations/cc_test/mytest.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
// a trivially passing test
#include <iostream>
#include <string>

int main() {
return 0;
}
int main(int argc, const char* argv[]) {
// Send argv to stdout.
std::string divider(80, '#');
std::cout << '\n' << divider << '\n';
for (int i = 0; i < argc; i++) {
std::cout << "MYTEST ARGV[" << i << "]: " << argv[i] << '\n';
}
std::cout << divider << '\n' << '\n';

return 0; // This test always passes.
}

0 comments on commit b051dc6

Please sign in to comment.