Skip to content

Commit

Permalink
rust: add rust_test_binary rule (#316)
Browse files Browse the repository at this point in the history
I have a case where I would like to build a rust binary exactly as output by `rust_test`, but not call it directly. Instead, I have a [`sh_test`](https://docs.bazel.build/versions/master/be/shell.html#sh_test) rule that will be the entrypoint for the test, acting as a test runner and setting up environment variables required by the test code.

This already works (amazing!), but I don't want to run the binary output by `rust_test` directly, as it will fail without the setup performed in the `sh_test` rule. This happens when running all tests with:
```bash
bazel test //...
```

In this PR, I have added the new rule  `rust_test_binary` which is simply the definition of `rust_test` with `test = True` removed, and docs updated.

If there's a way to make this an argument of the existing `rust_test` rule please let me know, but I couldn't find any examples of how I might set the value of `test` on a rule dynamically.
  • Loading branch information
tommilligan committed May 14, 2020
1 parent 60b89d0 commit 619fcab
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 0 deletions.
24 changes: 24 additions & 0 deletions rust/private/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,30 @@ Run the test with `bazel build //hello_lib:hello_lib_test`.
""",
)

rust_test_binary = rule(
_rust_test_impl,
attrs = dict(_rust_common_attrs.items() +
_rust_test_attrs.items()),
executable = True,
fragments = ["cpp"],
host_fragments = ["cpp"],
toolchains = [
"@io_bazel_rules_rust//rust:toolchain",
"@bazel_tools//tools/cpp:toolchain_type",
],
doc = """
Builds a Rust test binary, without marking this rule as a Bazel test.
**Warning**: This rule is currently experimental.
This should be used when you want to run the test binary from a different test
rule (such as [`sh_test`](https://docs.bazel.build/versions/master/be/shell.html#sh_test)),
and know that running the test binary directly will fail.
See `rust_test` for example usage.
""",
)

rust_benchmark = rule(
_rust_benchmark_impl,
attrs = _rust_common_attrs,
Expand Down
4 changes: 4 additions & 0 deletions rust/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ load(
_rust_binary = "rust_binary",
_rust_library = "rust_library",
_rust_test = "rust_test",
_rust_test_binary = "rust_test_binary",
)
load(
"@io_bazel_rules_rust//rust:private/rustdoc.bzl",
Expand All @@ -37,6 +38,9 @@ rust_binary = _rust_binary
rust_test = _rust_test
""" See @io_bazel_rules_rust//rust:private/rust.bzl for a complete description. """

rust_test_binary = _rust_test_binary
""" See @io_bazel_rules_rust//rust:private/rust.bzl for a complete description. """

rust_benchmark = _rust_benchmark
""" See @io_bazel_rules_rust//rust:private/rust.bzl for a complete description. """

Expand Down
27 changes: 27 additions & 0 deletions test/rust_test_binary/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package(default_visibility = ["//visibility:public"])

load(
"//rust:rust.bzl",
"rust_test_binary",
)

# Here we build the rust binary that, when run, will run our test cases.
# However, it requires some other arbitrary setup first.
#
# If this was just `rust_test`, running `bazel test //...` would fail.
rust_test_binary(
name = "rust_test_that_requires_wrapping",
srcs = ["tests/rust_test_that_requires_wrapping.rs"],
)

# We do our arbitrary setup in another rule such as `sh_test` which can depend
# on `rust_test_binary` in its `data` attribute.
#
# This is a trivial case, but demonstrates that a rust_test_binary output can be
# executed from another test rule.
sh_test(
name = "wrapped_rust_test",
srcs = ["scripts/exec_with_test_env.sh"],
data = [":rust_test_that_requires_wrapping"],
args = ["$(location :rust_test_that_requires_wrapping)"],
)
9 changes: 9 additions & 0 deletions test/rust_test_binary/scripts/exec_with_test_env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

# Run the given binary, setting up a required test environment variable.

set -ex

export USER_DEFINED_KEY=USER_DEFINED_VALUE

"$@"
11 changes: 11 additions & 0 deletions test/rust_test_binary/tests/rust_test_that_requires_wrapping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use std::env;

#[test]
pub fn rust_test_that_requires_wrapping() {
let actual = format!(
"This test requires {} at runtime.",
env::var("USER_DEFINED_KEY").unwrap()
);
let expected = "This test requires USER_DEFINED_VALUE at runtime.";
assert_eq!(actual, expected);
}

0 comments on commit 619fcab

Please sign in to comment.