Skip to content

Commit 8a7fcb8

Browse files
authored
Merge pull request #1143 from rust-lang/miri-test
Run tests with Miri
2 parents ae0b81d + a54907d commit 8a7fcb8

File tree

8 files changed

+75
-10
lines changed

8 files changed

+75
-10
lines changed

compiler/base/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ RUN rm src/*.rs
111111
COPY --from=build-orchestrator /playground/.cargo/bin/worker /playground/.cargo/bin/worker
112112
COPY --from=wasm-tools /playground/.cargo/bin/wasm-tools /playground/.cargo/bin
113113
COPY --chown=playground cargo-wasm /playground/.cargo/bin
114+
# `cargo-miri-playground` is vestigial and can be removed after a while
114115
COPY --chown=playground cargo-miri-playground /playground/.cargo/bin
115116

116117
ENTRYPOINT ["/playground/tools/entrypoint.sh"]

compiler/base/orchestrator/src/coordinator.rs

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ use crate::{
3333
DropErrorDetailsExt, TaskAbortExt as _,
3434
};
3535

36+
macro_rules! kvs {
37+
($($k:expr => $v:expr),+$(,)?) => {
38+
[
39+
$((Into::into($k), Into::into($v)),)+
40+
].into_iter()
41+
};
42+
}
43+
3644
pub mod limits;
3745

3846
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -393,7 +401,7 @@ impl LowerRequest for ExecuteRequest {
393401

394402
let mut envs = HashMap::new();
395403
if self.backtrace {
396-
envs.insert("RUST_BACKTRACE".to_owned(), "1".to_owned());
404+
envs.extend(kvs!("RUST_BACKTRACE" => "1"));
397405
}
398406

399407
ExecuteCommandRequest {
@@ -522,7 +530,7 @@ impl LowerRequest for CompileRequest {
522530
}
523531
let mut envs = HashMap::new();
524532
if self.backtrace {
525-
envs.insert("RUST_BACKTRACE".to_owned(), "1".to_owned());
533+
envs.extend(kvs!("RUST_BACKTRACE" => "1"));
526534
}
527535

528536
ExecuteCommandRequest {
@@ -660,6 +668,7 @@ pub struct MiriRequest {
660668
pub channel: Channel,
661669
pub crate_type: CrateType,
662670
pub edition: Edition,
671+
pub tests: bool,
663672
pub aliasing_model: AliasingModel,
664673
pub code: String,
665674
}
@@ -680,12 +689,25 @@ impl LowerRequest for MiriRequest {
680689
miriflags.push("-Zmiri-tree-borrows");
681690
}
682691

692+
miriflags.push("-Zmiri-disable-isolation");
693+
683694
let miriflags = miriflags.join(" ");
684695

696+
let subcommand = if self.tests { "test" } else { "run" };
697+
685698
ExecuteCommandRequest {
686699
cmd: "cargo".to_owned(),
687-
args: vec!["miri-playground".to_owned()],
688-
envs: HashMap::from_iter([("MIRIFLAGS".to_owned(), miriflags)]),
700+
args: ["miri", subcommand].map(Into::into).into(),
701+
envs: kvs! {
702+
"MIRIFLAGS" => miriflags,
703+
// Be sure that `cargo miri` will not build a new
704+
// sysroot. Creating a sysroot takes a while and Miri
705+
// will build one by default if it's missing. If
706+
// `MIRI_SYSROOT` is set and the sysroot is missing,
707+
// it will error instead.
708+
"MIRI_SYSROOT" => "/playground/.cache/miri",
709+
}
710+
.collect(),
689711
cwd: None,
690712
}
691713
}
@@ -1802,6 +1824,8 @@ impl Container {
18021824
.await
18031825
.context(AcquirePermitSnafu)?;
18041826

1827+
trace!(?execute_cargo, "starting cargo task");
1828+
18051829
let (stdin_tx, mut stdin_rx) = mpsc::channel(8);
18061830
let (stdout_tx, stdout_rx) = mpsc::channel(8);
18071831
let (stderr_tx, stderr_rx) = mpsc::channel(8);
@@ -3954,15 +3978,15 @@ mod tests {
39543978
channel: Channel::Nightly,
39553979
crate_type: CrateType::Binary,
39563980
edition: Edition::Rust2021,
3981+
tests: false,
39573982
aliasing_model: AliasingModel::Stacked,
39583983
code: String::new(),
39593984
};
39603985

39613986
#[tokio::test]
39623987
#[snafu::report]
39633988
async fn miri() -> Result<()> {
3964-
// cargo-miri-playground only exists inside the container
3965-
let coordinator = new_coordinator_docker();
3989+
let coordinator = new_coordinator();
39663990

39673991
let req = MiriRequest {
39683992
code: r#"
@@ -3987,6 +4011,36 @@ mod tests {
39874011
Ok(())
39884012
}
39894013

4014+
#[tokio::test]
4015+
#[snafu::report]
4016+
async fn miri_tests() -> Result<()> {
4017+
let coordinator = new_coordinator();
4018+
4019+
let req = MiriRequest {
4020+
tests: true,
4021+
code: r#"
4022+
#[test]
4023+
fn oops() {
4024+
unsafe { core::mem::MaybeUninit::<u8>::uninit().assume_init() };
4025+
}
4026+
"#
4027+
.into(),
4028+
..ARBITRARY_MIRI_REQUEST
4029+
};
4030+
4031+
let response = coordinator.miri(req).with_timeout().await.unwrap();
4032+
4033+
assert!(!response.success, "stderr: {}", response.stderr);
4034+
4035+
assert_contains!(response.stderr, "Undefined Behavior");
4036+
assert_contains!(response.stderr, "using uninitialized data");
4037+
assert_contains!(response.stderr, "operation requires initialized memory");
4038+
4039+
coordinator.shutdown().await?;
4040+
4041+
Ok(())
4042+
}
4043+
39904044
const ARBITRARY_MACRO_EXPANSION_REQUEST: MacroExpansionRequest = MacroExpansionRequest {
39914045
channel: Channel::Nightly,
39924046
crate_type: CrateType::Library(LibraryType::Cdylib),

ui/frontend/ToolsMenu.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ const ToolsMenu: React.FC<ToolsMenuProps> = props => {
2626
const nightlyVersion = useAppSelector(selectors.nightlyVersionText);
2727
const nightlyVersionDetails = useAppSelector(selectors.nightlyVersionDetailsText);
2828

29+
const miriRunningTests = useAppSelector(selectors.runAsTest);
30+
const miriText = miriRunningTests ? "these tests" : "this program";
31+
2932
const dispatch = useAppDispatch();
3033
const clippy = useCallback(() => {
3134
dispatch(performClippy());
@@ -62,7 +65,7 @@ const ToolsMenu: React.FC<ToolsMenuProps> = props => {
6265
name="Miri"
6366
onClick={miri}>
6467
<div>
65-
Execute this program in the Miri interpreter to detect certain
68+
Execute {miriText} in the Miri interpreter to detect certain
6669
cases of undefined behavior (like out-of-bounds memory access).
6770
</div>
6871
<MenuAside>{miriVersion} ({miriVersionDetails})</MenuAside>

ui/frontend/reducers/output/miri.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface State {
2222
interface MiriRequestBody {
2323
code: string;
2424
edition: string;
25+
tests: boolean;
2526
aliasingModel: AliasingModel;
2627
}
2728

ui/frontend/selectors/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,10 @@ export const formatRequestSelector = createSelector(
397397

398398
export const miriRequestSelector = createSelector(
399399
editionSelector,
400-
codeSelector,
400+
runAsTest,
401401
aliasingModelSelector,
402-
(edition, code, aliasingModel) => ({ edition, code, aliasingModel }),
402+
codeSelector,
403+
(edition, tests, aliasingModel, code, ) => ({ edition, tests, aliasingModel, code }),
403404
);
404405

405406
export const macroExpansionRequestSelector = createSelector(

ui/src/metrics.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ impl HasLabelsCore for coordinator::MiriRequest {
361361
channel,
362362
crate_type,
363363
edition,
364+
tests,
364365
aliasing_model: _,
365366
code: _,
366367
} = *self;
@@ -371,7 +372,7 @@ impl HasLabelsCore for coordinator::MiriRequest {
371372
mode: None,
372373
edition: Some(Some(edition)),
373374
crate_type: Some(crate_type),
374-
tests: None,
375+
tests: Some(tests),
375376
backtrace: None,
376377
}
377378
}

ui/src/public_http_api.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ pub(crate) struct MiriRequest {
103103
pub(crate) code: String,
104104
#[serde(default)]
105105
pub(crate) edition: String,
106+
#[serde(default)]
107+
pub(crate) tests: bool,
106108
#[serde(default, rename = "aliasingModel")]
107109
pub(crate) aliasing_model: Option<String>,
108110
}

ui/src/server_axum.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,7 @@ pub(crate) mod api_orchestrator_integration_impls {
12881288
let api::MiriRequest {
12891289
code,
12901290
edition,
1291+
tests,
12911292
aliasing_model,
12921293
} = other;
12931294

@@ -1300,6 +1301,7 @@ pub(crate) mod api_orchestrator_integration_impls {
13001301
channel: Channel::Nightly, // TODO: use what user has submitted
13011302
crate_type: CrateType::Binary, // TODO: use what user has submitted
13021303
edition: parse_edition(&edition)?,
1304+
tests,
13031305
aliasing_model,
13041306
code,
13051307
})

0 commit comments

Comments
 (0)