Skip to content

Commit ee11a9c

Browse files
committed
Add miri_test
1 parent e8f3393 commit ee11a9c

31 files changed

Lines changed: 1874 additions & 140 deletions

rs/experimental/miri/BUILD.bazel

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
load("@bazel_lib//:bzl_library.bzl", "bzl_library")
2+
3+
package(default_visibility = ["//visibility:private"])
4+
5+
toolchain_type(
6+
name = "toolchain_type",
7+
visibility = ["//visibility:public"],
8+
)
9+
10+
toolchain_type(
11+
name = "sysroot_toolchain_type",
12+
visibility = ["//visibility:public"],
13+
)
14+
15+
bzl_library(
16+
name = "miri_test",
17+
srcs = ["miri_test.bzl"],
18+
visibility = ["//visibility:public"],
19+
deps = [
20+
"//rs/experimental/miri/private:compile",
21+
"//rs/experimental/miri/private:providers",
22+
"//rs/experimental/miri/private:toolchain",
23+
"@bazel_features//:features",
24+
],
25+
)
26+
27+
bzl_library(
28+
name = "module_extension",
29+
srcs = ["module_extension.bzl"],
30+
visibility = ["//visibility:public"],
31+
deps = [
32+
"//rs/platforms:triples",
33+
"//rs/private:cargo_repository",
34+
"//rs/private:miri_repository",
35+
"//rs/private:module_extension_utils",
36+
"//rs/private:rustc_repository",
37+
"//rs/private:rustc_src_repository",
38+
"//rs/private:stdlib_repository",
39+
"//rs/toolchains:toolchain_utils",
40+
"@rules_rust//rust/platform:bzl_lib",
41+
"@rules_rust//rust/private:bzl_lib",
42+
],
43+
)

