Skip to content

Commit

Permalink
libtest: support display_output in JSON formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Emmerich committed Jul 11, 2019
1 parent 1add949 commit 409a41d
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 40 deletions.
71 changes: 40 additions & 31 deletions src/libtest/formatters/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,57 @@ impl<T: Write> JsonFormatter<T> {
Self { out }
}

fn write_message(&mut self, s: &str) -> io::Result<()> {
fn writeln_message(&mut self, s: &str) -> io::Result<()> {
assert!(!s.contains('\n'));

self.out.write_all(s.as_ref())?;
self.out.write_all(b"\n")
}

fn write_message(&mut self, s: &str) -> io::Result<()> {
assert!(!s.contains('\n'));

self.out.write_all(s.as_ref())
}

fn write_event(
&mut self,
ty: &str,
name: &str,
evt: &str,
extra: Option<String>,
stdout: Option<Cow<'_, str>>,
extra: Option<&str>,
) -> io::Result<()> {
if let Some(extras) = extra {
self.write_message(&*format!(
r#"{{ "type": "{}", "name": "{}", "event": "{}""#,
ty, name, evt
))?;
if let Some(stdout) = stdout {
self.write_message(&*format!(
r#"{{ "type": "{}", "name": "{}", "event": "{}", {} }}"#,
ty, name, evt, extras
))
} else {
r#", "stdout": "{}""#,
EscapedString(stdout)
))?;
}
if let Some(extra) = extra {
self.write_message(&*format!(
r#"{{ "type": "{}", "name": "{}", "event": "{}" }}"#,
ty, name, evt
))
r#", {}"#,
extra
))?;
}
self.writeln_message(" }")
}
}

impl<T: Write> OutputFormatter for JsonFormatter<T> {
fn write_run_start(&mut self, test_count: usize) -> io::Result<()> {
self.write_message(&*format!(
self.writeln_message(&*format!(
r#"{{ "type": "suite", "event": "started", "test_count": {} }}"#,
test_count
))
}

fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
self.write_message(&*format!(
self.writeln_message(&*format!(
r#"{{ "type": "test", "event": "started", "name": "{}" }}"#,
desc.name
))
Expand All @@ -57,34 +70,30 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
desc: &TestDesc,
result: &TestResult,
stdout: &[u8],
state: &ConsoleTestState,
) -> io::Result<()> {
let stdout = if (state.options.display_output || *result != TrOk) && stdout.len() > 0 {
Some(String::from_utf8_lossy(stdout))
} else {
None
};
match *result {
TrOk => self.write_event("test", desc.name.as_slice(), "ok", None),

TrFailed => {
let extra_data = if stdout.len() > 0 {
Some(format!(
r#""stdout": "{}""#,
EscapedString(String::from_utf8_lossy(stdout))
))
} else {
None
};
TrOk => self.write_event("test", desc.name.as_slice(), "ok", stdout, None),

self.write_event("test", desc.name.as_slice(), "failed", extra_data)
}
TrFailed => self.write_event("test", desc.name.as_slice(), "failed", stdout, None),

TrFailedMsg(ref m) => self.write_event(
"test",
desc.name.as_slice(),
"failed",
Some(format!(r#""message": "{}""#, EscapedString(m))),
stdout,
Some(&*format!(r#""message": "{}""#, EscapedString(m))),
),

TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", None),
TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", stdout, None),

TrAllowedFail => {
self.write_event("test", desc.name.as_slice(), "allowed_failure", None)
self.write_event("test", desc.name.as_slice(), "allowed_failure", stdout, None)
}

TrBench(ref bs) => {
Expand All @@ -105,20 +114,20 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
desc.name, median, deviation, mbps
);

self.write_message(&*line)
self.writeln_message(&*line)
}
}
}

fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
self.write_message(&*format!(
self.writeln_message(&*format!(
r#"{{ "type": "test", "event": "timeout", "name": "{}" }}"#,
desc.name
))
}

fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
self.write_message(&*format!(
self.writeln_message(&*format!(
"{{ \"type\": \"suite\", \
\"event\": \"{}\", \
\"passed\": {}, \
Expand Down
1 change: 1 addition & 0 deletions src/libtest/formatters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(crate) trait OutputFormatter {
desc: &TestDesc,
result: &TestResult,
stdout: &[u8],
state: &ConsoleTestState,
) -> io::Result<()>;
fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool>;
}
8 changes: 7 additions & 1 deletion src/libtest/formatters/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,13 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
Ok(())
}

fn write_result(&mut self, desc: &TestDesc, result: &TestResult, _: &[u8]) -> io::Result<()> {
fn write_result(
&mut self,
desc: &TestDesc,
result: &TestResult,
_: &[u8],
_: &ConsoleTestState,
) -> io::Result<()> {
if self.is_multithreaded {
self.write_test_name(desc)?;
}
Expand Down
8 changes: 7 additions & 1 deletion src/libtest/formatters/terse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,13 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
Ok(())
}

fn write_result(&mut self, desc: &TestDesc, result: &TestResult, _: &[u8]) -> io::Result<()> {
fn write_result(
&mut self,
desc: &TestDesc,
result: &TestResult,
_: &[u8],
_: &ConsoleTestState,
) -> io::Result<()> {
match *result {
TrOk => self.write_ok(),
TrFailed | TrFailedMsg(_) => self.write_failed(),
Expand Down
2 changes: 1 addition & 1 deletion src/libtest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
TeTimeout(ref test) => out.write_timeout(test),
TeResult(test, result, stdout) => {
st.write_log_result(&test, &result)?;
out.write_result(&test, &result, &*stdout)?;
out.write_result(&test, &result, &*stdout, &st)?;
match result {
TrOk => {
st.passed += 1;
Expand Down
12 changes: 8 additions & 4 deletions src/test/run-make-fulldeps/libtest-json/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

# Test expected libtest's JSON output

OUTPUT_FILE := $(TMPDIR)/libtest-json-output.json
OUTPUT_FILE_DEFAULT := $(TMPDIR)/libtest-json-output-default.json
OUTPUT_FILE_STDOUT_SUCCESS := $(TMPDIR)/libtest-json-output-stdout-success.json

all:
$(RUSTC) --test f.rs
RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json > $(OUTPUT_FILE) || true
RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json > $(OUTPUT_FILE_DEFAULT) || true
RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json --show-output > $(OUTPUT_FILE_STDOUT_SUCCESS) || true

cat $(OUTPUT_FILE) | "$(PYTHON)" validate_json.py
cat $(OUTPUT_FILE_DEFAULT) | "$(PYTHON)" validate_json.py
cat $(OUTPUT_FILE_STDOUT_SUCCESS) | "$(PYTHON)" validate_json.py

# Compare to output file
diff output.json $(OUTPUT_FILE)
diff output-default.json $(OUTPUT_FILE_DEFAULT)
diff output-stdout-success.json $(OUTPUT_FILE_STDOUT_SUCCESS)
3 changes: 2 additions & 1 deletion src/test/run-make-fulldeps/libtest-json/f.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#[test]
fn a() {
println!("print from successful test");
// Should pass
}

#[test]
fn b() {
assert!(false)
assert!(false);
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{ "type": "test", "event": "started", "name": "a" }
{ "type": "test", "name": "a", "event": "ok" }
{ "type": "test", "event": "started", "name": "b" }
{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:8:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
{ "type": "test", "event": "started", "name": "c" }
{ "type": "test", "name": "c", "event": "ok" }
{ "type": "test", "event": "started", "name": "d" }
Expand Down
10 changes: 10 additions & 0 deletions src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{ "type": "suite", "event": "started", "test_count": 4 }
{ "type": "test", "event": "started", "name": "a" }
{ "type": "test", "name": "a", "event": "ok", "stdout": "print from successful test\n" }
{ "type": "test", "event": "started", "name": "b" }
{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
{ "type": "test", "event": "started", "name": "c" }
{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" }
{ "type": "test", "event": "started", "name": "d" }
{ "type": "test", "name": "d", "event": "ignored" }
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0 }

0 comments on commit 409a41d

Please sign in to comment.