93 lines
1.8 KiB
Go
93 lines
1.8 KiB
Go
package watchdog
|
|
|
|
import (
|
|
"runtime"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/raulk/clock"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type testPolicy struct {
|
|
ch chan *PolicyInput
|
|
trigger bool
|
|
}
|
|
|
|
var _ Policy = (*testPolicy)(nil)
|
|
|
|
func (t *testPolicy) Evaluate(input PolicyInput) (trigger bool) {
|
|
t.ch <- &input
|
|
return t.trigger
|
|
}
|
|
|
|
func TestWatchdog(t *testing.T) {
|
|
clk := clock.NewMock()
|
|
Clock = clk
|
|
|
|
tp := &testPolicy{ch: make(chan *PolicyInput, 1)}
|
|
notifyCh := make(chan struct{}, 1)
|
|
|
|
err, stop := Memory(MemConfig{
|
|
Scope: ScopeHeap,
|
|
Limit: 100,
|
|
Resolution: 10 * time.Second,
|
|
Policy: tp,
|
|
NotifyFired: func() { notifyCh <- struct{}{} },
|
|
})
|
|
require.NoError(t, err)
|
|
defer stop()
|
|
|
|
time.Sleep(500 * time.Millisecond) // wait til the watchdog goroutine starts.
|
|
|
|
clk.Add(10 * time.Second)
|
|
pi := <-tp.ch
|
|
require.EqualValues(t, 100, pi.Limit)
|
|
require.NotNil(t, pi.MemStats)
|
|
require.NotNil(t, pi.SysStats)
|
|
require.Equal(t, ScopeHeap, pi.Scope)
|
|
|
|
require.Len(t, notifyCh, 0)
|
|
|
|
var ms runtime.MemStats
|
|
runtime.ReadMemStats(&ms)
|
|
require.EqualValues(t, 0, ms.NumGC)
|
|
|
|
// now fire.
|
|
tp.trigger = true
|
|
|
|
clk.Add(10 * time.Second)
|
|
pi = <-tp.ch
|
|
require.EqualValues(t, 100, pi.Limit)
|
|
require.NotNil(t, pi.MemStats)
|
|
require.NotNil(t, pi.SysStats)
|
|
require.Equal(t, ScopeHeap, pi.Scope)
|
|
|
|
time.Sleep(500 * time.Millisecond) // wait until the watchdog runs.
|
|
|
|
require.Len(t, notifyCh, 1)
|
|
|
|
runtime.ReadMemStats(&ms)
|
|
require.EqualValues(t, 1, ms.NumGC)
|
|
}
|
|
|
|
func TestDoubleClose(t *testing.T) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Fatal(r)
|
|
}
|
|
}()
|
|
|
|
tp := &testPolicy{ch: make(chan *PolicyInput, 1)}
|
|
|
|
err, stop := Memory(MemConfig{
|
|
Scope: ScopeHeap,
|
|
Limit: 100,
|
|
Resolution: 10 * time.Second,
|
|
Policy: tp,
|
|
})
|
|
require.NoError(t, err)
|
|
stop()
|
|
stop()
|
|
}
|