diff --git a/docs/defs.md b/docs/defs.md index 19784ac84f..15f0435165 100644 --- a/docs/defs.md +++ b/docs/defs.md @@ -466,7 +466,7 @@ When building the whole binary in Bazel, use `rust_library` instead.
 rust_test(name, aliases, compile_data, crate, crate_features, crate_name, crate_root, data, deps,
           edition, env, out_dir_tar, proc_macro_deps, rustc_env, rustc_env_files, rustc_flags, srcs,
-          version)
+          use_libtest_harness, version)
 
Builds a Rust test crate. @@ -619,6 +619,7 @@ Run the test with `bazel build //hello_lib:hello_lib_test`. | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | | rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | +| use_libtest_harness | Whether to use libtest. | Boolean | optional | True | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | diff --git a/docs/flatten.md b/docs/flatten.md index 90075793e2..9606a49f68 100644 --- a/docs/flatten.md +++ b/docs/flatten.md @@ -906,7 +906,7 @@ When building the whole binary in Bazel, use `rust_library` instead.
 rust_test(name, aliases, compile_data, crate, crate_features, crate_name, crate_root, data, deps,
           edition, env, out_dir_tar, proc_macro_deps, rustc_env, rustc_env_files, rustc_flags, srcs,
-          version)
+          use_libtest_harness, version)
 
Builds a Rust test crate. @@ -1059,6 +1059,7 @@ Run the test with `bazel build //hello_lib:hello_lib_test`. | rustc_env_files | Files containing additional environment variables to set for rustc.

These files should contain a single variable per line, of format NAME=value, and newlines may be included in a value by ending a line with a trailing back-slash (\).

The order that these files will be processed is unspecified, so multiple definitions of a particular variable are discouraged. | List of labels | optional | [] | | rustc_flags | List of compiler flags passed to rustc. | List of strings | optional | [] | | srcs | List of Rust .rs source files used to build the library.

