Add cron schedules and sync docs
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/monlet/agent/internal/config"
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
func runScheduler(ctx context.Context, agentID string, checks []config.CheckConfig, out chan<- Event, h Hooks) {
|
||||
@@ -27,6 +28,32 @@ func mkCheck(id, cmd string, interval, timeout time.Duration) config.CheckConfig
|
||||
}
|
||||
}
|
||||
|
||||
type fakeCronSchedule struct {
|
||||
delay time.Duration
|
||||
}
|
||||
|
||||
func (s fakeCronSchedule) Next(t time.Time) time.Time {
|
||||
return t.Add(s.delay)
|
||||
}
|
||||
|
||||
func withFakeCron(t *testing.T, delay time.Duration) {
|
||||
t.Helper()
|
||||
old := parseCronSchedule
|
||||
parseCronSchedule = func(string) (cron.Schedule, error) {
|
||||
return fakeCronSchedule{delay: delay}, nil
|
||||
}
|
||||
t.Cleanup(func() { parseCronSchedule = old })
|
||||
}
|
||||
|
||||
func mkCronCheck(id, cmd string, timeout time.Duration) config.CheckConfig {
|
||||
return config.CheckConfig{
|
||||
ID: id,
|
||||
Command: cmd,
|
||||
Cron: "0 * * * *",
|
||||
Timeout: config.Duration{Duration: timeout},
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmitsEvents(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
|
||||
defer cancel()
|
||||
@@ -45,6 +72,41 @@ func TestEmitsEvents(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCronDoesNotRunImmediately(t *testing.T) {
|
||||
withFakeCron(t, 200*time.Millisecond)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancel()
|
||||
out := make(chan Event, 10)
|
||||
m := NewManager(ctx, "a1", out, Hooks{})
|
||||
m.Update([]config.CheckConfig{mkCronCheck("cron", "echo cron", 100*time.Millisecond)})
|
||||
select {
|
||||
case ev := <-out:
|
||||
t.Fatalf("cron check ran before next slot: %+v", ev)
|
||||
case <-ctx.Done():
|
||||
}
|
||||
m.Stop()
|
||||
m.Wait()
|
||||
}
|
||||
|
||||
func TestCronEmitsOnDueSlot(t *testing.T) {
|
||||
withFakeCron(t, 30*time.Millisecond)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
out := make(chan Event, 10)
|
||||
m := NewManager(ctx, "a1", out, Hooks{})
|
||||
m.Update([]config.CheckConfig{mkCronCheck("cron", "echo cron", 100*time.Millisecond)})
|
||||
select {
|
||||
case ev := <-out:
|
||||
if ev.CheckID != "cron" || ev.Status != "ok" {
|
||||
t.Fatalf("unexpected event: %+v", ev)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
t.Fatal("no cron event")
|
||||
}
|
||||
m.Stop()
|
||||
m.Wait()
|
||||
}
|
||||
|
||||
func TestNoOverlapSkips(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 600*time.Millisecond)
|
||||
defer cancel()
|
||||
@@ -59,6 +121,23 @@ func TestNoOverlapSkips(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCronNoOverlapSkips(t *testing.T) {
|
||||
withFakeCron(t, 50*time.Millisecond)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond)
|
||||
defer cancel()
|
||||
out := make(chan Event, 10)
|
||||
var skipped int32
|
||||
hooks := Hooks{OnSkipped: func(string) { atomic.AddInt32(&skipped, 1) }}
|
||||
m := NewManager(ctx, "a1", out, hooks)
|
||||
m.Update([]config.CheckConfig{mkCronCheck("cron", "sleep 0.2", 500*time.Millisecond)})
|
||||
<-ctx.Done()
|
||||
m.Stop()
|
||||
m.Wait()
|
||||
if atomic.LoadInt32(&skipped) == 0 {
|
||||
t.Fatal("expected at least one skipped cron slot")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportsFullEventChannel(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
Reference in New Issue
Block a user