Skip to content

Commit 105d648

Browse files
committed
Make logfile respect --format.
1 parent 2b8590e commit 105d648

File tree

2 files changed

+77
-67
lines changed

2 files changed

+77
-67
lines changed

library/test/src/console.rs

+77-66
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::io::prelude::Write;
66
use std::time::Instant;
77

88
use super::{
9-
bench::fmt_bench_samples,
109
cli::TestOpts,
1110
event::{CompletedTest, TestEvent},
1211
filter_tests,
@@ -15,7 +14,7 @@ use super::{
1514
options::{Options, OutputFormat},
1615
run_tests, term,
1716
test_result::TestResult,
18-
time::{TestExecTime, TestSuiteExecTime},
17+
time::TestSuiteExecTime,
1918
types::{NamePadding, TestDesc, TestDescAndFn},
2019
};
2120

@@ -29,20 +28,19 @@ impl<T: Write> Write for OutputLocation<T> {
2928
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
3029
match *self {
3130
OutputLocation::Pretty(ref mut term) => term.write(buf),
32-
OutputLocation::Raw(ref mut stdout) => stdout.write(buf),
31+
OutputLocation::Raw(ref mut stdout_or_file) => stdout_or_file.write(buf),
3332
}
3433
}
3534

3635
fn flush(&mut self) -> io::Result<()> {
3736
match *self {
3837
OutputLocation::Pretty(ref mut term) => term.flush(),
39-
OutputLocation::Raw(ref mut stdout) => stdout.flush(),
38+
OutputLocation::Raw(ref mut stdout_or_file) => stdout_or_file.flush(),
4039
}
4140
}
4241
}
4342