rs/experimental/miri/miri_test.bzl

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
"""Miri test rule."""
2+
3+
load("//rs/experimental/miri/private:compile.bzl", "alias_for_dep", "miri_compile_aspect")
4+
load("//rs/experimental/miri/private:providers.bzl", "MiriCrateInfo")
5+
load("//rs/experimental/miri/private:toolchain.bzl", "MIRI_TOOLCHAIN_TYPE")
6+
7+
def _default_crate_name(label):
8+
return label.name.replace("-", "_")
9+
10+
def _crate_root(ctx):
11+
if ctx.file.crate_root:
12+
return ctx.file.crate_root
13+
14+
for src in ctx.files.srcs:
15+
if src.basename in ("main.rs", "lib.rs"):
16+
return src
17+
18+
if len(ctx.files.srcs) == 1:
19+
return ctx.files.srcs[0]
20+
21+
fail("miri_test requires crate_root when srcs does not contain main.rs or lib.rs")
22+
23+
def _miri_extern_arg(extern):
24+
return ["--extern", "{}={}".format(extern.name, extern.output.path)]
25+
26+
def _dependency_search_dir_arg(file):
27+
return "-Ldependency={}".format(file.dirname)
28+
29+
def _miri_test_impl(ctx):
30+
toolchain = ctx.toolchains[MIRI_TOOLCHAIN_TYPE]
31+
crate_root = _crate_root(ctx)
32+
crate_name = ctx.attr.crate_name or _default_crate_name(ctx.label)
33+
direct_deps = []
34+
for dep in ctx.attr.deps:
35+
if MiriCrateInfo not in dep:
36+
continue
37+
miri_dep = dep[MiriCrateInfo]
38+
direct_deps.append(struct(
39+
name = alias_for_dep(ctx.attr.aliases, dep, miri_dep.crate_info),
40+
output = miri_dep.output,
41+
transitive_inputs = miri_dep.transitive_inputs,
42+
transitive_outputs = miri_dep.transitive_outputs,
43+
))
44+
45+
test_runner_name = ctx.label.name
46+
if ctx.executable._test_runner.extension:
47+
test_runner_name += "." + ctx.executable._test_runner.extension
48+
49+
test_runner = ctx.actions.declare_file(test_runner_name)
50+
stdout_file = ctx.actions.declare_file(test_runner.basename + ".stdout", sibling = test_runner)
51+
stderr_file = ctx.actions.declare_file(test_runner.basename + ".stderr", sibling = test_runner)
52+
exit_code_file = ctx.actions.declare_file(test_runner.basename + ".exit_code", sibling = test_runner)
53+
outputs = [stdout_file, stderr_file, exit_code_file]
54+
55+
miri_args = ctx.actions.args()
56+
miri_args.set_param_file_format("multiline")
57+
miri_args.use_param_file("@%s", use_always = True)
58+
miri_args.add_all([
59+
"--sysroot",
60+
toolchain.miri_sysroot.path,
61+
crate_root.path,
62+
"--crate-name",
63+
crate_name,
64+
"--crate-type",
65+
"bin",
66+
"--edition",
67+
ctx.attr.edition,
68+
"--test",
69+
"--target",
70+
toolchain.target_triple,
71+
"--cfg=miri",
72+
])
73+
74+
miri_args.add_all(direct_deps, map_each = _miri_extern_arg)
75+
miri_args.add_all(depset(transitive = [dep.transitive_outputs for dep in direct_deps]), map_each = _dependency_search_dir_arg)
76+
miri_args.add_all(ctx.attr.rustc_flags)
77+
miri_args.add_all(ctx.attr.miri_flags)
78+
miri_args.add("--")
79+
miri_args.add_all(ctx.attr.args)
80+
81+
process_wrapper_args = ctx.actions.args()
82+
process_wrapper_args.add("--stdout-file", stdout_file)
83+
process_wrapper_args.add("--stderr-file", stderr_file)
84+
process_wrapper_args.add("--captured-exit-code-file", exit_code_file)
85+
86+
miri_path = ctx.actions.args()
87+
miri_path.add("--")
88+
miri_path.add(toolchain.miri)
89+
90+
ctx.actions.run(
91+
executable = toolchain.process_wrapper,
92+
arguments = [process_wrapper_args, miri_path, miri_args],
93+
env = ctx.attr.env | {"MIRI_SYSROOT": toolchain.miri_sysroot.path},
94+
inputs = depset(
95+
direct = ctx.files.srcs + ctx.files.data + [crate_root],
96+
transitive = [toolchain.all_files] + [dep.transitive_inputs for dep in direct_deps],
97+
),
98+
outputs = outputs,
99+
mnemonic = "MiriTest",
100+
progress_message = "Running Miri test %{label}",
101+
toolchain = MIRI_TOOLCHAIN_TYPE,
102+
)
103+
104+
ctx.actions.symlink(
105+
output = test_runner,
106+
target_file = ctx.executable._test_runner,
107+
is_executable = True,
108+
)
109+
110+
runfiles = ctx.runfiles(files = outputs)
111+
runfiles = runfiles.merge(ctx.attr._test_runner[DefaultInfo].default_runfiles)
112+
113+
return [
114+
DefaultInfo(
115+
executable = test_runner,
116+
files = depset([test_runner]),
117+
runfiles = runfiles,
118+
),
119+
OutputGroupInfo(
120+
miri_test_exit_code = depset([exit_code_file]),
121+
miri_test_outputs = depset(outputs),
122+
miri_test_stderr = depset([stderr_file]),
123+
miri_test_stdout = depset([stdout_file]),
124+
),
125+
]
126+
127+
miri_test = rule(
128+
implementation = _miri_test_impl,
129+
attrs = {
130+
"crate_name": attr.string(doc = "Rust crate name. Defaults to the target name with '-' replaced by '_'."),
131+
"crate_root": attr.label(allow_single_file = [".rs"]),
132+
"aliases": attr.label_keyed_string_dict(doc = "Remap direct dependencies to another extern crate name."),
133+
"data": attr.label_list(allow_files = True),
134+
"deps": attr.label_list(aspects = [miri_compile_aspect]),
135+
"edition": attr.string(default = "2021"),
136+
"env": attr.string_dict(doc = "Environment variables set while running Miri."),
137+
"miri_flags": attr.string_list(doc = "Extra flags passed to the Miri driver."),
138+
"rustc_flags": attr.string_list(doc = "Extra rustc-compatible flags passed to Miri."),
139+
"srcs": attr.label_list(allow_files = [".rs"], mandatory = True),
140+
"_test_runner": attr.label(
141+
default = Label("@rules_rust//rust/private:captured_output_test_runner"),
142+
executable = True,
143+
cfg = "exec",
144+
),
145+
},
146+
test = True,
147+
toolchains = [MIRI_TOOLCHAIN_TYPE],
148+
)

0 commit comments

Comments
 (0)