lundi 2 novembre 2020

How do I properly use channels inside a parallelized Go test?

I'm experimenting with parallel subtests, and I'm hitting a goroutine deadlock error. Assuming that tt is a table test with valid values, and LastIndex is the function being tested, the following code runs all the tests, but errors out:

for _, tt := range tests {
    tt := tt
    t.Run("foo", func(t *testing.T) {
        done := make(chan bool)
        for {
            select {
            case <-done:
                return
            case <-time.After(time.Second):
                if got := LastIndex(tt.list, tt.x); got != tt.want {
                    t.Fatalf("LastIndex(%v, %v) = %v, want %v", tt.list, tt.x, got, tt.want)
                } else {
                    done <- true
                }
            }
        }
    })
}

Specifically: fatal error: all goroutines are asleep - deadlock!

The error implies that the supertest is still waiting on results from these subtests, but shouldn't return and t.Fatalf() have exited them? The Go docs say that channels don't necessarily need to be closed, but I tried closing them anyway, and it still didn't work. I also tried to create the channel outside the subtest scope, inside the range iteration, and defer closing it with a t.Cleanup(), but that didn't work either.

Full code here: https://play.golang.org/p/1ujIIl7pjY9 Not all tests pass, this is intentional

What am I doing wrong?

Aucun commentaire:

Enregistrer un commentaire