4443
pub struct ConsoleTestState {
45-
pub log_out: Option<File>,
4644
pub total: usize,
4745
pub passed: usize,
4846
pub failed: usize,
@@ -59,13 +57,7 @@ pub struct ConsoleTestState {
5957

6058
impl ConsoleTestState {
6159
pub fn new(opts: &TestOpts) -> io::Result<ConsoleTestState> {
62-
let log_out = match opts.logfile {
63-
Some(ref path) => Some(File::create(path)?),
64-
None => None,
65-
};
66-
6760
Ok(ConsoleTestState {
68-
log_out,
6961
total: 0,
7062
passed: 0,
7163
failed: 0,
@@ -81,54 +73,6 @@ impl ConsoleTestState {
8173
})
8274
}
8375

84-
pub fn write_log<F, S>(&mut self, msg: F) -> io::Result<()>
85-
where
86-
S: AsRef<str>,
87-
F: FnOnce() -> S,
88-
{
89-
match self.log_out {
90-
None => Ok(()),
91-
Some(ref mut o) => {
92-
let msg = msg();
93-
let msg = msg.as_ref();
94-
o.write_all(msg.as_bytes())
95-
}
96-
}
97-
}
98-
99-
pub fn write_log_result(
100-
&mut self,
101-
test: &TestDesc,
102-
result: &TestResult,
103-
exec_time: Option<&TestExecTime>,
104-
) -> io::Result<()> {
105-
self.write_log(|| {
106-
let TestDesc { name, ignore_message, .. } = test;
107-
format!(
108-
"{} {}",
109-
match *result {
110-
TestResult::TrOk => "ok".to_owned(),
111-
TestResult::TrFailed => "failed".to_owned(),
112-
TestResult::TrFailedMsg(ref msg) => format!("failed: {msg}"),
113-
TestResult::TrIgnored => {
114-
if let Some(msg) = ignore_message {
115-
format!("ignored: {msg}")
116-
} else {
117-
"ignored".to_owned()
118-
}
119-
}
120-
TestResult::TrBench(ref bs) => fmt_bench_samples(bs),
121-
TestResult::TrTimedFail => "failed (time limit exceeded)".to_owned(),
122-
},
123-
name,
124-
)
125-
})?;
126-
if let Some(exec_time) = exec_time {
127-
self.write_log(|| format!(" <{exec_time}>"))?;
128-
}
129-
self.write_log(|| "\n")
130-
}
131-
13276
fn current_test_count(&self) -> usize {
13377
self.passed + self.failed + self.ignored + self.measured
13478
}
@@ -142,7 +86,11 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Res
14286
};
14387

14488
let quiet = opts.format == OutputFormat::Terse;
145-
let mut st = ConsoleTestState::new(opts)?;
89+
90+
let mut log_out = match &opts.logfile {
91+
None => None,
92+
Some(path) => Some(OutputLocation::Raw(File::create(path)?)),
93+
};
14694

14795
let mut ntest = 0;
14896
let mut nbench = 0;
@@ -164,7 +112,9 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Res
164112
};
165113

166114
writeln!(output, "{name}: {fntype}")?;
167-
st.write_log(|| format!("{fntype} {name}\n"))?;
115+
if let Some(ref mut log_output) = log_out {
116+
writeln!(log_output, "{name}: {fntype}")?;
117+
}
168118
}
169119

170120
fn plural(count: u32, s: &str) -> String {
@@ -177,9 +127,15 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Res
177127
if !quiet {
178128
if ntest != 0 || nbench != 0 {
179129
writeln!(output)?;
130+
if let Some(ref mut log_output) = log_out {
131+
writeln!(log_output)?;
132+
}
180133
}
181134

182135
writeln!(output, "{}, {}", plural(ntest, "test"), plural(nbench, "benchmark"))?;
136+
if let Some(ref mut log_output) = log_out {
137+
writeln!(log_output, "{}, {}", plural(ntest, "test"), plural(nbench, "benchmark"))?;
138+
}
183139
}
184140

185141
Ok(())
@@ -226,25 +182,41 @@ fn on_test_event(
226182
event: &TestEvent,
227183
st: &mut ConsoleTestState,
228184
out: &mut dyn OutputFormatter,
185+
log_out: Option<&mut dyn OutputFormatter>,
229186
) -> io::Result<()> {
230187
match (*event).clone() {
231188
TestEvent::TeFiltered(filtered_tests, shuffle_seed) => {
232189
st.total = filtered_tests;
233190
out.write_run_start(filtered_tests, shuffle_seed)?;
191+
if let Some(log_output) = log_out {
192+
log_output.write_run_start(filtered_tests, shuffle_seed)?;
193+
}
234194
}
235195
TestEvent::TeFilteredOut(filtered_out) => {
236196
st.filtered_out = filtered_out;
237197
}
238-
TestEvent::TeWait(ref test) => out.write_test_start(test)?,
239-
TestEvent::TeTimeout(ref test) => out.write_timeout(test)?,
198+
TestEvent::TeWait(ref test) => {
199+
out.write_test_start(test)?;
200+
if let Some(log_output) = log_out {
201+
log_output.write_test_start(test)?;
202+
}
203+
}
204+
TestEvent::TeTimeout(ref test) => {
205+
out.write_timeout(test)?;
206+
if let Some(log_output) = log_out {
207+
log_output.write_timeout(test)?;
208+
}
209+
}
240210
TestEvent::TeResult(completed_test) => {
241211
let test = &completed_test.desc;
242212
let result = &completed_test.result;
243213
let exec_time = &completed_test.exec_time;
244214
let stdout = &completed_test.stdout;
245215

246-
st.write_log_result(test, result, exec_time.as_ref())?;
247216
out.write_result(test, result, exec_time.as_ref(), stdout, st)?;
217+
if let Some(log_output) = log_out {
218+
log_output.write_result(test, result, exec_time.as_ref(), stdout, st)?;
219+
}
248220
handle_test_result(st, completed_test);
249221
}
250222
}
@@ -282,6 +254,30 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
282254
OutputFormat::Json => Box::new(JsonFormatter::new(output)),
283255
OutputFormat::Junit => Box::new(JunitFormatter::new(output)),
284256
};
257+
258+
let mut log_out: Option<Box<dyn OutputFormatter>> = match &opts.logfile {
259+
None => None,
260+
Some(path) => {
261+
let log_output_location = OutputLocation::Raw(File::create(path)?);
262+
match opts.format {
263+
OutputFormat::Pretty => Some(Box::new(PrettyFormatter::new(
264+
log_output_location,
265+
opts.use_color(),
266+
max_name_len,
267+
is_multithreaded,
268+
opts.time_options,
269+
))),
270+
OutputFormat::Terse => Some(Box::new(TerseFormatter::new(
271+
log_output_location,
272+
opts.use_color(),
273+
max_name_len,
274+
is_multithreaded,
275+
))),
276+
OutputFormat::Json => Some(Box::new(JsonFormatter::new(log_output_location))),
277+
OutputFormat::Junit => Some(Box::new(JunitFormatter::new(log_output_location))),
278+
}
279+
}
280+
};
285281
let mut st = ConsoleTestState::new(opts)?;
286282

287283
// Prevent the usage of `Instant` in some cases:
@@ -290,12 +286,27 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
290286
let is_instant_supported = !cfg!(target_family = "wasm") && !cfg!(miri);
291287

292288
let start_time = is_instant_supported.then(Instant::now);
293-
run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;
289+
run_tests(opts, tests, |x| {
290+
on_test_event(
291+
&x,
292+
&mut st,
293+
&mut *out,
294+
match &mut log_out {
295+
None => None,
296+
Some(ref mut log_output) => Some(&mut **log_output),
297+
},
298+
)
299+
})?;
294300
st.exec_time = start_time.map(|t| TestSuiteExecTime(t.elapsed()));
295301

296302
assert!(opts.fail_fast || st.current_test_count() == st.total);
297303

298-
out.write_run_finish(&st)
304+
let out_result = out.write_run_finish(&st);
305+
let log_out_result = match &mut log_out {
306+
None => Ok(true),
307+
Some(ref mut log_output) => log_output.write_run_finish(&st),
308+
};
309+
log_out_result.and(out_result)
299310
}
300311

301312
// Calculates padding for given test description.

library/test/src/tests.rs

-1
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,6 @@ fn should_sort_failures_before_printing_them() {
778778
let mut out = PrettyFormatter::new(OutputLocation::Raw(Vec::new()), false, 10, false, None);
779779

780780
let st = console::ConsoleTestState {
781-
log_out: None,
782781
total: 0,
783782
passed: 0,
784783
failed: 0,

0 commit comments

Comments
 (0)