package crontab import ( "fmt" "log" "runtime" "testing" "time" ) // type LRValue struct { // left, right int // } func TestParseCrontab(t *testing.T) { // crontab := "0-5/2,7-30/3,30,35,40-^1 * * * *" //(秒) 分 时 号(每月的多少号, 要注意月可可能性) 星期几(每个星期的) /每 ,列表 -范围 crontab := "* * * * *" PrintMemUsage() ty := newTrieYear() cron := NewCrontab(crontab) ty.FromCrontab(cron) if len(ty.GetPlanTime(cron, time.Now(), 10)) != 10 { t.Error("GetPlanTime error len != 10") } cron.createYearPlan() if cron.TimeUp() { t.Error("timeup error", cron.WillPlans[0:2]) } PrintMemUsage() } func TestParseInterval(t *testing.T) { //crontab := "0-5/2,7-30/3,30,35,40-^1 * * * *" //(秒) 分 时 号(每月的多少号, 要注意月可可能性) 星期几(每个星期的) /每 ,列表 -范围 //crontab := "f1-2|1-3|5-8x5,f1|10m,10-15,f22?15-12" crontab := "2s" cron := NewCrontab(crontab) now := time.Now() for i := 0; i <= 3; i++ { log.Println(cron.NextTime()) if cron.TimeUp() { sec := time.Since(now).Seconds() if i != 0 { if 2.0 <= sec && sec <= 2.1 { t.Log(sec) } else { t.Error("interval time is ", sec) } } now = time.Now() } time.Sleep(time.Second) } } func isInRangeTime(sec, t float64) error { if sec >= t-0.05 && sec <= t+0.05 { return nil } return fmt.Errorf("计算错误 范围 %f-%f interval time is %f", t-0.05, t+0.05, sec) } func TestParseIntervalPlus(t *testing.T) { // crontab := "0-5/2,7-30/3,30,35,40-^1 * * * *" //(秒) 分 时 号(每月的多少号, 要注意月可可能性) 星期几(每个星期的) /每 ,列表 -范围 // crondata := NewCrontab("*22 * * * *") //crontab := "0-5/2,7-30/3,30,35,40-^1 * * * *" //(秒) 分 时 号(每月的多少号, 要注意月可可能性) 星期几(每个星期的) /每 ,列表 -范围 //crontab := "f1-2|1-3|5-8x5,f1|10m,10-15,f1" ^代表往后算 ^5 2月份就代表 28-4=24 f代表失败后1-2秒设置 由SetStatus控制 t 相反默认不写前缀为t log.SetFlags(log.Llongfile) crontab := "f2|f2?3|f3?4|1|t4?5" cron := NewCrontab(crontab) i := 0 now := time.Now() lasttime := now for j := 0; j <= 2500; j++ { nexttime := cron.NextTime() if j >= 5 && !nexttime.Equal(lasttime) { lasttime = nexttime } if cron.TimeUp() { sec := time.Since(now).Seconds() switch i { case 0: case 1: if err := isInRangeTime(sec, 2.0); err != nil { t.Error(err.Error(), "status = ", cron.GetStatus()) } case 2: if err := isInRangeTime(sec, 3.0); err != nil { t.Error(err.Error(), "status = ", cron.GetStatus()) } case 3: if err := isInRangeTime(sec, 4.0); err != nil { t.Error(err.Error(), "status = ", cron.GetStatus()) } case 5: if err := isInRangeTime(sec, 1); err != nil { t.Error(err.Error(), "status = ", cron.GetStatus()) } default: if i >= 10 { if err := isInRangeTime(sec, 5.0); err != nil { t.Error(err.Error(), "status = ", cron.GetStatus()) } } } if i <= 3 { cron.SetStatus(false) } else { cron.SetStatus(true) } now = time.Now() i++ } time.Sleep(time.Millisecond * 10) } } func PrintMemUsage() { var m runtime.MemStats runtime.ReadMemStats(&m) // For info on each, see: https://golang.org/pkg/runtime/#MemStats fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc)) fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc)) fmt.Printf("\tSys = %v MiB", bToMb(m.Sys)) fmt.Printf("\tNumGC = %v\n", m.NumGC) } func bToMb(b uint64) uint64 { return b / 1024 / 1024 }