package server import ( "testing" "time" ) func TestQueueETASeconds(t *testing.T) { // No speed → can't extrapolate. if got := queueETASeconds(100, 3600, 0); got != 0 { t.Errorf("speed 0: got %d, want 0", got) } // current remaining 600s + 1800s of queued source at 0.5x (=3600s) = 4200s. if got := queueETASeconds(600, 1800, 0.5); got != 4200 { t.Errorf("got %d, want 4200", got) } // At 2x, 1800s of source encodes in 900s; + 600 remaining = 1500. if got := queueETASeconds(600, 1800, 2); got != 1500 { t.Errorf("got %d, want 1500", got) } // Empty queue → just the current job's remaining. if got := queueETASeconds(600, 0, 1); got != 600 { t.Errorf("got %d, want 600", got) } } // waitCached polls Get (the probe resolves on a background goroutine). func waitCached(c *durationCache, p string, mt time.Time) (float64, bool) { for i := 0; i < 200; i++ { if sec, ok := c.Get(p, mt); ok { return sec, true } time.Sleep(2 * time.Millisecond) } return 0, false } func TestDurationCache(t *testing.T) { c := newDurationCache(func(p string) (float64, error) { return 42, nil }) mt := time.Unix(1000, 0) if _, ok := c.Get("/a.mkv", mt); ok { t.Fatal("first Get should miss") } if sec, ok := waitCached(c, "/a.mkv", mt); !ok || sec != 42 { t.Fatalf("after probe: got %v ok=%v, want 42 true", sec, ok) } // A changed mtime invalidates the entry. if _, ok := c.Get("/a.mkv", time.Unix(2000, 0)); ok { t.Error("changed mtime should miss") } if _, ok := waitCached(c, "/a.mkv", time.Unix(2000, 0)); !ok { t.Fatal("re-probe under new mtime should cache") } // Retain drops entries for paths not in the keep set. c.Retain([]string{"/b.mkv"}) if _, ok := c.Get("/a.mkv", time.Unix(2000, 0)); ok { t.Error("Retain should have dropped /a.mkv") } }