105 lines
2.7 KiB
Go
105 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestUsagePoll(t *testing.T) {
|
|
exhausted := false
|
|
for _, allowed := range []*bool{nil, &exhausted} {
|
|
f := newFake(t, nil)
|
|
f.usage = allowed
|
|
if err := f.reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
w := f.op.store.watch("thread-1")
|
|
w.Failures = 3
|
|
f.fail()
|
|
f.goal.Status = "usageLimited"
|
|
for poll := 1; poll <= 3; poll++ {
|
|
w.Due = time.Now().Add(-time.Second)
|
|
start := time.Now()
|
|
if err := f.reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if f.count("account/rateLimits/read") != poll || f.count("thread/goal/set") != 0 || w.Failures != 3 {
|
|
t.Fatal("usage wait attempted work or increased backoff")
|
|
}
|
|
if w.Due.Before(start.Add(f.op.opts.poll)) || w.Due.After(time.Now().Add(f.op.opts.poll)) {
|
|
t.Fatal("usage poll did not retain the fixed interval")
|
|
}
|
|
if err := f.reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if f.count("account/rateLimits/read") != poll {
|
|
t.Fatal("usage was queried before the next poll")
|
|
}
|
|
}
|
|
ready := true
|
|
f.usage = &ready
|
|
w.Due = time.Now().Add(-time.Second)
|
|
if err := f.reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if f.count("thread/goal/set") != 1 || f.goal.Status != active {
|
|
t.Fatal("early usage reset did not resume work")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUsageReadStop(t *testing.T) {
|
|
for _, status := range []string{"paused", "interrupted"} {
|
|
t.Run(status, func(t *testing.T) {
|
|
f := newFake(t, nil)
|
|
if err := f.reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
f.fail()
|
|
f.goal.Status = "usageLimited"
|
|
ready := true
|
|
f.usage = &ready
|
|
f.before = func(m message) {
|
|
if m.Method != "account/rateLimits/read" {
|
|
return
|
|
}
|
|
f.before = nil
|
|
if status == "interrupted" {
|
|
f.turn.Status = status
|
|
f.notify("turn/completed", params{ThreadID: "thread-1", Turn: f.turn})
|
|
} else {
|
|
f.goal = testGoal(paused)
|
|
f.human(f.goal)
|
|
}
|
|
}
|
|
for range 3 {
|
|
if err := f.reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if w := f.op.store.watch("thread-1"); w.eligible() || !w.Due.IsZero() || f.count("thread/goal/set") != 0 {
|
|
t.Fatal("usage response revoked human cancellation")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUsageReadError(t *testing.T) {
|
|
f := newFake(t, nil)
|
|
if err := f.reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
f.fail()
|
|
f.goal.Status = "usageLimited"
|
|
f.usageErr = &rpcError{Code: -32603, Message: "synthetic usage error"}
|
|
for poll := 1; poll <= 2; poll++ {
|
|
w := f.op.store.watch("thread-1")
|
|
w.Due = time.Now().Add(-time.Second)
|
|
if err := f.reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if f.count("account/rateLimits/read") != poll || f.count("thread/goal/set") != 0 || !w.Due.After(time.Now()) {
|
|
t.Fatal("usage read error lost polling or attempted work")
|
|
}
|
|
}
|
|
}
|