-
Notifications
You must be signed in to change notification settings - Fork 17.6k
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
testing: annotate output text type #62728
Comments
|
Yup! I don't know the history of how ^V (0x16) was chosen as the current framing marker, but we would need another one probably. I'm not really sure how to pick another one, though. I assume it should probably be invisible again? I'm open to suggestions. |
The proposal looks good to me from a LUCI perspective. Implementation-wise, with the frame markers - is there any concern about race conditions when tests are run in parallel? Or maybe this is the best that is available with the current implementation. Beyond this proposal - if I can offer a CI perspective on what sort of structured data may be useful for a language like golang to generate -:
One of the best test frameworks I have come across so far in terms of structured result output is Tast [1], the integration-testing framework for ChromeOS. It captures the time, reason, file and stack trace for all errors that cause a test to fail [2]. [1] https://chromium.googlesource.com/chromiumos/platform/tast/ |
A few further thoughts:
|
This proposal has been added to the active column of the proposals project |
This seems reasonable, and following the existing framing (finding another little-used control character) seems fine too. |
Have all remaining concerns about this proposal been addressed? |
It looks like ^N and ^O are available and make a reasonable amount of sense, as these things go. |
@patrickmeiring For LUCI, I think first error makes the most sense and is the most consistent. Fatal is defined as Error+FailNow, and some programs or library code do call FailNow themselves. Code should not distinguish Error-generated messages from Fatal-calling-Error-generated messages. |
@mknyszek I'm not sure about the part where the first few lines of a crash are tagged "Error":true. It seems clearer conceptually and certainly easier implementation-wise to only tag messages from t.Fatal/t.Error with "Error":true. To tag runtime crashes you'd have to make the runtime emit the ^N and ^O or else have some easily-fooled pattern matching in test2json. #61839 is (now) about reporting a non-zero exit status in -json output. Perhaps that would be enough for crashes? You'd see the exit status and click on the full output and see the crash text. |
Will it be possible to identify there were two errors, and to distinguish error a (with possibly long output) from error b? |
Yes, there will be two ^N...^O sequences in the output. |
How will these sequences be distinguished in cmd/test2json output? It looks to me like cmd/test2json is stripping out those control characters and slicing the sequences into an arbitrary number of JSON messages. E.g. the following example output from comment 1:
Looks like it is all the same error based on the "Output" field. But this is structurally the same as the output I would expect from two errors (aaaaaaa...) and (bbbbb.....):
|
I think we could easily tag panics that are recovered and re-panicked by the testing package itself. That doesn't capture runtime fatal panics or panics from other goroutines, but I imagine that would get the vast majority of test panics and should be easy to implement in the testing package. |
@patrickmeiring I see what you mean. We need two different ways to flag an output line: "start of error" and "continuation of error". Perhaps we should use "OutputType": "error" and that leaves the door open for other kinds of OutputType as well, like we could have "OutputType": "frame" for all the framing text ("=== RUN" and so on) so test systems can decide to gray it out. ? |
Have all remaining concerns about this proposal been addressed? In go test -json output, the "Action":"output" lines would be annotated with an optional new field "OutputType" giving the kind of output included in the entry. The initial kinds would be:
The specific implementation of “error” and “error-continue” would be that in test2json mode the test would print error text wrapped in ^N...^O, and test2json would recognize and remove these, the same as it does today for ^V around framing. |
The only open question I can see is whether to capture panics on other (non-test) goroutines and report them as errors. My take here is:
Either way, the resolution of this issue need not block the proposal as even a partial ability to extract failure reasons will be a significant improvement over the status quo. |
Based on the discussion above, this proposal seems like a likely accept. In go test -json output, the "Action":"output" lines would be annotated with an optional new field "OutputType" giving the kind of output included in the entry. The initial kinds would be:
The specific implementation of “error” and “error-continue” would be that in test2json mode the test would print error text wrapped in ^N...^O, and test2json would recognize and remove these, the same as it does today for ^V around framing. |
No change in consensus, so accepted. 🎉 In go test -json output, the "Action":"output" lines would be annotated with an optional new field "OutputType" giving the kind of output included in the entry. The initial kinds would be:
The specific implementation of “error” and “error-continue” would be that in test2json mode the test would print error text wrapped in ^N...^O, and test2json would recognize and remove these, the same as it does today for ^V around framing. |
@rsc Should OutputType be empty/omitted for regular output events? As in if I |
Change https://go.dev/cl/601535 mentions this issue: |
Currently the
go test -json
provides no way to disambiguate output produced by(*testing.T).Error{,f}
and(*testing.T).Fatal{,f}
from other test logging. This fact makes it difficult for CI systems to identify what part of the output is most pertinent for constructing summaries of test failures.Consider a test that failed, producing a lot of log messages as a result. Reporting the full log of the test can often be distracting and overly specific, resulting in many CI systems (such as LUCI) not constructing test failure summaries for Go tests at all.
Heuristics such as taking the last line logged before a test fails work often, but not often enough to fully solve the problem. Enough tests call
(*testing.T).Error{,f}
and fail later (after more log output) that this heuristic is unreliable. This works even less well when considering tests that crash or panic: that last line is often going to be some random line in the stack trace.I propose adding a boolean field to "output" actions in the JSON produced by
cmd/test2json
called "Error". This field would be "true" for any "output" actions that were produced via(*testing.T).Error{,f}
and(*testing.T).Fatal{,f}
. This field would be also be "true" for the first few lines of a crash (but notably not the stack trace itself).For example:
Which lines of a crash get marked would be entirely up to
cmd/test2json
. Because it lives in the standard library, it can reasonably be coupled (with tests) to the crash output that the Go runtime produces.Testing binaries'
-test.v=test2json
output would need to be adjusted such thatcmd/test2json
could interpret errors correctly. For this, I propose the use of a new marker character (I am not picky as to which) at the beginning of a frame (delineated currently by ^V (0x16)).The text was updated successfully, but these errors were encountered: