mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-07-25 18:19:19 +00:00
89 lines
2.5 KiB
Go
89 lines
2.5 KiB
Go
//go:build sqlite || sqliteonly
|
|
|
|
package sqlitestore
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/nextlevelbuilder/goclaw/internal/store"
|
|
)
|
|
|
|
func TestSQLiteUsageEventStoreRefreshRollupHourIsIdempotent(t *testing.T) {
|
|
db := openTestDB(t)
|
|
if err := EnsureSchema(db); err != nil {
|
|
t.Fatalf("EnsureSchema: %v", err)
|
|
}
|
|
|
|
eventStore := NewSQLiteUsageEventStore(db)
|
|
ctx := store.WithTenantID(context.Background(), store.MasterTenantID)
|
|
bucket := time.Date(2026, 6, 12, 8, 0, 0, 0, time.UTC)
|
|
|
|
if err := eventStore.InsertEvent(ctx, &store.UsageEvent{
|
|
ID: uuid.New(),
|
|
TenantID: store.MasterTenantID,
|
|
EventTime: bucket.Add(10 * time.Minute),
|
|
EventType: store.UsageEventTypeRuntimeToolCall,
|
|
ResourceType: store.UsageResourceTypeRuntimeTool,
|
|
ResourceName: "exec",
|
|
ResourceID: "exec",
|
|
Source: store.UsageSourceToolCall,
|
|
Status: "completed",
|
|
InputTokens: 10,
|
|
TotalTokens: 10,
|
|
DurationMS: 50,
|
|
CallCount: 1,
|
|
}); err != nil {
|
|
t.Fatalf("InsertEvent first: %v", err)
|
|
}
|
|
if err := eventStore.RefreshEventRollupHour(ctx, bucket); err != nil {
|
|
t.Fatalf("Refresh first: %v", err)
|
|
}
|
|
|
|
if err := eventStore.InsertEvent(ctx, &store.UsageEvent{
|
|
ID: uuid.New(),
|
|
TenantID: store.MasterTenantID,
|
|
EventTime: bucket.Add(20 * time.Minute),
|
|
EventType: store.UsageEventTypeRuntimeToolCall,
|
|
ResourceType: store.UsageResourceTypeRuntimeTool,
|
|
ResourceName: "exec",
|
|
ResourceID: "exec",
|
|
Source: store.UsageSourceToolCall,
|
|
Status: "error",
|
|
OutputTokens: 5,
|
|
TotalTokens: 5,
|
|
DurationMS: 150,
|
|
CallCount: 1,
|
|
ErrorCount: 1,
|
|
}); err != nil {
|
|
t.Fatalf("InsertEvent second: %v", err)
|
|
}
|
|
if err := eventStore.RefreshEventRollupHour(ctx, bucket); err != nil {
|
|
t.Fatalf("Refresh second: %v", err)
|
|
}
|
|
if err := eventStore.RefreshEventRollupHour(ctx, bucket); err != nil {
|
|
t.Fatalf("Refresh idempotent: %v", err)
|
|
}
|
|
|
|
summary, err := eventStore.GetEventSummary(ctx, store.UsageEventQuery{
|
|
From: bucket,
|
|
To: bucket.Add(time.Hour),
|
|
ResourceType: store.UsageResourceTypeRuntimeTool,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("GetEventSummary: %v", err)
|
|
}
|
|
if summary.Calls != 2 || summary.Errors != 1 {
|
|
t.Fatalf("summary calls/errors = %d/%d, want 2/1", summary.Calls, summary.Errors)
|
|
}
|
|
if summary.TotalTokens != 15 {
|
|
t.Fatalf("summary tokens = %d, want 15", summary.TotalTokens)
|
|
}
|
|
if summary.AvgDurationMS != 100 {
|
|
t.Fatalf("summary avg duration = %d, want 100", summary.AvgDurationMS)
|
|
}
|
|
}
|