If srcs contains more than one file, then there must be a file either named lib.rs. Otherwise, crate_root must be set to the source file that is the root of the crate to be passed to rustc to build this crate. | List of labels | optional | [] | +| use_libtest_harness | Whether to use libtest. | Boolean | optional | True | | version | A version to inject in the cargo environment variable. | String | optional | "0.0.0" | diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index a7223c46b2..c1fb0fa967 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -437,7 +437,7 @@ def _rust_test_common(ctx, toolchain, output): toolchain = toolchain, crate_type = crate_type, crate_info = crate_info, - rust_flags = ["--test"], + rust_flags = ["--test"] if ctx.attr.use_libtest_harness else ["--cfg", "test"], ) return _create_test_launcher(ctx, toolchain, output, providers) @@ -703,6 +703,13 @@ _rust_test_attrs = { ["Make variable"](https://docs.bazel.build/versions/master/be/make-variables.html) substitution. """), ), + "use_libtest_harness": attr.bool( + mandatory = False, + default = True, + doc = _tidy("""\ + Whether to use libtest. + """), + ), "_launcher": attr.label( executable = True, default = Label("//util/launcher:launcher"), diff --git a/test/unit/common.bzl b/test/unit/common.bzl index 17692c2900..549931b331 100644 --- a/test/unit/common.bzl +++ b/test/unit/common.bzl @@ -28,3 +28,60 @@ def assert_argv_contains_prefix_suffix(env, action, prefix, suffix): args = action.argv, ), ) + +def assert_action_mnemonic(env, action, mnemonic): + if not action.mnemonic == mnemonic: + unittest.fail( + env, + "Expected the action to have the mnemonic '{expected}', but got '{actual}'".format( + expected = mnemonic, + actual = action.mnemonic, + ), + ) + +def _startswith(list, prefix): + if len(list) < len(prefix): + return False + for pair in zip(list[:len(prefix) + 1], prefix): + if pair[0] != pair[1]: + return False + return True + +def assert_list_contains_adjacent_elements(env, list_under_test, adjacent_elements): + """Assert that list_under_test contains given adjacent flags. + + Args: + env: env from analysistest.begin(ctx). + list_under_test: list supposed to contain adjacent elements. + adjacent_elements: list of elements to be found inside list_under_test. + """ + for idx in range(len(list_under_test)): + if list_under_test[idx] == adjacent_elements[0]: + if _startswith(list_under_test[idx:], adjacent_elements): + return + + unittest.fail( + env, + "Expected the to find '{expected}' within '{actual}'".format( + expected = adjacent_elements, + actual = list_under_test, + ), + ) + +def assert_list_contains_adjacent_elements_not(env, list_under_test, adjacent_elements): + """Assert that list_under_test does not contains given adjacent flags. + + Args: + env: env from analysistest.begin(ctx). + list_under_test: list supposed not to contain adjacent elements. + adjacent_elements: list of elements not to be found inside list_under_test.""" + for idx in range(len(list_under_test)): + if list_under_test[idx] == adjacent_elements[0]: + if _startswith(list_under_test[idx:], adjacent_elements): + unittest.fail( + env, + "Expected not the to find '{expected}' within '{actual}'".format( + expected = adjacent_elements, + actual = list_under_test, + ), + ) diff --git a/test/unit/use_libtest_harness/BUILD.bazel b/test/unit/use_libtest_harness/BUILD.bazel new file mode 100644 index 0000000000..eb9195123f --- /dev/null +++ b/test/unit/use_libtest_harness/BUILD.bazel @@ -0,0 +1,4 @@ +load(":use_libtest_harness_test.bzl", "use_libtest_harness_test_suite") + +############################ UNIT TESTS ############################# +use_libtest_harness_test_suite(name = "use_libtest_harness_test_suite") diff --git a/test/unit/use_libtest_harness/mytest.rs b/test/unit/use_libtest_harness/mytest.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/unit/use_libtest_harness/mytest_noharness.rs b/test/unit/use_libtest_harness/mytest_noharness.rs new file mode 100644 index 0000000000..e71fdf5542 --- /dev/null +++ b/test/unit/use_libtest_harness/mytest_noharness.rs @@ -0,0 +1 @@ +fn main() {} \ No newline at end of file diff --git a/test/unit/use_libtest_harness/use_libtest_harness_test.bzl b/test/unit/use_libtest_harness/use_libtest_harness_test.bzl new file mode 100644 index 0000000000..72ec2b7770 --- /dev/null +++ b/test/unit/use_libtest_harness/use_libtest_harness_test.bzl @@ -0,0 +1,66 @@ +"""Unittest to verify ordering of rust stdlib in rust_library() CcInfo""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest") +load("//rust:defs.bzl", "rust_test") +load("//test/unit:common.bzl", "assert_action_mnemonic", "assert_argv_contains", "assert_argv_contains_not", "assert_list_contains_adjacent_elements", "assert_list_contains_adjacent_elements_not") + +def _use_libtest_harness_rustc_flags_test_impl(ctx): + env = analysistest.begin(ctx) + tut = analysistest.target_under_test(env) + action = tut.actions[0] + argv = action.argv + assert_action_mnemonic(env, action, "Rustc") + assert_argv_contains(env, action, "test/unit/use_libtest_harness/mytest.rs") + assert_argv_contains(env, action, "--test") + assert_list_contains_adjacent_elements_not(env, action.argv, ["--cfg", "test"]) + return analysistest.end(env) + +def _use_libtest_harness_rustc_noharness_flags_test_impl(ctx): + env = analysistest.begin(ctx) + tut = analysistest.target_under_test(env) + action = tut.actions[0] + assert_action_mnemonic(env, action, "Rustc") + assert_argv_contains(env, action, "test/unit/use_libtest_harness/mytest_noharness.rs") + assert_argv_contains_not(env, action, "--test") + assert_list_contains_adjacent_elements(env, action.argv, ["--cfg", "test"]) + return analysistest.end(env) + +use_libtest_harness_rustc_flags_test = analysistest.make(_use_libtest_harness_rustc_flags_test_impl) +use_libtest_harness_rustc_noharness_flags_test = analysistest.make(_use_libtest_harness_rustc_noharness_flags_test_impl) + +def _use_libtest_harness_test(): + rust_test( + name = "mytest", + srcs = ["mytest.rs"], + ) + + rust_test( + name = "mytest_noharness", + srcs = ["mytest_noharness.rs"], + use_libtest_harness = False, + ) + + use_libtest_harness_rustc_flags_test( + name = "use_libtest_harness_rustc_flags_test", + target_under_test = ":mytest", + ) + + use_libtest_harness_rustc_noharness_flags_test( + name = "use_libtest_harness_rustc_noharness_flags_test", + target_under_test = ":mytest_noharness", + ) + +def use_libtest_harness_test_suite(name): + """Entry-point macro called from the BUILD file. + + Args: + name: Name of the macro. + """ + _use_libtest_harness_test() + + native.test_suite( + name = name, + tests = [ + ":use_libtest_harness_rustc_flags_test", + ], + )