Skip to content

Commit 7b5d94b

Browse files
committed
v0
1 parent b4ab730 commit 7b5d94b

File tree

1 file changed

+77
-53
lines changed

1 file changed

+77
-53
lines changed

src/cargo/ops/cargo_test.rs

Lines changed: 77 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::ops;
55
use crate::util::errors::CargoResult;
66
use crate::util::{add_path_args, CargoTestError, Config, Test};
77
use cargo_util::ProcessError;
8+
use crossbeam_utils::thread;
89
use std::ffi::OsString;
910

1011
pub struct TestOptions {
@@ -76,63 +77,85 @@ fn run_unit_tests(
7677
compilation: &Compilation<'_>,
7778
) -> CargoResult<(Test, Vec<ProcessError>)> {
7879
let cwd = config.cwd();
79-
let mut errors = Vec::new();
80+
let mut errors: Vec<(TargetKind, String, String, anyhow::Error)> = Vec::new();
8081

81-
for UnitOutput {
82-
unit,
83-
path,
84-
script_meta,
85-
} in compilation.tests.iter()
86-
{
87-
let test = unit.target.name().to_string();
82+
thread::scope(|s| {
83+
let mut handles = vec![];
84+
let parallel = true;
8885

89-
let test_path = unit.target.src_path().path().unwrap();
90-
let exe_display = if let TargetKind::Test = unit.target.kind() {
91-
format!(
92-
"{} ({})",
93-
test_path
94-
.strip_prefix(unit.pkg.root())
95-
.unwrap_or(test_path)
96-
.display(),
97-
path.strip_prefix(cwd).unwrap_or(path).display()
98-
)
99-
} else {
100-
format!(
101-
"unittests ({})",
102-
path.strip_prefix(cwd).unwrap_or(path).display()
103-
)
104-
};
86+
for UnitOutput {
87+
unit,
88+
path,
89+
script_meta,
90+
} in compilation.tests.iter()
91+
{
92+
let test_path = unit.target.src_path().path().unwrap();
93+
let exe_display = if let TargetKind::Test = unit.target.kind() {
94+
format!(
95+
"{} ({})",
96+
test_path
97+
.strip_prefix(unit.pkg.root())
98+
.unwrap_or(test_path)
99+
.display(),
100+
path.strip_prefix(cwd).unwrap_or(path).display()
101+
)
102+
} else {
103+
format!(
104+
"unittests ({})",
105+
path.strip_prefix(cwd).unwrap_or(path).display()
106+
)
107+
};
105108

106-
let mut cmd = compilation.target_process(path, unit.kind, &unit.pkg, *script_meta)?;
107-
cmd.args(test_args);
108-
if unit.target.harness() && config.shell().verbosity() == Verbosity::Quiet {
109-
cmd.arg("--quiet");
110-
}
111-
config
112-
.shell()
113-
.concise(|shell| shell.status("Running", &exe_display))?;
114-
config
115-
.shell()
116-
.verbose(|shell| shell.status("Running", &cmd))?;
109+
let mut cmd = compilation.target_process(&path, unit.kind, &unit.pkg, *script_meta)?;
110+
cmd.args(test_args);
111+
if unit.target.harness() && config.shell().verbosity() == Verbosity::Quiet {
112+
cmd.arg("--quiet");
113+
}
114+
config
115+
.shell()
116+
.concise(|shell| shell.status("Running", &exe_display))?;
117+
config
118+
.shell()
119+
.verbose(|shell| shell.status("Running", &cmd))?;
117120

118-
let result = cmd.exec();
121+
let pkg_name = unit.pkg.name().to_string();
122+
let target = &unit.target;
123+
let handle = s.spawn(move |_| {
124+
cmd.exec().map_err(|e| {
125+
(
126+
target.kind().clone(),
127+
target.name().to_string(),
128+
pkg_name,
129+
e,
130+
)
131+
})
132+
});
133+
if parallel {
134+
handles.push(handle);
135+
} else {
136+
let result = handle.join().unwrap();
137+
if let Err(err) = result {
138+
errors.push(err);
139+
if !options.no_fail_fast {
140+
break;
141+
}
142+
}
143+
}
144+
}
119145

120-
match result {
121-
Err(e) => {
122-
let e = e.downcast::<ProcessError>()?;
123-
errors.push((
124-
unit.target.kind().clone(),
125-
test.clone(),
126-
unit.pkg.name().to_string(),
127-
e,
128-
));
146+
for handle in handles {
147+
let result = handle.join().unwrap();
148+
if let Err(err) = result {
149+
errors.push(err);
129150
if !options.no_fail_fast {
130-
break;
151+
break; // TODO: we can be clever than this
131152
}
132153
}
133-
Ok(()) => {}
134154
}
135-
}
155+
let out: Result<(), anyhow::Error> = Ok(());
156+
out
157+
})
158+
.unwrap()?;
136159

137160
if errors.len() == 1 {
138161
let (kind, name, pkg_name, e) = errors.pop().unwrap();
@@ -142,13 +165,14 @@ fn run_unit_tests(
142165
name,
143166
pkg_name,
144167
},
145-
vec![e],
168+
vec![e.downcast::<ProcessError>()?],
146169
))
147170
} else {
148-
Ok((
149-
Test::Multiple,
150-
errors.into_iter().map(|(_, _, _, e)| e).collect(),
151-
))
171+
let mut res = vec![];
172+
for (_, _, _, e) in errors.into_iter() {
173+
res.push(e.downcast::<ProcessError>()?);
174+
}
175+
Ok((Test::Multiple, res))
152176
}
153177
}
154178

0 commit comments

Comments
 (0)