Provide Memory Leak Test Suite
by adding an assertion about the number of Goroutines to the unit tests.
This commit is contained in:
@ -25,6 +25,7 @@ const (
|
|||||||
AnotherRunnerID = AnotherEnvironmentIDAsString + "-" + AnotherUUID
|
AnotherRunnerID = AnotherEnvironmentIDAsString + "-" + AnotherUUID
|
||||||
DefaultExecutionID = "s0m3-3x3cu710n-1d"
|
DefaultExecutionID = "s0m3-3x3cu710n-1d"
|
||||||
DefaultMockID = "m0ck-1d"
|
DefaultMockID = "m0ck-1d"
|
||||||
|
TinyTimeout = 10 * time.Millisecond
|
||||||
ShortTimeout = 100 * time.Millisecond
|
ShortTimeout = 100 * time.Millisecond
|
||||||
DefaultTestTimeout = 10 * time.Minute
|
DefaultTestTimeout = 10 * time.Minute
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
package tests
|
package tests
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"runtime/pprof"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// ChannelReceivesSomething waits timeout seconds for something to be received from channel ch.
|
// ChannelReceivesSomething waits timeout seconds for something to be received from channel ch.
|
||||||
// If something is received, it returns true. If the timeout expires without receiving anything, it return false.
|
// If something is received, it returns true. If the timeout expires without receiving anything, it return false.
|
||||||
@ -12,3 +21,42 @@ func ChannelReceivesSomething(ch chan bool, timeout time.Duration) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MemoryLeakTestSuite adds an assertion for checking Goroutine leaks.
|
||||||
|
// Be aware not to overwrite the SetupTest or TearDownTest function!
|
||||||
|
type MemoryLeakTestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
ExpectedGoroutingIncrease int
|
||||||
|
TestCtx context.Context
|
||||||
|
testCtxCancel context.CancelFunc
|
||||||
|
goroutineCountBefore int
|
||||||
|
goroutinesBefore *bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MemoryLeakTestSuite) SetupTest() {
|
||||||
|
s.goroutineCountBefore = runtime.NumGoroutine()
|
||||||
|
s.ExpectedGoroutingIncrease = 0
|
||||||
|
s.goroutinesBefore = &bytes.Buffer{}
|
||||||
|
|
||||||
|
err := pprof.Lookup("goroutine").WriteTo(s.goroutinesBefore, 1)
|
||||||
|
s.NoError(err)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
s.TestCtx = ctx
|
||||||
|
s.testCtxCancel = cancel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MemoryLeakTestSuite) TearDownTest() {
|
||||||
|
s.testCtxCancel()
|
||||||
|
runtime.Gosched() // Flush done Goroutines
|
||||||
|
<-time.After(TinyTimeout) // Just to make sure
|
||||||
|
goroutinesAfter := runtime.NumGoroutine()
|
||||||
|
s.Equal(s.goroutineCountBefore+s.ExpectedGoroutingIncrease, goroutinesAfter)
|
||||||
|
|
||||||
|
if s.goroutineCountBefore+s.ExpectedGoroutingIncrease != goroutinesAfter {
|
||||||
|
_, err := io.Copy(os.Stderr, s.goroutinesBefore)
|
||||||
|
s.NoError(err)
|
||||||
|
err = pprof.Lookup("goroutine").WriteTo(os.Stderr, 1)
|
||||||
|
s.NoError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user