# Run parallel chatty tests. Assert on CONT lines. This test makes sure that # multiple parallel outputs have the appropriate CONT lines between them. ! go test -parallel 3 chatty_parallel_test.go -v stdout -count=1 '^=== CONT TestChattyParallel/sub-0\n chatty_parallel_test.go:38: error from sub-0$' stdout -count=1 '^=== CONT TestChattyParallel/sub-1\n chatty_parallel_test.go:38: error from sub-1$' stdout -count=1 '^=== CONT TestChattyParallel/sub-2\n chatty_parallel_test.go:38: error from sub-2$' # Run parallel chatty tests with -json. Assert on CONT lines as above - make # sure there are CONT lines before each output line. ! go test -json -parallel 3 chatty_parallel_test.go -v stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":"=== CONT TestChattyParallel/sub-0\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":" chatty_parallel_test.go:38: error from sub-0\\n"}' stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":"=== CONT TestChattyParallel/sub-1\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":" chatty_parallel_test.go:38: error from sub-1\\n"}' stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"=== CONT TestChattyParallel/sub-2\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":" chatty_parallel_test.go:38: error from sub-2\\n"}' -- chatty_parallel_test.go -- package chatty_parallel_test import ( "testing" "fmt" "flag" ) // This test ensures the order of CONT lines in parallel chatty tests. func TestChattyParallel(t *testing.T) { t.Parallel() // The number of concurrent tests running. This is closely tied to the // -parallel test flag, so we grab it from the flag rather than setting it // to some constant. parallel := flag.Lookup("test.parallel").Value.(flag.Getter).Get().(int) // ready is a synchronization mechanism that causes subtests to execute // round robin. ready := make([]chan bool, parallel) for i := range ready { ready[i] = make(chan bool, 1) } ready[0] <- true for i := range ready { i := i t.Run(fmt.Sprintf("sub-%d", i), func(t *testing.T) { t.Parallel() // Some basic log output to precede the failures. <-ready[i] t.Logf("this is sub-%d", i) ready[(i+1)%len(ready)] <- true // The actual failure messages we care about. <-ready[i] t.Errorf("error from sub-%d", i) ready[(i+1)%len(ready)] <- true }) } }