Skip to content

testing: streaming output loses parallel subtest associations #38458

@rsc

Description

@rsc

Normal go test prints output like this for parallel subtests:

$ go test -run=Testdata/MIT
--- FAIL: TestTestdata (0.51s)
    --- FAIL: TestTestdata/MIT-0.t1 (0.00s)
        license_test.go:138: testdata/MIT-0.t1:1,3: diff -want +have:
            - 93.5%
            + 97.4%
            - MIT-0 100.0% 74,$
            + MIT-0 100.0% 26,$
    --- FAIL: TestTestdata/MIT-0.t2 (0.00s)
        license_test.go:138: testdata/MIT-0.t2:2,4: diff -want +have:
            - 100.0%
            + 0.0%
            - MIT-0 100.0% 0,$
    --- FAIL: TestTestdata/MIT.t3 (0.00s)
        license_test.go:138: testdata/MIT.t3:2,4: diff -want +have:
            - 100.0%
            + 0.0%
            - MIT 95.8% 0,$
    --- FAIL: TestTestdata/MIT-Header.t1 (0.00s)
        license_test.go:138: testdata/MIT-Header.t1:1,3: diff -want +have:
            - 86.9%
            + 0.0%
            - MIT-Header 100.0% 83,$
FAIL

My memory is that we made a change to try to print output earlier for -v, but this is completely breaking the output for parallel subtests. There is no obvious way to tell which test printed:

$ go test -v -run=Testdata/MIT
=== RUN   TestTestdata
=== RUN   TestTestdata/MIT-0.t1
=== PAUSE TestTestdata/MIT-0.t1
=== RUN   TestTestdata/MIT-0.t2
=== PAUSE TestTestdata/MIT-0.t2
=== RUN   TestTestdata/MIT-Header.t1
=== PAUSE TestTestdata/MIT-Header.t1
=== RUN   TestTestdata/MIT.t1
=== PAUSE TestTestdata/MIT.t1
=== RUN   TestTestdata/MIT.t2
=== PAUSE TestTestdata/MIT.t2
=== RUN   TestTestdata/MIT.t3
=== PAUSE TestTestdata/MIT.t3
=== CONT  TestTestdata/MIT-0.t1
=== CONT  TestTestdata/MIT.t1
=== CONT  TestTestdata/MIT-0.t2
=== CONT  TestTestdata/MIT.t3
=== CONT  TestTestdata/MIT.t2
=== CONT  TestTestdata/MIT-Header.t1
    TestTestdata/MIT-0.t1: license_test.go:138: testdata/MIT-0.t1:1,3: diff -want +have:
        - 93.5%
        + 97.4%
        - MIT-0 100.0% 74,$
        + MIT-0 100.0% 26,$
    TestTestdata/MIT-0.t2: license_test.go:138: testdata/MIT-0.t2:2,4: diff -want +have:
        - 100.0%
        + 0.0%
        - MIT-0 100.0% 0,$
    TestTestdata/MIT.t3: license_test.go:138: testdata/MIT.t3:2,4: diff -want +have:
        - 100.0%
        + 0.0%
        - MIT 95.8% 0,$
    TestTestdata/MIT-Header.t1: license_test.go:138: testdata/MIT-Header.t1:1,3: diff -want +have:
        - 86.9%
        + 0.0%
        - MIT-Header 100.0% 83,$
--- FAIL: TestTestdata (0.52s)
    --- FAIL: TestTestdata/MIT-0.t1 (0.00s)
    --- FAIL: TestTestdata/MIT-0.t2 (0.00s)
    --- PASS: TestTestdata/MIT.t1 (0.00s)
    --- PASS: TestTestdata/MIT.t2 (0.00s)
    --- FAIL: TestTestdata/MIT.t3 (0.00s)
    --- FAIL: TestTestdata/MIT-Header.t1 (0.00s)
FAIL

In this case, the subtest name happens to be echoed in the message, but that's because of a print in the test; the testing framework has failed at its job and omitted the information.

In contrast, here is Go 1.12:

