Skip to content

assert: Eventually should not leak a goroutine #1611

@dolmen

Description

@dolmen

Description

If the condition function runs for longer than the timeout given to assert.Eventually (and family: EventuallyWithT, Never) it returns anyway right after the timeout, and the goroutine in which the condition runs continues in the background beyond Eventually returns. This is a goroutine leak that can lead to dirty bugs and flaky tests.

Note that the Eventually internal test suite TestEventuallyWithT_ReturnsTheLatestFinishedConditionErrors and TestEventuallyTimeout rely on this behavior so we first have to fix those 2 tests.

Step To Reproduce

On the Go Playground: https://go.dev/play/p/mDyUOIJXQS5

func TestEventuallyLeak(t *testing.T) {
	done := make(chan struct{})

	inEventually := true
	assert.Eventually(t, func() bool {
		defer func() {
			t.Log(time.Now(), "Condition: end.")
			done <- struct{}{}
		}()
		t.Log(time.Now(), "Condition: inEventually =", inEventually)
		time.Sleep(500 * time.Millisecond)
		t.Log(time.Now(), "Condition: inEventually =", inEventually)
		return true
	}, 100*time.Millisecond, 10*time.Millisecond)
	inEventually = false
	t.Log(time.Now(), "Eventually done")

	<-done
	t.Log(time.Now(), "End of", t.Name())
}

Expected behavior

Every log happening in the condition should happen before "Eventually done".

Actual behavior

=== RUN   TestEventuallyLeak
    prog_test.go:19: 2009-11-10 23:00:00.01 +0000 UTC m=+0.010000001 Condition: inEventually = true
    prog_test.go:14: 
        	Error Trace:	/tmp/sandbox257157838/prog_test.go:14
        	Error:      	Condition never satisfied
        	Test:       	TestEventuallyLeak
    prog_test.go:25: 2009-11-10 23:00:00.1 +0000 UTC m=+0.100000001 Eventually done
    prog_test.go:21: 2009-11-10 23:00:00.51 +0000 UTC m=+0.510000001 Condition: inEventually = false
    prog_test.go:16: 2009-11-10 23:00:00.51 +0000 UTC m=+0.510000001 Condition: end.
    prog_test.go:28: 2009-11-10 23:00:00.51 +0000 UTC m=+0.510000001 End of TestEventuallyLeak
--- FAIL: TestEventuallyLeak (0.51s)
FAIL

Metadata

Metadata

Assignees

No one assigned

    Labels

    assert.EventuallyAbout assert.Eventually/EventuallyWithTbugpkg-assertChange related to package testify/assert

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions