Skip to content

Commit ca3fd79

Browse files
committed
Run all run(-dep) tests natively, too
1 parent d28fb80 commit ca3fd79

File tree

4 files changed

+163
-36
lines changed

4 files changed

+163
-36
lines changed

tests/pass-dep/libc/libc-mem.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,17 @@ fn test_strcpy() {
7979
}
8080

8181
fn test_malloc() {
82-
// Test that small allocations sometimes *are* not very aligned.
83-
let saw_unaligned = (0..64).any(|_| unsafe {
84-
let p = libc::malloc(3);
85-
libc::free(p);
86-
(p as usize) % 4 != 0 // find any that this is *not* 4-aligned
87-
});
88-
assert!(saw_unaligned);
82+
// Real systems may always align to at least a specific power of 2 (like 4 or 8).
83+
#[cfg(miri)]
84+
{
85+
// Test that small allocations sometimes *are* not very aligned.
86+
let saw_unaligned = (0..64).any(|_| unsafe {
87+
let p = libc::malloc(3);
88+
libc::free(p);
89+
(p as usize) % 4 != 0 // find any that this is *not* 4-aligned
90+
});
91+
assert!(saw_unaligned);
92+
}
8993

9094
unsafe {
9195
let p1 = libc::malloc(20);

tests/pass-dep/num_cpus.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@compile-flags: -Zmiri-disable-isolation
2+
//@only-miri: fake cpu number
23

34
fn main() {
45
assert_eq!(num_cpus::get(), 1);

tests/pass-dep/page_size_override.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@compile-flags: -Zmiri-force-page-size=8
2+
//@only-miri: fake page size
23

34
fn main() {
45
let page_size = page_size::get();

tests/ui.rs

+150-29
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,22 @@ use colored::*;
99
use regex::bytes::Regex;
1010
use ui_test::build_manager::BuildManager;
1111
use ui_test::color_eyre::eyre::{Context, Result};
12+
use ui_test::custom_flags::Flag;
1213
use ui_test::custom_flags::edition::Edition;
14+
use ui_test::custom_flags::run::Run;
1315
use ui_test::dependencies::DependencyBuilder;
14-
use ui_test::per_test_config::TestConfig;
16+
use ui_test::per_test_config::{Comments, Condition, TestConfig};
1517
use ui_test::spanned::Spanned;
16-
use ui_test::{CommandBuilder, Config, Format, Match, ignore_output_conflict, status_emitter};
18+
use ui_test::{
19+
CommandBuilder, Config, Errored, Format, Match, ignore_output_conflict, status_emitter,
20+
};
1721

1822
#[derive(Copy, Clone, Debug)]
1923
enum Mode {
20-
Pass,
24+
Pass {
25+
/// Whether to compile and run with rustc instead of miri
26+
rustc: bool,
27+
},
2128
/// Requires annotations
2229
Fail,
2330
/// Not used for tests, but for `miri run --dep`
@@ -107,8 +114,89 @@ fn miri_config(
107114
..Config::rustc(path)
108115
};
109116

117+
if let Mode::Pass { rustc: true } = mode {
118+
config.comment_defaults.base().add_custom("run", Run {
119+
exit_code: 0,
120+
output_conflict_handling: Some(|path, actual, errors, config| {
121+
let path = path.with_file_name(
122+
path.file_name().unwrap().to_str().unwrap().replace(".run.", "."),
123+
);
124+
// Blessing is only allowed in miri mode, rustc mode must match
125+
ui_test::error_on_output_conflict(&path, actual, errors, config);
126+
}),
127+
});
128+
config.program.envs.push(("MIRI_BE_RUSTC".into(), Some("host".into())));
129+
130+
#[derive(Debug)]
131+
struct Strip;
132+
133+
impl Flag for Strip {
134+
fn clone_inner(&self) -> Box<dyn Flag> {
135+
Box::new(Strip)
136+
}
137+
138+
fn must_be_unique(&self) -> bool {
139+
true
140+
}
141+
142+
fn apply(
143+
&self,
144+
cmd: &mut Command,
145+
_config: &TestConfig,
146+
_build_manager: &BuildManager,
147+
) -> Result<(), Errored> {
148+
let mut c = Command::new(cmd.get_program());
149+
for (k, v) in cmd.get_envs() {
150+
match v {
151+
Some(v) => c.env(k, v),
152+
None => c.env_remove(k),
153+
};
154+
}
155+
if let Some(dir) = cmd.get_current_dir() {
156+
c.current_dir(dir);
157+
}
158+
c.args(
159+
cmd.get_args().filter(|arg| !arg.as_encoded_bytes().starts_with(b"-Zmiri-")),
160+
);
161+
*cmd = c;
162+
Ok(())
163+
}
164+
165+
fn test_condition(
166+
&self,
167+
_config: &Config,
168+
comments: &Comments,
169+
revision: &str,
170+
) -> bool {
171+
for rev in comments.for_revision(revision) {
172+
for arg in &rev.compile_flags {
173+
// A real execution will preempt, and thus behave differently
174+
if arg.starts_with("-Zmiri-preemption-rate") {
175+
return true;
176+
}
177+
// FIXME: can probably support these somehow
178+
if arg.starts_with("-Zmiri-env") {
179+
return true;
180+
}
181+
}
182+
}
183+
false
184+
}
185+
}
186+
187+
config.comment_defaults.base().add_custom("strip_dash_z_miri", Strip);
188+
189+
// Only run on no target if `only-miri` is passed.
190+
config
191+
.custom_comments
192+
.insert("only-miri", |parser, _, _| parser.only.push(Condition::Target(vec![])));
193+
} else {
194+
// Nop, we are in miri mode
195+
config.custom_comments.insert("only-miri", |_, _, _| {});
196+
}
197+
110198
config.comment_defaults.base().exit_status = match mode {
111-
Mode::Pass => Some(0),
199+
Mode::Pass { .. } => Some(0),
112200
Mode::Fail => Some(1),
113201
Mode::RunDep => None,
114202
Mode::Panic => Some(101),
@@ -128,18 +216,23 @@ fn miri_config(
128216
config.comment_defaults.base().add_custom("edition", Edition("2021".into()));
129217

130218
if let Some(WithDependencies { bless }) = with_dependencies {
219+
let program = match mode {
220+
Mode::Pass { rustc: true } => CommandBuilder::cargo(),
221+
_ =>
222+
CommandBuilder {
223+
// Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary.
224+
// (It's a separate crate, so we don't get an env var from cargo.)
225+
program: miri_path()
226+
.with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)),
227+
// There is no `cargo miri build` so we just use `cargo miri run`.
228+
args: ["miri", "run"].into_iter().map(Into::into).collect(),
229+
// Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>.
230+
envs: vec![("RUSTFLAGS".into(), None)],
231+
..CommandBuilder::cargo()
232+
},
233+
};
131234
config.comment_defaults.base().set_custom("dependencies", DependencyBuilder {
132-
program: CommandBuilder {
133-
// Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary.
134-
// (It's a separate crate, so we don't get an env var from cargo.)
135-
program: miri_path()
136-
.with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)),
137-
// There is no `cargo miri build` so we just use `cargo miri run`.
138-
args: ["miri", "run"].into_iter().map(Into::into).collect(),
139-
// Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>.
140-
envs: vec![("RUSTFLAGS".into(), None)],
141-
..CommandBuilder::cargo()
142-
},
235+
program,
143236
crate_manifest_path: Path::new("test_dependencies").join("Cargo.toml"),
144237
build_std: None,
145238
bless_lockfile: bless,
@@ -163,7 +256,19 @@ fn run_tests(
163256

164257
let mut config = miri_config(target, path, mode, with_dependencies);
165258
config.with_args(&args);
166-
config.bless_command = Some("./miri test --bless".into());
259+
if let Mode::Pass { rustc: true } = mode {
260+
config.fill_host_and_target()?;
261+
// Rustc mode only works on the host
262+
if !config.host_matches_target() {
263+
return Ok(());
264+
}
265+
config.output_conflict_handling = ui_test::ignore_output_conflict;
266+
267+
config.bless_command =
268+
Some("add `//@only-miri:` to the test if it cannot be run on the host directly".into());
269+
} else {
270+
config.bless_command = Some("./miri test --bless".into());
271+
}
167272

168273
if env::var_os("MIRI_SKIP_UI_CHECKS").is_some() {
169274
assert!(!args.bless, "cannot use RUSTC_BLESS and MIRI_SKIP_UI_CHECKS at the same time");
@@ -174,17 +279,25 @@ fn run_tests(
174279
config.program.envs.push(("MIRI_ENV_VAR_TEST".into(), Some("0".into())));
175280
// Let the tests know where to store temp files (they might run for a different target, which can make this hard to find).
176281
config.program.envs.push(("MIRI_TEMP".into(), Some(tmpdir.to_owned().into())));
177-
// If a test ICEs, we want to see a backtrace.
178-
config.program.envs.push(("RUST_BACKTRACE".into(), Some("1".into())));
179282

180283
// Add some flags we always want.
181-
config.program.args.push(
182-
format!(
183-
"--sysroot={}",
184-
env::var("MIRI_SYSROOT").expect("MIRI_SYSROOT must be set to run the ui test suite")
185-
)
186-
.into(),
187-
);
284+
match mode {
285+
// rustc mode doesn't want miri specific flags
286+
Mode::Pass { rustc: true } => {}
287+
_ => {
288+
// If a test ICEs, we want to see a backtrace.
289+
config.program.envs.push(("RUST_BACKTRACE".into(), Some("1".into())));
290+
config.program.args.push(
291+
format!(
292+
"--sysroot={}",
293+
env::var("MIRI_SYSROOT")
294+
.expect("MIRI_SYSROOT must be set to run the ui test suite")
295+
)
296+
.into(),
297+
);
298+
}
299+
}
300+
188301
config.program.args.push("-Dwarnings".into());
189302
config.program.args.push("-Dunused".into());
190303
config.program.args.push("-Ainternal_features".into());
@@ -274,7 +387,7 @@ regexes! {
274387
// Windows file paths
275388
r"\\" => "/",
276389
// erase Rust stdlib path
277-
"[^ \n`]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/",
390+
"[^ \n`]*/(rust[^/]*|checkout|rustc/[0-9a-f]+)/library/" => "RUSTLIB/",
278391
// erase platform file paths
279392
"sys/pal/[a-z]+/" => "sys/pal/PLATFORM/",
280393
// erase paths into the crate registry
@@ -327,13 +440,21 @@ fn main() -> Result<()> {
327440
}
328441
}
329442

330-
ui(Mode::Pass, "tests/pass", &target, WithoutDependencies, tmpdir.path())?;
331-
ui(Mode::Pass, "tests/pass-dep", &target, WithDependencies, tmpdir.path())?;
443+
ui(Mode::Pass { rustc: false }, "tests/pass", &target, WithoutDependencies, tmpdir.path())?;
444+
for rustc in [false, true] {
445+
ui(Mode::Pass { rustc }, "tests/pass-dep", &target, WithDependencies, tmpdir.path())?;
446+
}
332447
ui(Mode::Panic, "tests/panic", &target, WithDependencies, tmpdir.path())?;
333448
ui(Mode::Fail, "tests/fail", &target, WithoutDependencies, tmpdir.path())?;
334449
ui(Mode::Fail, "tests/fail-dep", &target, WithDependencies, tmpdir.path())?;
335450
if cfg!(unix) {
336-
ui(Mode::Pass, "tests/native-lib/pass", &target, WithoutDependencies, tmpdir.path())?;
451+
ui(
452+
Mode::Pass { rustc: false },
453+
"tests/native-lib/pass",
454+
&target,
455+
WithoutDependencies,
456+
tmpdir.path(),
457+
)?;
337458
ui(Mode::Fail, "tests/native-lib/fail", &target, WithoutDependencies, tmpdir.path())?;
338459
}
339460

0 commit comments

Comments
 (0)