Files

69 lines
2.5 KiB
Go

package cron
import (
"testing"
"time"
)
func TestNextRun(t *testing.T) {
loc := time.UTC
from := time.Date(2026, 9, 17, 15, 30, 0, 0, loc) // Thursday
cases := []struct {
expr string
want time.Time
}{
{"0 1 * * *", time.Date(2026, 9, 18, 1, 0, 0, 0, loc)},
{"17 * * * *", time.Date(2026, 9, 17, 16, 17, 0, 0, loc)},
{"*/15 * * * *", time.Date(2026, 9, 17, 15, 45, 0, 0, loc)},
{"47 6 * * 7", time.Date(2026, 9, 20, 6, 47, 0, 0, loc)}, // Sunday as 7
{"52 6 1 * *", time.Date(2026, 10, 1, 6, 52, 0, 0, loc)}, // first of month
{"24 0 1-7 * *", time.Date(2026, 10, 1, 0, 24, 0, 0, loc)}, // range
{"30 3 * * 0", time.Date(2026, 9, 20, 3, 30, 0, 0, loc)}, // Sunday as 0
{"0 9 15 * mon", time.Date(2026, 9, 21, 9, 0, 0, 0, loc)}, // dom OR dow
{"@daily", time.Date(2026, 9, 18, 0, 0, 0, 0, loc)},
{"@weekly", time.Date(2026, 9, 20, 0, 0, 0, 0, loc)},
{"0 0 29 feb *", time.Date(2028, 2, 29, 0, 0, 0, 0, loc)},
}
for _, c := range cases {
got, ok := nextRun(c.expr, from)
if !ok || !got.Equal(c.want) {
t.Errorf("%q: got %v ok=%v, want %v", c.expr, got, ok, c.want)
}
}
if _, ok := nextRun("@reboot", from); ok {
t.Error("@reboot should have no next run")
}
for _, bad := range []string{"* * * *", "60 * * * *", "a b c d e", "*/0 * * * *"} {
if _, err := parseSchedule(bad); err == nil {
t.Errorf("%q should fail", bad)
}
}
}
func TestParseLine(t *testing.T) {
sch, u, cmd, ok := parseLine("25 6\t* * *\troot\ttest -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; }", true)
if !ok || sch != "25 6 * * *" || u != "root" || !strings_HasPrefix(cmd, "test -x") {
t.Errorf("system line: %q %q %q %v", sch, u, cmd, ok)
}
if _, _, _, ok := parseLine("PATH=/usr/bin:/bin", true); ok {
t.Error("env line parsed as job")
}
if _, _, _, ok := parseLine("# m h dom mon dow command", false); ok {
t.Error("comment parsed as job")
}
if _, u, cmd, ok := parseLine("@reboot /usr/local/bin/thing --flag", false); !ok || u != "" || cmd != "/usr/local/bin/thing --flag" {
t.Errorf("@reboot: %q %q %v", u, cmd, ok)
}
if got := outFile("foo >> /var/log/foo.log 2>&1"); got != "/var/log/foo.log" {
t.Errorf("outFile: %q", got)
}
if c, in := cronPercent("echo hi%line1%line2"); c != "echo hi" || in != "line1\nline2" {
t.Errorf("percent: %q %q", c, in)
}
if c, _ := cronPercent(`date +\%w`); c != "date +%w" {
t.Errorf("escaped percent: %q", c)
}
}
func strings_HasPrefix(s, p string) bool { return len(s) >= len(p) && s[:len(p)] == p }