Skip to content

Commit d4f0f35

Browse files
authored
Rollup merge of #148088 - Zalathar:test-thread, r=jieyouxu
compiletest: Simplify passing arguments to spawned test threads The current code structure was heavily influenced by wanting to match the libtest executor as closely as possible. Now that the libtest executor has been removed, we can get rid of some complexity that no longer serves a purpose in the new executor. --- The renaming of `ShouldPanic` is only semi-related, but I included it here because it's small, and as a separate PR it would have conflicted with this one. r? jieyouxu
2 parents 141c910 + bb20367 commit d4f0f35

4 files changed

Lines changed: 63 additions & 61 deletions

File tree

‎src/tools/compiletest/src/directives.rs‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::directives::line::{DirectiveLine, line_directive};
1818
usecrate::directives::needs::CachedNeedsConditions;
1919
usecrate::edition::{Edition, parse_edition};
2020
usecrate::errors::ErrorKind;
21-
usecrate::executor::{CollectedTestDesc,ShouldPanic};
21+
usecrate::executor::{CollectedTestDesc,ShouldFail};
2222
usecrate::util::static_regex;
2323
usecrate::{fatal, help};
2424

@@ -1366,18 +1366,18 @@ pub(crate) fn make_test_description(
13661366
// The `should-fail` annotation doesn't apply to pretty tests,
13671367
// since we run the pretty printer across all tests by default.
13681368
// If desired, we could add a `should-fail-pretty` annotation.
1369-
letshould_panic = matchconfig.mode{
1370-
TestMode::Pretty => ShouldPanic::No,
1371-
_ if should_fail => ShouldPanic::Yes,
1372-
_ => ShouldPanic::No,
1369+
letshould_fail = if should_fail && config.mode != TestMode::Pretty{
1370+
ShouldFail::Yes
1371+
}else{
1372+
ShouldFail::No
13731373
};
13741374

13751375
CollectedTestDesc{
13761376
name,
13771377
filterable_path: filterable_path.to_owned(),
13781378
ignore,
13791379
ignore_message,
1380-
should_panic,
1380+
should_fail,
13811381
}
13821382
}
13831383

‎src/tools/compiletest/src/directives/tests.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::directives::{
77
extract_llvm_version, extract_version_range, iter_directives, line_directive, parse_edition,
88
parse_normalize_rule,
99
};
10-
usecrate::executor::{CollectedTestDesc,ShouldPanic};
10+
usecrate::executor::{CollectedTestDesc,ShouldFail};
1111

1212
fnmake_test_description(
1313
config:&Config,
@@ -247,9 +247,9 @@ fn should_fail() {
247247
let p = Utf8Path::new("a.rs");
248248

249249
let d = make_test_description(&config, tn.clone(), p, p,"",None);
250-
assert_eq!(d.should_panic,ShouldPanic::No);
250+
assert_eq!(d.should_fail,ShouldFail::No);
251251
let d = make_test_description(&config, tn, p, p,"//@ should-fail",None);
252-
assert_eq!(d.should_panic,ShouldPanic::Yes);
252+
assert_eq!(d.should_fail,ShouldFail::Yes);
253253
}
254254

255255
#[test]

‎src/tools/compiletest/src/executor.rs‎

Lines changed: 53 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -98,32 +98,43 @@ pub(crate) fn run_tests(config: &Config, tests: Vec<CollectedTest>) -> bool {
9898
fnspawn_test_thread(
9999
id:TestId,
100100
test:&CollectedTest,
101-
completion_tx: mpsc::Sender<TestCompletion>,
101+
completion_sender: mpsc::Sender<TestCompletion>,
102102
) -> Option<thread::JoinHandle<()>>{
103103
if test.desc.ignore && !test.config.run_ignored{
104-
completion_tx
104+
completion_sender
105105
.send(TestCompletion{ id,outcome:TestOutcome::Ignored,stdout:None})
106106
.unwrap();
107107
returnNone;
108108
}
109109

110-
let runnable_test = RunnableTest::new(test);
111-
let should_panic = test.desc.should_panic;
112-
let run_test = move || run_test_inner(id, should_panic, runnable_test, completion_tx);
113-
110+
let args = TestThreadArgs{
111+
id,
112+
config:Arc::clone(&test.config),
113+
testpaths: test.testpaths.clone(),
114+
revision: test.revision.clone(),
115+
should_fail: test.desc.should_fail,
116+
completion_sender,
117+
};
114118
let thread_builder = thread::Builder::new().name(test.desc.name.clone());
115-
let join_handle = thread_builder.spawn(run_test).unwrap();
119+
let join_handle = thread_builder.spawn(move || test_thread_main(args)).unwrap();
116120
Some(join_handle)
117121
}
118122

119-
/// Runs a single test, within the dedicated thread spawned by the caller.
120-
fnrun_test_inner(
123+
/// All of the owned data needed by `test_thread_main`.
124+
structTestThreadArgs{
121125
id:TestId,
122-
should_panic:ShouldPanic,
123-
runnable_test:RunnableTest,
126+
127+
config:Arc<Config>,
128+
testpaths:TestPaths,
129+
revision:Option<String>,
130+
should_fail:ShouldFail,
131+
124132
completion_sender: mpsc::Sender<TestCompletion>,
125-
){
126-
let capture = CaptureKind::for_config(&runnable_test.config);
133+
}
134+
135+
/// Runs a single test, within the dedicated thread spawned by the caller.
136+
fntest_thread_main(args:TestThreadArgs){
137+
let capture = CaptureKind::for_config(&args.config);
127138

128139
// Install a panic-capture buffer for use by the custom panic hook.
129140
if capture.should_set_panic_hook(){
@@ -133,24 +144,42 @@ fn run_test_inner(
133144
let stdout = capture.stdout();
134145
let stderr = capture.stderr();
135146

136-
let panic_payload = panic::catch_unwind(move || runnable_test.run(stdout, stderr)).err();
147+
// Run the test, catching any panics so that we can gracefully report
148+
// failure (or success).
149+
//
150+
// FIXME(Zalathar): Ideally we would report test failures with `Result`,
151+
// and use panics only for bugs within compiletest itself, but that would
152+
// require a major overhaul of error handling in the test runners.
153+
let panic_payload = panic::catch_unwind(|| {
154+
__rust_begin_short_backtrace(|| {
155+
crate::runtest::run(
156+
&args.config,
157+
stdout,
158+
stderr,
159+
&args.testpaths,
160+
args.revision.as_deref(),
161+
);
162+
});
163+
})
164+
.err();
137165

138166
ifletSome(panic_buf) = panic_hook::take_capture_buf(){
139167
let panic_buf = panic_buf.lock().unwrap_or_else(|e| e.into_inner());
140168
// Forward any captured panic message to (captured) stderr.
141169
write!(stderr,"{panic_buf}");
142170
}
143171

144-
let outcome = match(should_panic, panic_payload){
145-
(ShouldPanic::No,None) | (ShouldPanic::Yes,Some(_)) => TestOutcome::Succeeded,
146-
(ShouldPanic::No,Some(_)) => TestOutcome::Failed{message:None},
147-
(ShouldPanic::Yes,None) => {
148-
TestOutcome::Failed{message:Some("test did not panic as expected")}
172+
// Interpret the presence/absence of a panic as test failure/success.
173+
let outcome = match(args.should_fail, panic_payload){
174+
(ShouldFail::No,None) | (ShouldFail::Yes,Some(_)) => TestOutcome::Succeeded,
175+
(ShouldFail::No,Some(_)) => TestOutcome::Failed{message:None},
176+
(ShouldFail::Yes,None) => {
177+
TestOutcome::Failed{message:Some("`//@ should-fail` test did not fail as expected")}
149178
}
150179
};
151180

152181
let stdout = capture.into_inner();
153-
completion_sender.send(TestCompletion{ id, outcome, stdout }).unwrap();
182+
args.completion_sender.send(TestCompletion{id: args.id, outcome, stdout }).unwrap();
154183
}
155184

156185
enumCaptureKind{
@@ -207,33 +236,6 @@ impl CaptureKind {
207236
#[derive(Clone,Copy,Debug,PartialEq,Eq,Hash)]
208237
structTestId(usize);
209238

210-
structRunnableTest{
211-
config:Arc<Config>,
212-
testpaths:TestPaths,
213-
revision:Option<String>,
214-
}
215-
216-
implRunnableTest{
217-
fnnew(test:&CollectedTest) -> Self{
218-
let config = Arc::clone(&test.config);
219-
let testpaths = test.testpaths.clone();
220-
let revision = test.revision.clone();
221-
Self{ config, testpaths, revision }
222-
}
223-
224-
fnrun(&self,stdout:&dynConsoleOut,stderr:&dynConsoleOut){
225-
__rust_begin_short_backtrace(|| {
226-
crate::runtest::run(
227-
Arc::clone(&self.config),
228-
stdout,
229-
stderr,
230-
&self.testpaths,
231-
self.revision.as_deref(),
232-
);
233-
});
234-
}
235-
}
236-
237239
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
238240
#[inline(never)]
239241
fn__rust_begin_short_backtrace<T,F:FnOnce() -> T>(f:F) -> T{
@@ -336,7 +338,7 @@ pub(crate) struct CollectedTestDesc {
336338
pub(crate)filterable_path:Utf8PathBuf,
337339
pub(crate)ignore:bool,
338340
pub(crate)ignore_message:Option<Cow<'static,str>>,
339-
pub(crate)should_panic:ShouldPanic,
341+
pub(crate)should_fail:ShouldFail,
340342
}
341343

342344
/// Whether console output should be colored or not.
@@ -348,9 +350,10 @@ pub enum ColorConfig {
348350
NeverColor,
349351
}
350352

351-
/// Whether test is expected to panic or not.
353+
/// Tests with `//@ should-fail` are tests of compiletest itself, and should
354+
/// be reported as successful if and only if they would have _failed_.
352355
#[derive(Copy,Clone,Debug,PartialEq,Eq,Hash)]
353-
pub(crate)enumShouldPanic{
356+
pub(crate)enumShouldFail{
354357
No,
355358
Yes,
356359
}

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::hash::{DefaultHasher, Hash, Hasher};
66
use std::io::prelude::*;
77
use std::io::{self,BufReader};
88
use std::process::{Child,Command,ExitStatus,Output,Stdio};
9-
use std::sync::Arc;
109
use std::{env, fmt, iter, str};
1110

1211
use build_helper::fs::remove_and_create_dir_all;
@@ -110,7 +109,7 @@ fn dylib_name(name: &str) -> String {
110109
}
111110

112111
pubfnrun(
113-
config:Arc<Config>,
112+
config:&Config,
114113
stdout:&dynConsoleOut,
115114
stderr:&dynConsoleOut,
116115
testpaths:&TestPaths,

0 commit comments

Comments
 (0)