Skip to content

Commit feae7e6

Browse files
authored
Merge pull request #1674 from ydb-platform/goleak
Small changes in detector goroutines leak
2 parents ee4e384 + ef5c063 commit feae7e6

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

internal/xtest/leak.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package xtest
22

33
import (
4+
"fmt"
45
"regexp"
56
"runtime"
67
"strings"
78
"testing"
89
)
910

10-
func checkGoroutinesLeak(onLeak func(goroutines []string)) {
11+
func findGoroutinesLeak() error {
1112
var bb []byte
1213
for size := 1 << 16; ; size *= 2 {
1314
bb = make([]byte, size)
@@ -61,14 +62,14 @@ func checkGoroutinesLeak(onLeak func(goroutines []string)) {
6162
unexpectedGoroutines = append(unexpectedGoroutines, g)
6263
}
6364
if l := len(unexpectedGoroutines); l > 0 {
64-
onLeak(goroutines)
65+
return fmt.Errorf("found %d unexpected goroutines:\n%s", len(goroutines), strings.Join(goroutines, "\n"))
6566
}
67+
68+
return nil
6669
}
6770

6871
func CheckGoroutinesLeak(tb testing.TB) {
69-
tb.Helper()
70-
checkGoroutinesLeak(func(goroutines []string) {
71-
tb.Helper()
72-
tb.Errorf("found %d unexpected goroutines:\n%s", len(goroutines), strings.Join(goroutines, "\n"))
73-
})
72+
if err := findGoroutinesLeak(); err != nil {
73+
tb.Errorf("leak goroutines detected: %v", err)
74+
}
7475
}

internal/xtest/leak_test.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package xtest
22

33
import (
4+
"sync/atomic"
45
"testing"
56

67
"github.com/stretchr/testify/require"
@@ -9,32 +10,44 @@ import (
910
func TestCheckGoroutinesLeak(t *testing.T) {
1011
t.Run("Leak", func(t *testing.T) {
1112
TestManyTimes(t, func(t testing.TB) {
12-
ch := make(chan struct{})
13-
require.Panics(t, func() {
14-
defer checkGoroutinesLeak(func([]string) {
15-
panic("test")
16-
})
13+
var (
14+
leakDetected atomic.Bool
15+
ch = make(chan struct{})
16+
)
17+
func() {
18+
defer func() {
19+
if err := findGoroutinesLeak(); err != nil {
20+
leakDetected.Store(true)
21+
}
22+
}()
1723
go func() {
1824
<-ch
1925
}()
20-
})
26+
}()
2127
close(ch)
28+
require.True(t, leakDetected.Load())
2229
})
2330
})
2431
t.Run("NoLeak", func(t *testing.T) {
2532
TestManyTimes(t, func(t testing.TB) {
26-
require.NotPanics(t, func() {
27-
defer checkGoroutinesLeak(func([]string) {
28-
panic("test")
29-
})
30-
ch := make(chan struct{})
33+
var (
34+
leakDetected atomic.Bool
35+
ch = make(chan struct{})
36+
)
37+
func() {
38+
defer func() {
39+
if err := findGoroutinesLeak(); err != nil {
40+
leakDetected.Store(true)
41+
}
42+
}()
3143
defer func() {
3244
<-ch
3345
}()
3446
go func() {
3547
close(ch)
3648
}()
37-
})
49+
}()
50+
require.False(t, leakDetected.Load())
3851
})
3952
})
4053
}

0 commit comments

Comments
 (0)