Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
53 lines
1.6 KiB
Go
53 lines
1.6 KiB
Go
package reconciler
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/control/catalog"
|
|
)
|
|
|
|
func TestAScheduleRaisesTheMinimumThroughItsHours(t *testing.T) {
|
|
m := testModel(1)
|
|
m.Scaling = catalog.Scaling{Min: 1, Max: 4, Prewarm: 30 * time.Minute,
|
|
Schedule: []catalog.ScaleWindow{{From: "08:00", To: "18:00", Min: 2, Max: 3}}}
|
|
h := newHarness(t, m, gpuNode("1", 8))
|
|
at := func(hm string) {
|
|
target, _ := time.Parse("2006-01-02 15:04", "2026-01-02 "+hm)
|
|
h.clock.advance(target.Sub(h.clock.now()))
|
|
}
|
|
cur := func() catalog.Model { got, _ := h.live.Load().Resolve(m.Name); return got }
|
|
at("03:00")
|
|
if n := h.r.desiredFor(cur()); n != 1 {
|
|
t.Errorf("at night: %d", n)
|
|
}
|
|
at("07:45") // prewarmed
|
|
if n := h.r.desiredFor(cur()); n != 2 {
|
|
t.Errorf("before the window, prewarming: %d", n)
|
|
}
|
|
if mx := h.r.maxFor(cur()); mx != 3 {
|
|
t.Errorf("the window's ceiling: %d", mx)
|
|
}
|
|
at("18:30")
|
|
if n := h.r.desiredFor(cur()); n != 1 {
|
|
t.Errorf("after the window: %d", n)
|
|
}
|
|
}
|
|
|
|
func TestAnOnDemandModelIsKeptLoadedThroughItsWindow(t *testing.T) {
|
|
m := testModel(1)
|
|
m.Scaling = catalog.Scaling{Min: 0, Max: 1,
|
|
Schedule: []catalog.ScaleWindow{{From: "09:00", To: "17:00", Min: 1}}}
|
|
h := newHarness(t, m, gpuNode("1", 8))
|
|
target, _ := time.Parse("2006-01-02 15:04", "2026-01-02 10:00")
|
|
h.clock.advance(target.Sub(h.clock.now()))
|
|
got, _ := h.live.Load().Resolve(m.Name)
|
|
if n := h.r.desiredFor(got); n != 1 {
|
|
t.Errorf("unasked-for in its window: %d", n)
|
|
}
|
|
h.clock.advance(8 * time.Hour)
|
|
if n := h.r.desiredFor(got); n != 0 {
|
|
t.Errorf("unasked-for outside its window: %d", n)
|
|
}
|
|
}
|