package miner import ( "testing" "time" "crypto-miner-agent/config" "crypto-miner-agent/stats" ) func parseTestTime(hour, minute int) time.Time { return time.Date(2026, 5, 26, hour, minute, 0, 0, time.UTC) } func TestScheduleGuardAlways(t *testing.T) { guard := NewScheduleGuard(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{MiningMode: "always"}}, stats.NewReporter()) if !guard.Allowed() { t.Fatal("always mode should allow mining") } } func TestScheduleGuardScheduledUsesConfigWindow(t *testing.T) { cfg := config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{ MiningMode: "scheduled", ScheduleStart: "21:00", ScheduleEnd: "06:00", }} if !cfg.InScheduleWindow(parseTestTime(23, 0)) { t.Fatal("expected overnight schedule to allow mining at 23:00") } } func TestScheduleGuardScheduledDeniedOutsideWindow(t *testing.T) { guard := NewScheduleGuard(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{ MiningMode: "scheduled", ScheduleStart: "09:00", ScheduleEnd: "17:00", }}, stats.NewReporter()) if !guard.allowedAt(parseTestTime(10, 0)) { t.Fatal("10:00 should allow mining in 09-17 window") } if guard.allowedAt(parseTestTime(20, 0)) { t.Fatal("20:00 should deny mining outside 09-17 window") } } func TestScheduleGuardScheduleAlias(t *testing.T) { guard := NewScheduleGuard(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{ MiningMode: "schedule", ScheduleStart: "09:00", ScheduleEnd: "17:00", }}, stats.NewReporter()) if guard.allowedAt(parseTestTime(10, 0)) != true { t.Fatal("normalized schedule alias should honor daytime window at 10:00") } if guard.allowedAt(parseTestTime(3, 0)) { t.Fatal("normalized schedule alias should deny mining at 03:00") } } func TestScheduleGuardIdleFirstSampleNotAllowed(t *testing.T) { guard := NewScheduleGuard(config.RuntimeConfig{BuiltinConfig: config.BuiltinConfig{ MiningMode: "idle", }}, stats.NewReporter()) // First SystemCPUPercent sample is 0 → treated as not idle. if guard.Allowed() { t.Fatal("idle mode should deny mining on first CPU sample (cpu=0)") } }