mirror of
https://github.com/strukturag/nextcloud-spreed-signaling.git
synced 2023-10-21 07:33:40 -05:00
Merge pull request #396 from strukturag/test-count-goroutines
Fix goroutines leak check.
This commit is contained in:
@@ -60,7 +60,7 @@ func CreateLoopbackNatsClientForTest(t *testing.T) NatsClient {
|
||||
}
|
||||
|
||||
func TestLoopbackNatsClient_Subscribe(t *testing.T) {
|
||||
ensureNoGoroutinesLeak(t, func() {
|
||||
ensureNoGoroutinesLeak(t, func(t *testing.T) {
|
||||
client := CreateLoopbackNatsClientForTest(t)
|
||||
|
||||
testNatsClient_Subscribe(t, client)
|
||||
@@ -68,7 +68,7 @@ func TestLoopbackNatsClient_Subscribe(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoopbackClient_PublishAfterClose(t *testing.T) {
|
||||
ensureNoGoroutinesLeak(t, func() {
|
||||
ensureNoGoroutinesLeak(t, func(t *testing.T) {
|
||||
client := CreateLoopbackNatsClientForTest(t)
|
||||
|
||||
testNatsClient_PublishAfterClose(t, client)
|
||||
@@ -76,7 +76,7 @@ func TestLoopbackClient_PublishAfterClose(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoopbackClient_SubscribeAfterClose(t *testing.T) {
|
||||
ensureNoGoroutinesLeak(t, func() {
|
||||
ensureNoGoroutinesLeak(t, func(t *testing.T) {
|
||||
client := CreateLoopbackNatsClientForTest(t)
|
||||
|
||||
testNatsClient_SubscribeAfterClose(t, client)
|
||||
@@ -84,7 +84,7 @@ func TestLoopbackClient_SubscribeAfterClose(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoopbackClient_BadSubjects(t *testing.T) {
|
||||
ensureNoGoroutinesLeak(t, func() {
|
||||
ensureNoGoroutinesLeak(t, func(t *testing.T) {
|
||||
client := CreateLoopbackNatsClientForTest(t)
|
||||
|
||||
testNatsClient_BadSubjects(t, client)
|
||||
|
||||
+4
-4
@@ -105,7 +105,7 @@ func testNatsClient_Subscribe(t *testing.T, client NatsClient) {
|
||||
}
|
||||
|
||||
func TestNatsClient_Subscribe(t *testing.T) {
|
||||
ensureNoGoroutinesLeak(t, func() {
|
||||
ensureNoGoroutinesLeak(t, func(t *testing.T) {
|
||||
client := CreateLocalNatsClientForTest(t)
|
||||
|
||||
testNatsClient_Subscribe(t, client)
|
||||
@@ -121,7 +121,7 @@ func testNatsClient_PublishAfterClose(t *testing.T, client NatsClient) {
|
||||
}
|
||||
|
||||
func TestNatsClient_PublishAfterClose(t *testing.T) {
|
||||
ensureNoGoroutinesLeak(t, func() {
|
||||
ensureNoGoroutinesLeak(t, func(t *testing.T) {
|
||||
client := CreateLocalNatsClientForTest(t)
|
||||
|
||||
testNatsClient_PublishAfterClose(t, client)
|
||||
@@ -138,7 +138,7 @@ func testNatsClient_SubscribeAfterClose(t *testing.T, client NatsClient) {
|
||||
}
|
||||
|
||||
func TestNatsClient_SubscribeAfterClose(t *testing.T) {
|
||||
ensureNoGoroutinesLeak(t, func() {
|
||||
ensureNoGoroutinesLeak(t, func(t *testing.T) {
|
||||
client := CreateLocalNatsClientForTest(t)
|
||||
|
||||
testNatsClient_SubscribeAfterClose(t, client)
|
||||
@@ -160,7 +160,7 @@ func testNatsClient_BadSubjects(t *testing.T, client NatsClient) {
|
||||
}
|
||||
|
||||
func TestNatsClient_BadSubjects(t *testing.T) {
|
||||
ensureNoGoroutinesLeak(t, func() {
|
||||
ensureNoGoroutinesLeak(t, func(t *testing.T) {
|
||||
client := CreateLocalNatsClientForTest(t)
|
||||
|
||||
testNatsClient_BadSubjects(t, client)
|
||||
|
||||
+29
-12
@@ -23,35 +23,52 @@ package signaling
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ensureNoGoroutinesLeak(t *testing.T, f func()) {
|
||||
var listenSignalOnce sync.Once
|
||||
|
||||
func ensureNoGoroutinesLeak(t *testing.T, f func(t *testing.T)) {
|
||||
t.Helper()
|
||||
|
||||
// The signal package will start a goroutine the first time "signal.Notify"
|
||||
// is called. Do so outside the function under test so the signal goroutine
|
||||
// will not be shown as "leaking".
|
||||
listenSignalOnce.Do(func() {
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, os.Interrupt)
|
||||
go func() {
|
||||
for {
|
||||
<-ch
|
||||
}
|
||||
}()
|
||||
})
|
||||
|
||||
profile := pprof.Lookup("goroutine")
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
before := pprof.Lookup("goroutine")
|
||||
before := profile.Count()
|
||||
|
||||
f()
|
||||
t.Run("leakcheck", f)
|
||||
|
||||
var after *pprof.Profile
|
||||
var after int
|
||||
// Give time for things to settle before capturing the number of
|
||||
// go routines
|
||||
timeout := time.Now().Add(time.Second)
|
||||
for time.Now().Before(timeout) {
|
||||
after = pprof.Lookup("goroutine")
|
||||
if after.Count() == before.Count() {
|
||||
after = profile.Count()
|
||||
if after == before {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if after.Count() != before.Count() {
|
||||
os.Stderr.WriteString("Before:\n")
|
||||
before.WriteTo(os.Stderr, 1) // nolint
|
||||
os.Stderr.WriteString("After:\n")
|
||||
after.WriteTo(os.Stderr, 1) // nolint
|
||||
t.Fatalf("Number of Go routines has changed in %s", t.Name())
|
||||
if after != before {
|
||||
profile.WriteTo(os.Stderr, 2) // nolint
|
||||
t.Fatalf("Number of Go routines has changed from %d to %d", before, after)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user