textmachine/backend/internal/store/ledger_test.go

51 lines
1.7 KiB
Go

package store
import "testing"
// TestCheckpointUsageForBookReturnsInsertionOrder pins the ordering the re-payment projection reads
// generation membership from (pipeline/reprice.go). Checkpoints are append-only for the life of a book,
// so telling this run's calls from a superseded run's is possible only by WHEN each was written.
// `attempt` cannot do it — it restarts at 0 every run — which is exactly what this fixture makes visible:
// the attempt numbers run 0,1,0,1 while the insertion order is g1a0, g1a1, g2a0, g2a1.
func TestCheckpointUsageForBookReturnsInsertionOrder(t *testing.T) {
s, _ := openTemp(t)
job := mustSnapshotAndJob(t, s)
for _, cp := range []struct {
hash string
attempt int
cost float64
}{
{"g1a0", 0, 0.01}, {"g1a1", 1, 0.02}, // generation 1
{"g2a0", 0, 0.03}, {"g2a1", 1, 0.04}, // generation 2, written later, attempts restart
} {
res, _, err := s.Reserve("book", cp.cost, Ceilings{BookUSD: 100, DayUSD: 100})
if err != nil {
t.Fatal(err)
}
if err := s.SettleWithCheckpoint(res, cp.cost, Checkpoint{
RequestHash: cp.hash, JobID: job.ID, ChunkIdx: 0, Attempt: cp.attempt, Stage: "draft",
Role: "translator", ModelRequested: "m", ModelActual: "m", UsageJSON: "{}", CostUSD: cp.cost,
}, nil); err != nil {
t.Fatal(err)
}
}
rows, err := s.CheckpointUsageForBook("book")
if err != nil {
t.Fatal(err)
}
var got []float64
for _, r := range rows {
got = append(got, r.CostUSD)
}
want := []float64{0.01, 0.02, 0.03, 0.04} // ordering by `attempt` would give 0.01, 0.03, 0.02, 0.04
if len(got) != len(want) {
t.Fatalf("got %d rows, want %d", len(got), len(want))
}
for i := range want {
if got[i] != want[i] {
t.Fatalf("checkpoint order = %v, want insertion order %v", got, want)
}
}
}