diff --git a/docs/defs.md b/docs/defs.md index a1b55f4f3d..89d8f15c8d 100644 --- a/docs/defs.md +++ b/docs/defs.md @@ -567,7 +567,9 @@ rust_test( ) ``` -Run the test with `bazel test //hello_lib:hello_lib_test`. +Run the test with `bazel test //hello_lib:hello_lib_test`. The crate +will be built using the same crate name as the underlying ":hello_lib" +crate. ### Example: `test` directory diff --git a/docs/flatten.md b/docs/flatten.md index ab5969b550..0d4866686f 100644 --- a/docs/flatten.md +++ b/docs/flatten.md @@ -1050,7 +1050,9 @@ rust_test( ) ``` -Run the test with `bazel test //hello_lib:hello_lib_test`. +Run the test with `bazel test //hello_lib:hello_lib_test`. The crate +will be built using the same crate name as the underlying ":hello_lib" +crate. ### Example: `test` directory diff --git a/rust/private/rust.bzl b/rust/private/rust.bzl index 78ee58f196..838c925fe1 100644 --- a/rust/private/rust.bzl +++ b/rust/private/rust.bzl @@ -296,7 +296,6 @@ def _rust_test_impl(ctx): toolchain = find_toolchain(ctx) - crate_name = compute_crate_name(ctx.workspace_name, ctx.label, toolchain, ctx.attr.crate_name) crate_type = "bin" deps = transform_deps(ctx.attr.deps) proc_macro_deps = transform_deps(ctx.attr.proc_macro_deps + get_import_macro_deps(ctx)) @@ -310,8 +309,13 @@ def _rust_test_impl(ctx): # Target is building the crate in `test` config crate = ctx.attr.crate[rust_common.crate_info] if rust_common.crate_info in ctx.attr.crate else ctx.attr.crate[rust_common.test_crate_info].crate + output_hash = determine_output_hash(crate.root, ctx.label) output = ctx.actions.declare_file( - ctx.label.name + toolchain.binary_ext, + "test-%s/%s%s" % ( + output_hash, + ctx.label.name, + toolchain.binary_ext, + ), ) srcs, crate_root = transform_sources(ctx, ctx.files.srcs, getattr(ctx.file, "crate_root", None)) @@ -338,7 +342,7 @@ def _rust_test_impl(ctx): # Build the test binary using the dependency's srcs. crate_info_dict = dict( - name = crate_name, + name = crate.name, type = crate_type, root = crate.root, srcs = depset(srcs, transitive = [crate.srcs]), @@ -364,8 +368,13 @@ def _rust_test_impl(ctx): crate_root = crate_root_src(ctx.attr.name, ctx.files.srcs, crate_root_type) srcs, crate_root = transform_sources(ctx, ctx.files.srcs, crate_root) + output_hash = determine_output_hash(crate_root, ctx.label) output = ctx.actions.declare_file( - ctx.label.name + toolchain.binary_ext, + "test-%s/%s%s" % ( + output_hash, + ctx.label.name, + toolchain.binary_ext, + ), ) data_paths = depset(direct = getattr(ctx.attr, "data", [])).to_list() @@ -377,7 +386,7 @@ def _rust_test_impl(ctx): # Target is a standalone crate. Build the test binary as its own crate. crate_info_dict = dict( - name = crate_name, + name = compute_crate_name(ctx.workspace_name, ctx.label, toolchain, ctx.attr.crate_name), type = crate_type, root = crate_root, srcs = depset(srcs), @@ -1339,7 +1348,9 @@ rust_test = rule( ) ``` - Run the test with `bazel test //hello_lib:hello_lib_test`. + Run the test with `bazel test //hello_lib:hello_lib_test`. The crate + will be built using the same crate name as the underlying ":hello_lib" + crate. ### Example: `test` directory diff --git a/test/rust/src/lib.rs b/test/rust/src/lib.rs index 9dc608911f..bee47c96fb 100644 --- a/test/rust/src/lib.rs +++ b/test/rust/src/lib.rs @@ -12,4 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![crate_name = "hello_lib"] pub mod greeter; diff --git a/test/unit/linkstamps/linkstamps_test.bzl b/test/unit/linkstamps/linkstamps_test.bzl index 089972fe02..a0ae6fe519 100644 --- a/test/unit/linkstamps/linkstamps_test.bzl +++ b/test/unit/linkstamps/linkstamps_test.bzl @@ -2,7 +2,7 @@ load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") load("@rules_cc//cc:defs.bzl", "cc_library") -load("//rust:defs.bzl", "rust_binary", "rust_library", "rust_test") +load("//rust:defs.bzl", "rust_binary", "rust_common", "rust_library", "rust_test") load("//test/unit:common.bzl", "assert_action_mnemonic") def _is_running_on_linux(ctx): @@ -20,9 +20,13 @@ def _supports_linkstamps_test(ctx): linkstamp_out = linkstamp_action.outputs.to_list()[0] asserts.equals(env, linkstamp_out.basename, "linkstamp.o") tut_out = tut.files.to_list()[0] + is_test = tut[rust_common.crate_info].is_test workspace_prefix = "" if ctx.workspace_name == "rules_rust" else "/external/rules_rust" - expected_linkstamp_path = tut_out.dirname + "/_objs/" + tut_out.basename + workspace_prefix + "/test/unit/linkstamps/linkstamp.o" + # Rust compilation outputs coming from a test are put in test-{hash} directory + # which we need to remove in order to obtain the linkstamp file path. + dirname = "/".join(tut_out.dirname.split("/")[:-1]) if is_test else tut_out.dirname + expected_linkstamp_path = dirname + "/_objs/" + tut_out.basename + workspace_prefix + "/test/unit/linkstamps/linkstamp.o" asserts.equals( env, linkstamp_out.path, diff --git a/test/unit/rust_test_outputs_are_in_subdirectory/BUILD.bazel b/test/unit/rust_test_outputs_are_in_subdirectory/BUILD.bazel new file mode 100644 index 0000000000..bf00a3af7a --- /dev/null +++ b/test/unit/rust_test_outputs_are_in_subdirectory/BUILD.bazel @@ -0,0 +1,4 @@ +load(":rust_test_outputs.bzl", "rust_test_outputs_test_suite") + +############################ UNIT TESTS ############################# +rust_test_outputs_test_suite(name = "rust_test_outputs_test_suite") diff --git a/test/unit/rust_test_outputs_are_in_subdirectory/foo.rs b/test/unit/rust_test_outputs_are_in_subdirectory/foo.rs new file mode 100644 index 0000000000..da0f5d925d --- /dev/null +++ b/test/unit/rust_test_outputs_are_in_subdirectory/foo.rs @@ -0,0 +1 @@ +pub fn main() {} diff --git a/test/unit/rust_test_outputs_are_in_subdirectory/rust_test_outputs.bzl b/test/unit/rust_test_outputs_are_in_subdirectory/rust_test_outputs.bzl new file mode 100644 index 0000000000..3fb4782b39 --- /dev/null +++ b/test/unit/rust_test_outputs_are_in_subdirectory/rust_test_outputs.bzl @@ -0,0 +1,64 @@ +"""Tests for rust_test outputs directory.""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("//rust:defs.bzl", "rust_binary", "rust_common", "rust_test") + +def _rust_test_outputs_test(ctx): + env = analysistest.begin(ctx) + tut = analysistest.target_under_test(env) + + output = tut[rust_common.crate_info].output + + asserts.true(env, output.dirname.split("/")[-1].startswith("test-")) + + return analysistest.end(env) + +rust_test_outputs_test = analysistest.make( + _rust_test_outputs_test, +) + +def _rust_test_outputs_targets(): + rust_binary( + name = "bin_outputs", + srcs = ["foo.rs"], + edition = "2018", + ) + + rust_test( + name = "test_outputs_with_srcs", + srcs = ["foo.rs"], + edition = "2018", + ) + + rust_test_outputs_test( + name = "rust_test_outputs_using_srcs_attr", + target_under_test = ":test_outputs_with_srcs", + ) + + rust_test( + name = "test_outputs_with_crate", + crate = "bin_outputs", + edition = "2018", + ) + + rust_test_outputs_test( + name = "rust_test_outputs_using_crate_attr", + target_under_test = ":test_outputs_with_crate", + ) + +def rust_test_outputs_test_suite(name): + """Entry-point macro called from the BUILD file. + + Args: + name: Name of the macro. + """ + + _rust_test_outputs_targets() + + native.test_suite( + name = name, + tests = [ + ":rust_test_outputs_using_srcs_attr", + ":rust_test_outputs_using_crate_attr", + ], + )