Skip to content

Commit

Permalink
Added tests for pipelining with custom rules
Browse files Browse the repository at this point in the history
  • Loading branch information
gigaroby committed Aug 3, 2022
1 parent 4e01fa0 commit f4eaa71
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 21 deletions.
13 changes: 0 additions & 13 deletions test/unit/force_all_deps_direct/generator.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ load("//rust/private:providers.bzl", "BuildInfo", "CrateInfo", "DepInfo", "DepVa
# buildifier: disable=bzl-visibility
load("//rust/private:rustc.bzl", "rustc_compile_action")

# buildifier: disable=bzl-visibility
load("//rust/private:utils.bzl", "can_build_metadata")

def _generator_impl(ctx):
rs_file = ctx.actions.declare_file(ctx.label.name + "_generated.rs")
ctx.actions.run_shell(
Expand Down Expand Up @@ -42,12 +39,6 @@ EOF
lib_hash = output_hash,
extension = ".rlib",
)
rust_metadata_name = "{prefix}{name}-{lib_hash}{extension}".format(
prefix = "lib",
name = crate_name,
lib_hash = output_hash,
extension = ".rmeta",
)

deps = [DepVariantInfo(
crate_info = dep[CrateInfo] if CrateInfo in dep else None,
Expand All @@ -57,9 +48,6 @@ EOF
) for dep in ctx.attr.deps]

rust_lib = ctx.actions.declare_file(rust_lib_name)
rust_metadata = None
if can_build_metadata(toolchain, ctx, crate_type):
rust_metadata = ctx.actions.declare_file(rust_metadata_name)
return rustc_compile_action(
ctx = ctx,
attr = ctx.attr,
Expand All @@ -73,7 +61,6 @@ EOF
proc_macro_deps = depset([]),
aliases = {},
output = rust_lib,
metadata = rust_metadata,
owner = ctx.label,
edition = "2018",
compile_data = depset([]),
Expand Down
3 changes: 3 additions & 0 deletions test/unit/pipelined_compilation/custom_rule_test/to_wrap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn to_wrap() {
eprintln!("something");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use wrapper::wrap;

pub fn calls_wrap() {
wrap();
}
85 changes: 77 additions & 8 deletions test/unit/pipelined_compilation/pipelined_compilation_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("//rust:defs.bzl", "rust_binary", "rust_library", "rust_proc_macro")
load("//test/unit:common.bzl", "assert_argv_contains", "assert_list_contains_adjacent_elements", "assert_list_contains_adjacent_elements_not")
load(":wrap.bzl", "wrap")

NOT_WINDOWS = select({
"@platforms//os:linux": [],
"@platforms//os:macos": [],
"//conditions:default": ["@platforms//:incompatible"],
})

ENABLE_PIPELINING = {
"@//rust/settings:pipelined_compilation": True,
}

def _second_lib_test_impl(ctx):
env = analysistest.begin(ctx)
Expand Down Expand Up @@ -67,9 +78,6 @@ def _bin_test_impl(ctx):

return analysistest.end(env)

ENABLE_PIPELINING = {
"@//rust/settings:pipelined_compilation": True,
}
bin_test = analysistest.make(_bin_test_impl, config_settings = ENABLE_PIPELINING)
second_lib_test = analysistest.make(_second_lib_test_impl, config_settings = ENABLE_PIPELINING)

Expand Down Expand Up @@ -101,26 +109,87 @@ def _pipelined_compilation_test():
deps = [":second"],
)

NOT_WINDOWS = select({
"@platforms//os:linux": [],
"@platforms//os:macos": [],
"//conditions:default": ["@platforms//:incompatible"],
})
second_lib_test(name = "second_lib_test", target_under_test = ":second", target_compatible_with = NOT_WINDOWS)
bin_test(name = "bin_test", target_under_test = ":bin", target_compatible_with = NOT_WINDOWS)

def _custom_rule_test_impl(ctx):
env = analysistest.begin(ctx)
tut = analysistest.target_under_test(env)

# This is the metadata-generating action. It should depend on metadata for the library and, if generate_metadata is set
# also depend on metadata for 'wrapper'.
rust_action = [act for act in tut.actions if act.mnemonic == "RustcMetadata"][0]

metadata_inputs = [i for i in rust_action.inputs.to_list() if i.path.endswith(".rmeta")]
rlib_inputs = [i for i in rust_action.inputs.to_list() if i.path.endswith(".rlib")]

seen_wrapper_metadata = False
seen_to_wrap = False
for mi in metadata_inputs:
if "libwrapper" in mi.path:
seen_wrapper_metadata = True
if "libto_wrap" in mi.path:
seen_to_wrap = True

seen_wrapper_rlib = True
for ri in rlib_inputs:
if "libwrapper" in ri.path:
seen_wrapper_rlib = True

if ctx.attr.generate_metadata:
asserts.true(env, seen_wrapper_metadata, "expected dependency on metadata for 'wrapper' but not found")
else:
asserts.true(env, seen_wrapper_rlib, "expected dependency on rlib for 'wrapper' but not found")

asserts.true(env, seen_to_wrap, "expected dependency on metadata for 'to_wrap' but not found")

return analysistest.end(env)

custom_rule_test = analysistest.make(_custom_rule_test_impl, attrs = {"generate_metadata": attr.bool()}, config_settings = ENABLE_PIPELINING)

def _custom_rule_test(generate_metadata, prefix):
rust_library(
name = "to_wrap" + prefix,
crate_name = "to_wrap",
srcs = ["custom_rule_test/to_wrap.rs"],
edition = "2021",
)
wrap(
name = "wrapper" + prefix,
crate_name = "wrapper",
target = ":to_wrap" + prefix,
generate_metadata = generate_metadata,
)
rust_library(
name = "uses_wrapper" + prefix,
srcs = ["custom_rule_test/uses_wrapper.rs"],
deps = [":wrapper" + prefix],
edition = "2021",
)

custom_rule_test(
name = "custom_rule_test" + prefix,
generate_metadata = generate_metadata,
target_compatible_with = NOT_WINDOWS,
target_under_test = ":uses_wrapper" + prefix,
)

def pipelined_compilation_test_suite(name):
"""Entry-point macro called from the BUILD file.
Args:
name: Name of the macro.
"""
_pipelined_compilation_test()
_custom_rule_test(generate_metadata = True, prefix = "_with_metadata")
_custom_rule_test(generate_metadata = False, prefix = "_without_metadata")

native.test_suite(
name = name,
tests = [
":bin_test",
":second_lib_test",
":custom_rule_test_with_metadata",
":custom_rule_test_without_metadata",
],
)
106 changes: 106 additions & 0 deletions test/unit/pipelined_compilation/wrap.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
"""A custom rule that wraps a crate called to_wrap."""

# buildifier: disable=bzl-visibility
load("//rust/private:common.bzl", "rust_common")

# buildifier: disable=bzl-visibility
load("//rust/private:providers.bzl", "BuildInfo", "CrateInfo", "DepInfo", "DepVariantInfo")

# buildifier: disable=bzl-visibility
load("//rust/private:rustc.bzl", "rustc_compile_action")

def _wrap_impl(ctx):
rs_file = ctx.actions.declare_file(ctx.label.name + "_wrapped.rs")
crate_name = ctx.attr.crate_name if ctx.attr.crate_name else ctx.label.name
ctx.actions.run_shell(
outputs = [rs_file],
command = """cat <<EOF > {}
// crate_name: {}
use to_wrap::to_wrap;
pub fn wrap() {{
to_wrap();
}}
EOF
""".format(rs_file.path, crate_name),
mnemonic = "WriteWrapperRsFile",
)

toolchain = ctx.toolchains[Label("//rust:toolchain")]

# Determine unique hash for this rlib
output_hash = repr(hash(rs_file.path))
crate_type = "rlib"

rust_lib_name = "{prefix}{name}-{lib_hash}{extension}".format(
prefix = "lib",
name = crate_name,
lib_hash = output_hash,
extension = ".rlib",
)
rust_metadata_name = "{prefix}{name}-{lib_hash}{extension}".format(
prefix = "lib",
name = crate_name,
lib_hash = output_hash,
extension = ".rmeta",
)

tgt = ctx.attr.target
deps = [DepVariantInfo(
crate_info = tgt[CrateInfo] if CrateInfo in tgt else None,
dep_info = tgt[DepInfo] if DepInfo in tgt else None,
build_info = tgt[BuildInfo] if BuildInfo in tgt else None,
cc_info = tgt[CcInfo] if CcInfo in tgt else None,
)]

rust_lib = ctx.actions.declare_file(rust_lib_name)
rust_metadata = None
if ctx.attr.generate_metadata:
rust_metadata = ctx.actions.declare_file(rust_metadata_name)
return rustc_compile_action(
ctx = ctx,
attr = ctx.attr,
toolchain = toolchain,
crate_info = rust_common.create_crate_info(
name = crate_name,
type = crate_type,
root = rs_file,
srcs = depset([rs_file]),
deps = depset(deps),
proc_macro_deps = depset([]),
aliases = {},
output = rust_lib,
metadata = rust_metadata,
owner = ctx.label,
edition = "2018",
compile_data = depset([]),
rustc_env = {},
is_test = False,
),
output_hash = output_hash,
force_all_deps_direct = True,
)

wrap = rule(
implementation = _wrap_impl,
attrs = {
"target": attr.label(),
"crate_name": attr.string(),
"generate_metadata": attr.bool(default = False),
"_cc_toolchain": attr.label(
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
),
"_error_format": attr.label(
default = Label("//:error_format"),
),
"_process_wrapper": attr.label(
default = Label("//util/process_wrapper"),
executable = True,
allow_single_file = True,
cfg = "exec",
),
},
toolchains = ["@rules_rust//rust:toolchain", "@bazel_tools//tools/cpp:toolchain_type"],
incompatible_use_toolchain_transition = True,
fragments = ["cpp"],
)

0 comments on commit f4eaa71

Please sign in to comment.