$ go1.12 test -run=Testdata/MIT -v
=== RUN   TestTestdata
=== RUN   TestTestdata/MIT-0.t1
=== PAUSE TestTestdata/MIT-0.t1
=== RUN   TestTestdata/MIT-0.t2
=== PAUSE TestTestdata/MIT-0.t2
=== RUN   TestTestdata/MIT-Header.t1
=== PAUSE TestTestdata/MIT-Header.t1
=== RUN   TestTestdata/MIT.t1
=== PAUSE TestTestdata/MIT.t1
=== RUN   TestTestdata/MIT.t2
=== PAUSE TestTestdata/MIT.t2
=== RUN   TestTestdata/MIT.t3
=== PAUSE TestTestdata/MIT.t3
=== CONT  TestTestdata/MIT-0.t1
=== CONT  TestTestdata/MIT.t1
=== CONT  TestTestdata/MIT.t2
=== CONT  TestTestdata/MIT-Header.t1
=== CONT  TestTestdata/MIT-0.t2
=== CONT  TestTestdata/MIT.t3
--- FAIL: TestTestdata (0.57s)
    --- PASS: TestTestdata/MIT.t1 (0.00s)
    --- FAIL: TestTestdata/MIT-0.t1 (0.00s)
        license_test.go:138: testdata/MIT-0.t1:1,3: diff -want +have:
            - 93.5%
            + 97.4%
            - MIT-0 100.0% 74,$
            + MIT-0 100.0% 26,$
    --- PASS: TestTestdata/MIT.t2 (0.00s)
    --- FAIL: TestTestdata/MIT-Header.t1 (0.00s)
        license_test.go:138: testdata/MIT-Header.t1:1,3: diff -want +have:
            - 86.9%
            + 0.0%
            - MIT-Header 100.0% 83,$
    --- FAIL: TestTestdata/MIT.t3 (0.00s)
        license_test.go:138: testdata/MIT.t3:2,4: diff -want +have:
            - 100.0%
            + 0.0%
            - MIT 95.8% 0,$
    --- FAIL: TestTestdata/MIT-0.t2 (0.00s)
        license_test.go:138: testdata/MIT-0.t2:2,4: diff -want +have:
            - 100.0%
            + 0.0%
            - MIT-0 100.0% 0,$
FAIL
exit status 1
FAIL	github.com/google/licensecheck	0.882s
$ 

And here is current go with the t.Parallel call commented out:

$ go test -run=Testdata/MIT -v
=== RUN   TestTestdata
=== RUN   TestTestdata/MIT-0.t1
    TestTestdata/MIT-0.t1: license_test.go:138: testdata/MIT-0.t1:1,3: diff -want +have:
        - 93.5%
        + 97.4%
        - MIT-0 100.0% 74,$
        + MIT-0 100.0% 26,$
=== RUN   TestTestdata/MIT-0.t2
    TestTestdata/MIT-0.t2: license_test.go:138: testdata/MIT-0.t2:2,4: diff -want +have:
        - 100.0%
        + 0.0%
        - MIT-0 100.0% 0,$
=== RUN   TestTestdata/MIT-Header.t1
    TestTestdata/MIT-Header.t1: license_test.go:138: testdata/MIT-Header.t1:1,3: diff -want +have:
        - 86.9%
        + 0.0%
        - MIT-Header 100.0% 83,$
=== RUN   TestTestdata/MIT.t1
=== RUN   TestTestdata/MIT.t2
=== RUN   TestTestdata/MIT.t3
    TestTestdata/MIT.t3: license_test.go:138: testdata/MIT.t3:2,4: diff -want +have:
        - 100.0%
        + 0.0%
        - MIT 95.8% 0,$
--- FAIL: TestTestdata (0.54s)
    --- FAIL: TestTestdata/MIT-0.t1 (0.00s)
    --- FAIL: TestTestdata/MIT-0.t2 (0.00s)
    --- FAIL: TestTestdata/MIT-Header.t1 (0.00s)
    --- PASS: TestTestdata/MIT.t1 (0.00s)
    --- PASS: TestTestdata/MIT.t2 (0.00s)
    --- FAIL: TestTestdata/MIT.t3 (0.00s)
FAIL
$ 

Rolling back the change for parallel subtests would be unfortunate, since it would make the output placement dependent on use of t.Parallel. (It's already unfortunate that the output placement is dependent on -v but that ship has sailed.)

Perhaps the best fix would be to print a new === CONT line each time the test generating output changes (before the output).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions