Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Libtest json output #45923

Closed
wants to merge 4 commits into from
Closed

Conversation

Gilnaa
Copy link

@Gilnaa Gilnaa commented Nov 10, 2017

Added an option to output the tests' summary in Json.
The exact format can use a good bikesheding.

A new "--format" flag is added, with the following options:

  • Pretty: The default output format.
  • Terse: Like -q
  • Json: Json

-q is now an alias to --format=terse, but any --format= overrides -q

Discussed a bit here: https://internals.rust-lang.org/t/alternate-libtest-output-format/6121/12

The actual code generating JSON is a bit messy. I thought about using serde, but I think it's simple enough, and as @matklad said, events should be outputted as they are ready.

Example:

running 2 tests
test t1 ... FAILED
test t2 ... FAILED

failures:

---- t1 stdout ----
	FLO"RP
thread 't1' panicked at 'explicit panic', f.rs:4:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.

---- t2 stdout ----
	BLARG\
thread 't2' panicked at 'assertion failed: 2 != 2', f.rs:10:1


failures:
    t1
    t2

test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out

Turns into

{
	"events": [
		{ "test": "t2", "event": "started" },
		{ "test": "t2", "event": "failed" },
		{ "test": "t1", "event": "started" },
		{ "test": "t1", "event": "failed" }
	],
	"summary": {
		"passed": 0,
		"failed": 2,
		"allowed_fail": 0,
		"ignored": 0,
		"measured": 0,
		"filtered_out": 0,
		"failures": [
			"t2": "BLARG\\
thread 't2' panicked at 'assertion failed: 2 != 2', f.rs:10:1
",
			"t1": "FLO\"RP
thread 't1' panicked at 'explicit panic', f.rs:4:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.
"
		]
	}
}

@shepmaster shepmaster added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Nov 11, 2017
@shepmaster
Copy link
Member

Auto-assigning to...

r? @Kimundi

@shepmaster shepmaster added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 11, 2017
@matklad
Copy link
Member

matklad commented Nov 11, 2017

Related issues are

#44813

rust-lang/rfcs#816

@killercup
Copy link
Member

Your JSON example output confuses me. Wasn't there discussion of outputting every event as a JSON document? This was also discussed in rust-lang/rfcs#1284.

@Gilnaa
Copy link
Author

Gilnaa commented Nov 11, 2017

Yeah, I might have misunderstood that one.
Why would you want each of them to be separate document?

Is there some consensus about how the output should look like?

Edit: What you linked is a bit in conflict with @matklad request to have separate "events" for tests' start/finish.

Otherwise, if the old RFC is acceptable, I'll close this PR and fix my code to match it.

@killercup
Copy link
Member

killercup commented Nov 11, 2017 via email

@Gilnaa
Copy link
Author

Gilnaa commented Nov 11, 2017

So then I have a few questions:

  • Why not use a streaming parser?
  • The whole difference is just using a flat structure with no commas, right?
  • How should several test threads be handled?

@killercup
Copy link
Member

killercup commented Nov 11, 2017

I have no authority to give any advice on how to do this, I'm just someone from the dev tools team who likes tools that offer machine readable output :)

Edit: What you linked is a bit in conflict with @matklad request to have separate "events" for tests' start/finish.
Otherwise, if the old RFC is acceptable, I'll close this PR and fix my code to match it.

I just wanted to point out that there's been discussion around this topic. The RFC was closed as the author wanted to rewrite it IIUC. As such, it was never accepted by the Rust team in charge.

  • Why not use a streaming parser?

Is there a good streaming JSON parser for Rust? I don't think serde_json supports this.

  • The whole difference is just using a flat structure with no commas, right?

Instead of

{
  "events": [
    { "test": "t2", "event": "started" },
    { "test": "t2", "event": "failed" },
    { "test": "t1", "event": "started" },
    { "test": "t1", "event": "failed" }
  ],
  "summary": { }
}

you'd output something like

