-
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
testing: mark when parallel test begins running in output #19280
Comments
cc @mpvl |
Bump @mpvl? Happy to work on a patch, but first want to know if the current behaviour is on purpose - i.e. whether a patch would be welcome or not. |
This gets more confusing if your tests have sleeps: package main
import (
"log"
"testing"
"time"
)
func TestA(t *testing.T) {
t.Parallel()
for i := 0; i < 3; i++ {
log.Println("A")
time.Sleep(25 * time.Millisecond)
}
}
func TestB(t *testing.T) {
t.Parallel()
for i := 0; i < 3; i++ {
log.Println("B")
time.Sleep(25 * time.Millisecond)
}
} Output:
|
In order to see logging interleaved in a more structured way with test output, one would use t.Log, not println, log, or fmt. If you don't use the logging facilities of the testing package, there is no guarantees and what you see is in the realm of the possible. If you increase the number of subtasks you'll see more interleaving of printing and RUN lines. If you use t.Log, the logs will be grouped with the respective tests. In this case, tests collect the logs for this test and flush it to the parent on completion. Top-level tests flush to stdout. That said. The particular order in which things are run is very finicky, but if you find an easy way to make this more like you expect you're welcome to try. |
@mpvl you are missing the point. The log output in the example does not come from the test but from the code that is tested. I've added it to demonstrate that tests which use In my case, the example was that the last log line of an integration test was attributed to a different test which confused me because it didn't make sense. After commenting out |
My example above was perhaps misleading. My output came from the tested code too. |
Fair enough, I'll look into the issue. May take a bit, as I'm attending a summit at the moment. |
@mpvl Thank you. |
This is actually working as intended and an unfortunate consequence of the way t.Parallel works. Firstly, note that the reported behavior is identical to the case if t.Parallel is called on a bunch of top-level tests.
In other words, no matter what the parallelism is, or whether we are talking about top-level or subtests, it is pretty much guaranteed all RUNs are run before the parent test completes and that anything after t.Parallel in a subtest will be run after the parent completes. Ideally, there would be no t.Parallel and we would use something like t.Go() instead. That way we could print RUN really when the user-given function is called. So we can't fix RUN. What we could do, though, is to have another header that is printed after a test that was suspended by a call to Parallel is resumed. Something like: === RUN TestFoo The output would be the same regardless of whether -parallel=1 is passed or not. Input welcome. |
I think what you are describing is a leaking implementation detail. When |
This cannot be changed though; it goes against the spec: Aside from the restrictions opposed by the spec, your suggestion changes the semantics of the parallel test. The parallel tests may depend on initialization of the parent test. Changing this can (and probably will) lead to very obscure and hard to track bugs. Look at the very contrived example below. The output will be different (though deterministic in both cases) if you remove t.Parallel() or not.
I'm open to adding an additional RESUME or RUN PARALLEL message, but the suggest change cannot be done. |
@mpvl your I think adding the How about a separate flag that ignored all |
To clarify my last point; This is going back to my initial problem that led to opening this issue. I have a lot of parallel tests, some are failing and I want to clearly see what output comes from what test. Unless I run them one by one with |
you could define diff --git a/src/testing/testing.go b/src/testing/testing.go
index bd19a31c27..363e372d97 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -569,8 +569,14 @@ func (c *common) Skipped() bool {
}
// Parallel signals that this test is to be run in parallel with (and only with)
-// other parallel tests.
+// other parallel tests. This has no effect when test.parallel is negative.
func (t *T) Parallel() {
+ if parallel >= 0 {
+ t.parallel()
+ }
+}
+
+func (t *T) parallel() {
if t.isParallel {
panic("testing: t.Parallel called multiple times")
} (note: I didn't test this yet) |
I would be okay with adding an additional flag or setting parallelism to -1. I tend to prefer the latter one, as I think it will be easier to discover and document. |
@mpvl good point, and thanks for all the info and guidance. I'll come up with a CL soon. |
Would |
@magiconair I don't believe |
@mvdan true. |
CL https://golang.org/cl/44530 mentions this issue. |
It seems too difficult to explain why -parallel 1 should mean something different from -parallel 0 or -parallel -1. It seems like the plausible paths forward are:
|
It sounds like the RESUME headers are the best solution, and they make the output parseable for -parallel=1. Will mark accepted assuming that's the solution. CONT might be better since we've got various output that lines up to 4 letters. |
CL https://golang.org/cl/49430 mentions this issue. |
I hit a stuck test where I thought this would be helpful, so I implemented it. (Didn't help me, but now the CL is out for Go 1.10 at least.) |
What version of Go are you using (
go version
)?What operating system and processor architecture are you using (
go env
)?linux/amd64
, doesn't matter reallyWhat did you do?
Write a bunch of parallel subtests. Run them with different values of
-parallel N
.What did you expect to see?
What did you see instead?
Second command does not separate subtest outputs:
I realise this example is very stupid, but the current behavior is confusing.
-parallel
does take effect, butgo test
prints all the=== RUN
lines at once regardless. It's hard to tell when each subtest actually starts executing.And, for my particular problem, I can't tell what output is from what subtest with
-parallel 1
since the outputs aren't delimited by each of their=== RUN
lines.The text was updated successfully, but these errors were encountered: