+ require.Contains(t, report.String(), "calls at once: at most ")
+ require.Contains(t, report.String(), "quota at the first call: primary-used-percent=")
+}
+
+func TestProbeRunStopsAtTheCallLimit(t *testing.T) {
+ server := newModelFake(t)
+ run := newTestProbeRun(t, server)
+ run.client.LimitCalls(5)
+
+ entries := make([]probeEntry, 40)
+ for n := range entries {
+ entries[n] = probeEntry{
+ Kind: "echo",
+ Text: strings.Repeat("long output ", 100),
+ }
+ }
+
+ _, stop := run.Run(t.Context(), entries)
+ require.NoError(t, run.memory.Close())
+ require.Equal(t, "call limit of 5 reached", stop)
+ require.Equal(t, 5, server.Calls())
+}
+
+func TestProbeRunWaitsOnlyBeforeUserMessages(t *testing.T) {
+ gate := make(chan struct{})
+ var mutex sync.Mutex
+ running, most := 0, 0
+ server := newModelFake(t)
+ server.reply = func(w http.ResponseWriter, call ModelFakeCall) {
+ mutex.Lock()
+ running++
+ most = max(most, running)
+ mutex.Unlock()
+
+ <-gate
+
+ mutex.Lock()
+ running--
+ mutex.Unlock()
+
+ modelWriteEvents(w, modelCompletedEvent([]any{modelMessageItem("a line")}, 100, 0, 5))
+ }
+
+ run := newTestProbeRun(t, server)
+ long := strings.Repeat("long output ", 100)
+ entries := []probeEntry{
+ {
+ Kind: "echo",
+ Text: long,
+ },
+ {
+ Kind: "tool",
+ Text: long,
+ },
+ {
+ Kind: "user",
+ Text: "next",
+ },
+ {
+ Kind: "reply",
+ Text: long,
+ },
+ }
+
+ done := make(chan string)
+ go func() {
+ _, stop := run.Run(t.Context(), entries)
+ done <- stop
+ }()
+
+ require.Eventually(t, func() bool {
+ return server.Calls() == 2
+ }, 10*time.Second, time.Millisecond)
+
+ run.memory.mutex.Lock()
+ appended := run.memory.log.Len()
+ run.memory.mutex.Unlock()
+ require.Equal(t, 2, appended)
+
+ close(gate)
+ require.Empty(t, <-done)
+ require.NoError(t, run.memory.Close())
+
+ mutex.Lock()
+ defer mutex.Unlock()
+
+ require.Equal(t, 2, most)
+ require.Equal(t, 3, server.Calls())
+}
+
+func TestSlotSummarizerLimitsTheBuildsAtOnce(t *testing.T) {
+ inner := newFakeSummarizer()
+ inner.gate = make(chan struct{})
+ summarizer := slotSummarizer{
+ inner: inner,
+ slots: make(chan struct{}, 2),
+ }
+
+ var group sync.WaitGroup
+ for n := range 6 {
+ group.Go(func() {
+ _, err := summarizer.Summarize(t.Context(), Task{
+ Level: 0,
+ Index: n,
+ Input: []string{"user: " + strings.Repeat("x", 600)},
+ })
+ require.NoError(t, err)
+ })
+ }
+
+ require.Eventually(t, func() bool {
+ return inner.Active() == 2
+ }, 10*time.Second, time.Millisecond)
+
+ close(inner.gate)
+ group.Wait()
+ require.Equal(t, 2, inner.peak)
+}
+
+func TestReadUsageFileSortsByCallStart(t *testing.T) {
+ path := filepath.Join(t.TempDir(), "usage.jsonl")
+ usage := ModelUsageLog{
+ path: path,
+ }
+
+ for _, date := range []string{"2026-01-01T12:00:02Z", "2026-01-01T12:00:00.5Z", "2026-01-01T12:00:01.25Z"} {
+ require.NoError(t, usage.Write(ModelUsageRecord{
+ Date: date,
+ }))
+ }
+
+ records, err := readUsageFile(path)
+ require.NoError(t, err)
+ require.Equal(t, []string{"2026-01-01T12:00:00.5Z", "2026-01-01T12:00:01.25Z", "2026-01-01T12:00:02Z"}, []string{records[0].Date, records[1].Date, records[2].Date})
+}
+
+func TestTimeTextCountsTheCallsAtOnce(t *testing.T) {
+ start := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)
+ record := func(offset, seconds float64) ModelUsageRecord {
+ return ModelUsageRecord{
+ Date: start.Add(time.Duration(offset * float64(time.Second))).Format(time.RFC3339Nano),
+ Seconds: seconds,
+ }
+ }
+
+ text := timeText([]ModelUsageRecord{record(0, 10), record(2, 4), record(3, 2), record(10, 10)})
+ require.Equal(t, "time: 20 s in all, 12.0 calls per minute, 6.5 s per call (median 10.0, max 10.0), calls at once: at most 3, 1.3 on average", text)