Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/protocols/common/protocolstate/memguardian_test.go
2843 views
1
package protocolstate
2
3
import (
4
"context"
5
"testing"
6
"time"
7
8
"github.com/projectdiscovery/utils/memguardian"
9
"github.com/stretchr/testify/require"
10
"github.com/tarunKoyalwar/goleak"
11
)
12
13
// TestMemGuardianGoroutineLeak tests that MemGuardian properly cleans up goroutines
14
func TestMemGuardianGoroutineLeak(t *testing.T) {
15
defer goleak.VerifyNone(t,
16
goleak.IgnoreAnyContainingPkg("go.opencensus.io/stats/view"),
17
goleak.IgnoreAnyContainingPkg("github.com/syndtr/goleveldb"),
18
goleak.IgnoreAnyContainingPkg("github.com/go-rod/rod"),
19
goleak.IgnoreAnyContainingPkg("github.com/projectdiscovery/interactsh/pkg/server"),
20
goleak.IgnoreAnyContainingPkg("github.com/projectdiscovery/ratelimit"),
21
)
22
23
// Initialize memguardian if not already initialized
24
if memguardian.DefaultMemGuardian == nil {
25
var err error
26
memguardian.DefaultMemGuardian, err = memguardian.New()
27
require.NoError(t, err, "Failed to initialize memguardian")
28
}
29
30
t.Run("StartAndStopMemGuardian", func(t *testing.T) {
31
// Test that starting and stopping memguardian doesn't leak goroutines
32
ctx := context.Background()
33
34
// Start MemGuardian
35
StartActiveMemGuardian(ctx)
36
require.NotNil(t, memTimer, "memTimer should be initialized")
37
require.NotNil(t, cancelFunc, "cancelFunc should be initialized")
38
39
// Give it a moment to start
40
time.Sleep(10 * time.Millisecond)
41
42
// Stop MemGuardian
43
StopActiveMemGuardian()
44
45
// Give goroutine time to exit
46
time.Sleep(20 * time.Millisecond)
47
48
// Verify cleanup
49
require.Nil(t, memTimer, "memTimer should be nil after stop")
50
require.Nil(t, cancelFunc, "cancelFunc should be nil after stop")
51
})
52
53
t.Run("MultipleStartStop", func(t *testing.T) {
54
// Test multiple start/stop cycles
55
for i := 0; i < 3; i++ {
56
ctx := context.Background()
57
StartActiveMemGuardian(ctx)
58
time.Sleep(5 * time.Millisecond)
59
StopActiveMemGuardian()
60
time.Sleep(10 * time.Millisecond)
61
}
62
})
63
64
t.Run("ContextCancellation", func(t *testing.T) {
65
// Test that context cancellation properly stops the goroutine
66
ctx, cancel := context.WithCancel(context.Background())
67
68
StartActiveMemGuardian(ctx)
69
require.NotNil(t, memTimer, "memTimer should be initialized")
70
71
// Cancel context to trigger goroutine exit
72
cancel()
73
74
// Give it time to process cancellation
75
time.Sleep(20 * time.Millisecond)
76
77
// Clean up
78
StopActiveMemGuardian()
79
time.Sleep(10 * time.Millisecond)
80
})
81
82
t.Run("IdempotentStart", func(t *testing.T) {
83
// Test that multiple starts don't create multiple goroutines
84
ctx := context.Background()
85
86
StartActiveMemGuardian(ctx)
87
firstTimer := memTimer
88
89
// Start again - should be idempotent
90
StartActiveMemGuardian(ctx)
91
require.Equal(t, firstTimer, memTimer, "memTimer should be the same")
92
require.NotNil(t, cancelFunc, "cancelFunc should still be set")
93
94
StopActiveMemGuardian()
95
time.Sleep(10 * time.Millisecond)
96
})
97
}
98
99
// TestMemGuardianReset tests resetting global state
100
func TestMemGuardianReset(t *testing.T) {
101
defer goleak.VerifyNone(t,
102
goleak.IgnoreAnyContainingPkg("go.opencensus.io/stats/view"),
103
goleak.IgnoreAnyContainingPkg("github.com/syndtr/goleveldb"),
104
goleak.IgnoreAnyContainingPkg("github.com/go-rod/rod"),
105
goleak.IgnoreAnyContainingPkg("github.com/projectdiscovery/interactsh/pkg/server"),
106
goleak.IgnoreAnyContainingPkg("github.com/projectdiscovery/ratelimit"),
107
)
108
109
// Ensure clean state
110
StopActiveMemGuardian()
111
time.Sleep(20 * time.Millisecond) // Allow any existing goroutines to exit
112
113
// Test that we can start after stop
114
ctx := context.Background()
115
StartActiveMemGuardian(ctx)
116
117
// Verify it started
118
require.NotNil(t, memTimer, "memTimer should be initialized after restart")
119
120
// Clean up
121
StopActiveMemGuardian()
122
time.Sleep(10 * time.Millisecond) // Allow cleanup
123
}
124
125