{ "type": "test", "event": "start", "name": "foo::t2" }
{ "type": "test", "event": "start", "name": "bar::t1" }
{ "type": "test", "event": "fail", "name": "foo::t2" }
{ "type": "test", "event": "success", "name": "bar:t1" }
{ "type": "final", "summary": {  } }
  • How should several test threads be handled?

Same as right now? Does it need to change in any way? When a test is started, you emit an event, when the test finishes (it thread ends) you emit another event depending on the result of the thread (panic/no panic basically). If you really wanted, you could capture stdout/stderr and emit it (line or timeout based) as events in-between, but I haven't really thought about this.

@Gilnaa
Copy link
Author

Gilnaa commented Nov 11, 2017

I see. I'll contact the other maintainer to make sure I'm not ruining his work somehow. Thanks

As for streaming parsers, I hacked one using serde https://github.com/Gilnaa/rusty3bar/blob/master/src/infinite_array.rs
But it is not pretty

@Gilnaa Gilnaa closed this Nov 11, 2017
@dnsco
Copy link

dnsco commented Nov 11, 2017

I'm excited to see work happening in this direction, I would love to have more easily machine readable test output.

@Gilnaa Gilnaa mentioned this pull request Dec 2, 2017
bors added a commit that referenced this pull request Jan 25, 2018
Libtest json output

A revisit to my [last PR](#45923).

Events are now more atomic, printed in a flat hierarchy.

For the normal test output:
```
running 1 test
test f ... FAILED

failures:

---- f stdout ----
	thread 'f' panicked at 'assertion failed: `(left == right)`
  left: `3`,
 right: `4`', f.rs:3:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.

failures:
    f

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
```

The JSON equivalent is:
```
{ "type": "suite", "event": "started", "test_count": "1" }
{ "type": "test", "event": "started", "name": "f" }
{ "type": "test", "event": "failed", "name": "f" }
{ "type": "suite", "event": "failed", "passed": 0, "failed": 1, "allowed_fail": 0, "ignored": 0,  "measured": 0, "filtered_out": "0" }
{ "type": "test_output", "name": "f", "output": "thread 'f' panicked at 'assertion failed: `(left == right)`
  left: `3`,
 right: `4`', f.rs:3:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.
" }
```
bors added a commit that referenced this pull request Jan 26, 2018
Libtest json output

A revisit to my [last PR](#45923).

Events are now more atomic, printed in a flat hierarchy.

For the normal test output:
```
running 1 test
test f ... FAILED

failures:

---- f stdout ----
	thread 'f' panicked at 'assertion failed: `(left == right)`
  left: `3`,
 right: `4`', f.rs:3:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.

failures:
    f

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
```

The JSON equivalent is:
```
{ "type": "suite", "event": "started", "test_count": "1" }
{ "type": "test", "event": "started", "name": "f" }
{ "type": "test", "event": "failed", "name": "f" }
{ "type": "suite", "event": "failed", "passed": 0, "failed": 1, "allowed_fail": 0, "ignored": 0,  "measured": 0, "filtered_out": "0" }
{ "type": "test_output", "name": "f", "output": "thread 'f' panicked at 'assertion failed: `(left == right)`
  left: `3`,
 right: `4`', f.rs:3:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.
" }
```
bors added a commit that referenced this pull request Jan 27, 2018
Libtest json output

A revisit to my [last PR](#45923).

Events are now more atomic, printed in a flat hierarchy.

For the normal test output:
```
running 1 test
test f ... FAILED

failures:

---- f stdout ----
	thread 'f' panicked at 'assertion failed: `(left == right)`
  left: `3`,
 right: `4`', f.rs:3:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.

failures:
    f

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
```

The JSON equivalent is:
```
{ "type": "suite", "event": "started", "test_count": "1" }
{ "type": "test", "event": "started", "name": "f" }
{ "type": "test", "event": "failed", "name": "f" }
{ "type": "suite", "event": "failed", "passed": 0, "failed": 1, "allowed_fail": 0, "ignored": 0,  "measured": 0, "filtered_out": "0" }
{ "type": "test_output", "name": "f", "output": "thread 'f' panicked at 'assertion failed: `(left == right)`
  left: `3`,
 right: `4`', f.rs:3:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.
" }
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants