-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
cmd/test2json: filtering out testing service messages or mark them in a special way #23036
Comments
CC @rsc To be clear, the output is all in a JSON format, right? You are talking specifically about lines like
You are suggesting that test2json should omit those lines, or mark them in some way that lets them be distinguished from other Is that right? |
Yes, please consider following test:
Now it will produces following output:
But should produce either this one:
or
|
The whole design here is that test2json reads the test output (because the test may crash or have prints directly to stdout/stderr and therefore cannot be trusted to print JSON itself). If a test is going out of its way to print invalid framing, then test2json is going to get confused, and I'm sorry but there's very little we can do about it. I think this is working well enough. Have you ever seen this in practice? |
In my experience, the assumptions like "let's use that string as a marker since nobody will use it in the real programs" fail in few months :(
Unfortunately, yes, we had several bug reports related to it. This one was easy to find: go-lang-plugin-org/go-lang-idea-plugin#2678 |
Perhaps test2json could make up a random string delimiter (like multipart/mime) and pass it to the child process to use. |
OK, but at least that bug is not as trivial as the reproduction you've reported. It is doing ordinary output as part of the test, which will be indented differently and can therefore be distinguished from the usual FAIL lines. In fact, test2json almost handles it correctly:
It has dropped the ---FAIL line entirely, which is wrong, but fixable. I'm happy to fix that. The mime random string is the obvious answer (or just some flag that turns on a fixed string like "\xff\x00") but I'm not interested in the complexity of adding a new flag until it's clearer that we must. |
Change https://golang.org/cl/86238 mentions this issue: |
Ian asked for an example, so I gave the minimal one. Despite I brought the bug report, my initial intention (as it's stated in the issue description) is to exclude service-output on the client that doesn't make much sense in Is there a guarantee that all service output like "===RUN" is going to be printed without indent, and all other output will have non-zero indentation? If so, test2json itself or its clients could filter them out. |
Yes, I think your example sidetracked the issue. The real issue is whether the generated JSON should have some easy way to distinguish the framing messages from any other test output. Reopening. |
I don't think you should attempt to exclude that output, for a variety of reasons (parallel tests being one). It's certainly not a release blocker at this point. |
And to emphasize what I wrote above, I'm not interested in the complexity of adding a new flag until it's clearer that we must. So real examples of how this might innocently occur would be welcome and would help change the priority here. Without real examples I think this is not worth fixing further. |
What's about parallel tests? They usually produce even more service messages. Could you please elaborate the rest reasons? Not sure what example you expect, but here is my case. Outputs of different tests are split based on JSON. There is no need to show these "===RUN", "=== PAUSE", etc, they only make reading of test's output difficult. |
Offtopic. Speaking of parallel tests. Please look at the screenshot. Is this expected that output of
|
@zolotov Yes, it is expected. Tests should use t.Log/t.Error and not fmt.Printf. If they insist on using fmt.Printf then we will assign it as best we can, but it can't be perfect. In the case of parallel tests there are multiple tests all running simultaneously. If they print to os.Stdout directly, there's literally no way to tell the output apart. test2json does the best it can, which is to assign the output to the test named in the most recent CONT line. If tests are running in parallel, then sorry, but they can't print to os.Stdout/os.Stderr directly and expect magic to happen to figure out which test printed what. This is basically the same reason I don't think we need to worry about tests that print raw framing to os.Stdout/os.Stderr. If you write a test that goes out of its way to make the output confusing, well, the output will be confusing. Note that as of my CL above, test2json now correctly handles framing printed by t.Log/t.Error. And it has always correctly handled parallel test output printed using t.Log/t.Error. The problems only happen when tests make direct prints to os.Stdout/os.Stderr. I don't believe the answer has to be more complexity. The answer is don't do that. |
@rsc I think it's ok to require using t.Log/t.Error in tests, but it might be a production code (that is invoked during testing) that prints directly to os.Stdout/os.Stderr and there is no way to invoke t.Log/t.Error there. Regarding omitting service-messages, is the example I provided good enough? What about the variety of reasons not to exclude service-messages? |
I've encountered a similar problem so I'll present my use case. I'm reading the
Generally this is working well, but I have to write some ugly string comparison to identify some of the framing messages. To reproduce the standard if testEvent.Test == "" && event.Output != "PASS\n" {
// Print event.Output
} If this Another example is trying to identify if package func isPkgFailureOutput(event TestEvent) bool {
out := event.Output
return all(
event.Test == "",
event.Action == ActionOutput,
out != "PASS\n",
out != "FAIL\n",
!strings.HasPrefix(out, "FAIL\t"+event.Package),
!strings.HasPrefix(out, "ok \t"+event.Package),
)
} It's necessary to check the output against a bunch of possible lines that are framing messages to determine if the line is test output or a framing message. A field in |
@zolotov I reported a problem over here: gotestyourself/gotestsum#22 (comment) to @dnephin where with Am I doing something wrong with how I am generating my test output? I found this with go 1.10.3 |
@robfig I don't know, sorry, I'm a client of |
Not sure I agree with one of the points above.
When writing a tool that reads in the output of E.g., in our pipeline we run This enables us to get a clear summary of packages and tests. If something goes wrong the It's possible there could be a flag for |
Change https://go.dev/cl/443596 mentions this issue: |
Test2json is parsing the output stream from the test, which includes package testing's own framing lines intermingled with other output, in particular any output printed via fmt.Printf, println, and so on. We have had recurring problems with unexpected partial output lines causing a framing line to be missed. A recent talk at GopherCon gave an example of an integration test involving Docker that happened to print \r-terminated lines instead of \n-terminated lines in some configurations, which in turn broke test2json badly. (https://www.gophercon.com/agenda/session/944259) There are also a variety of open reported issues with similar problems, which this CL also addresses. The general approach is to add a new testing flag -test.v=json that means to print additional output to help test2json. And then test2json takes advantage of that output. Among the fixes: - Identify testing framing more reliably, using ^V (golang#23036, golang#26325, golang#43683, GopherCon talk) - Test that output with \r\n endings is handled correctly (golang#43683, golang#34286) - Use === RUN in fuzz tests (golang#52636, golang#48132) - Add === RUN lines to note benchmark starts (golang#27764, golang#49505) - Print subtest --- PASS/FAIL lines as they happen (golang#29811) - Add === NAME lines to emit more test change events, such as when a subtest stops and the parent continues running. - Fix event shown in overall test failure (golang#27568) - Avoid interleaving of writes to os.Stdout and os.Stderr (golang#33419) Fixes golang#23036. Fixes golang#26325. Fixes golang#27568. Fixes golang#27764. Fixes golang#29811. Fixes golang#33419. Fixes golang#34286. Fixes golang#43683. Fixes golang#49505. Fixes golang#52636. Change-Id: Id4207b746a20693f92e52d68c6e4a7f8c41cc7c6 Reviewed-on: https://go-review.googlesource.com/c/go/+/443596 Auto-Submit: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
With
-json
parameter enabledgo test
still generates service messages like "===RUN", which don't make much sense in json-mode.I would be nice to exclude them from the output or at least mark them with an additional attribute, so the client would be able to filter these messages by themselves.
The text was updated successfully, but these errors were encountered: