Do not return event with ok status on first run of check. Will only return check result if anything went wrong.
183 lines
3.6 KiB
Go
183 lines
3.6 KiB
Go
package watchdog_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"code.uint32.ru/tiny/watchdog"
|
|
)
|
|
|
|
type mockChecker struct {
|
|
name string
|
|
status watchdog.Status
|
|
err error
|
|
called bool
|
|
}
|
|
|
|
func (m *mockChecker) Func(ctx context.Context) (watchdog.Status, error) {
|
|
m.called = true
|
|
|
|
time.Sleep(time.Millisecond * 10)
|
|
if err := ctx.Err(); err != nil {
|
|
return watchdog.StatusUnknown, err
|
|
}
|
|
|
|
return m.status, m.err
|
|
}
|
|
|
|
func (m *mockChecker) HasBeenCalled() bool {
|
|
return m.called
|
|
}
|
|
|
|
func (m *mockChecker) Check() watchdog.Check {
|
|
return watchdog.Check{
|
|
Name: m.name,
|
|
Interval: time.Minute,
|
|
Check: m.Func,
|
|
}
|
|
}
|
|
|
|
func newMockChecker(name string, s watchdog.Status, err error) *mockChecker {
|
|
return &mockChecker{name: name, status: s, err: err}
|
|
}
|
|
|
|
func TestCreateWith_new(t *testing.T) {
|
|
w := new(watchdog.Watchdog)
|
|
|
|
if len(w.ListChecks()) != 0 {
|
|
t.Errorf("expected len = 0")
|
|
}
|
|
}
|
|
|
|
func TestNew(t *testing.T) {
|
|
w := watchdog.New()
|
|
|
|
if len(w.ListChecks()) != 0 {
|
|
t.Errorf("expected len = 0")
|
|
}
|
|
|
|
m1 := newMockChecker("mock", watchdog.StatusOK, nil)
|
|
m2 := newMockChecker("mock2", watchdog.StatusOK, nil)
|
|
|
|
w = watchdog.New()
|
|
w.AddChecks(m1.Check(), m2.Check())
|
|
if len(w.ListChecks()) != 2 {
|
|
t.Errorf("expected len = 2")
|
|
}
|
|
|
|
w.RemoveChecks("mock")
|
|
|
|
if len(w.ListChecks()) != 1 {
|
|
t.Errorf("expected len = 1")
|
|
}
|
|
|
|
w.RemoveChecks("mock2")
|
|
|
|
if len(w.ListChecks()) != 0 {
|
|
t.Errorf("expected len = 0")
|
|
}
|
|
|
|
w = watchdog.New(m1.Check(), m2.Check())
|
|
if len(w.ListChecks()) != 2 {
|
|
t.Errorf("")
|
|
}
|
|
}
|
|
|
|
func TestRunImmediately(t *testing.T) {
|
|
w := new(watchdog.Watchdog)
|
|
out, err := w.RunImmediately(t.Context(), 1)
|
|
if err == nil {
|
|
t.Error("empty instance must return error on RunImmediately")
|
|
}
|
|
if len(out) != 0 {
|
|
t.Errorf("expected zero len slice for empty instance, got %d", len(out))
|
|
}
|
|
|
|
m1 := newMockChecker("mock", watchdog.StatusOK, nil)
|
|
m2 := newMockChecker("mock2", watchdog.StatusOK, nil)
|
|
|
|
w = watchdog.New(m1.Check(), m2.Check())
|
|
out, _ = w.RunImmediately(t.Context(), 0)
|
|
if len(out) != 2 {
|
|
t.Error("expected result of len 2")
|
|
}
|
|
|
|
for _, m := range []*mockChecker{m1, m2} {
|
|
if !m.HasBeenCalled() {
|
|
t.Errorf("mock %s has not been called", m.name)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func TestStartStop(t *testing.T) {
|
|
w := new(watchdog.Watchdog)
|
|
if _, err := w.Start(0); err == nil {
|
|
t.Error("Start doen't error on empty checks slice")
|
|
}
|
|
|
|
m1 := newMockChecker("mock", watchdog.StatusOK, nil)
|
|
m2 := newMockChecker("mock2", watchdog.StatusOK, nil)
|
|
|
|
w.AddChecks(m1.Check(), m2.Check())
|
|
|
|
out, err := w.Start(0)
|
|
if err != nil {
|
|
t.Error("Start returns error", err)
|
|
}
|
|
|
|
out2, err := w.Start(0)
|
|
if err != nil {
|
|
t.Error("second call to Start returns error")
|
|
}
|
|
|
|
if !reflect.DeepEqual(out, out2) {
|
|
t.Error("returned channels are not equal")
|
|
}
|
|
|
|
time.Sleep(time.Second)
|
|
if err := w.Stop(); err != nil {
|
|
t.Error("Stop returned error", err)
|
|
}
|
|
|
|
count := 0
|
|
|
|
for range out {
|
|
count++
|
|
}
|
|
|
|
if count != 0 {
|
|
t.Error("incorrect result count received from chan")
|
|
}
|
|
|
|
for _, m := range []*mockChecker{m1, m2} {
|
|
if !m.HasBeenCalled() {
|
|
t.Errorf("mock %s has not been called", m.name)
|
|
}
|
|
}
|
|
|
|
if err := w.Stop(); err == nil {
|
|
t.Error("call to stop on stopped instance does not return err")
|
|
}
|
|
}
|
|
|
|
func TestSetTimeout(t *testing.T) {
|
|
w := new(watchdog.Watchdog)
|
|
w.SetTimeout(time.Millisecond)
|
|
m1 := newMockChecker("mock", watchdog.StatusOK, nil)
|
|
w.AddChecks(m1.Check())
|
|
|
|
out, _ := w.Start(0)
|
|
time.Sleep(time.Second)
|
|
w.Stop()
|
|
res := <-out
|
|
|
|
if !(res.Status == watchdog.StatusUnknown) || !errors.Is(res.Error, context.DeadlineExceeded) {
|
|
t.Logf("got status: %s, err: %v", res.Status, res.Error)
|
|
t.Fatal("incorrect status for timed out op")
|
|
}
|
|
}
|