Ramblings

t.Parallel is kinda neat

To the credit of the Go language team, I've barely given t.Parallel a thought beyond "add this at the top and tests go brrr...". Today I was reading a test that did some work before calling t.Parallel and I wondered how that affected parallel test execution. In particular, my mental model was that parallelisation was a binary decision, either the test is or isn't running in parallel. However, this obviously doesn't make sense, because the call to t.Parallel only occurs within the body of the test itself, so absent some AST parsing, it must happen during execution.

First I asked an LLM, which gave me about one tenth of the picture, that t.Parallel continues the rest of the test execution within a goroutine, but after that it made increasingly more unbelievable claims, like that if a parallel test ran first and then began executing in a goroutine, that a serial test might start running in parallel as a result of test ordering. ¯\_(ツ)_/¯

As far as I can divine without diving too deeply into the code, ignoring subtests, and GOMAXPROCS, the gist of it is:

The interesting thing about this is that it means parallelisable tests can block others before t.Parallel is called. You can see how this plays out in the verbose logs for this test below, with TestParallel beginning to RUN, and then PAUSING before CONTINUING when TestSerial has completed.

func TestParallel(t *testing.T) {
	fmt.Println("parallel starting")
	t.Parallel()
	fmt.Println("parallel continuing")
}

func TestSerial(t *testing.T) {
	fmt.Println("serial starting")
}
=== RUN   TestParallel
parallel starting
=== PAUSE TestParallel
=== RUN   TestSerial
serial starting
--- PASS: TestSerial (0.00s)
=== CONT  TestParallel
parallel continuing
--- PASS: TestParallel (0.00s)
PASS

All that said, I've been writing Go since 2015 and I never gave this much thought before, so in that regard, I think t.Parallel is kinda neat!