Files
go-sip/internal/store/lease_test.go
T

94 lines
2.7 KiB
Go

package store
import (
"errors"
"path/filepath"
"testing"
"time"
)
func TestSingleActiveLeaseAndExpiry(t *testing.T) {
now := time.Date(2026, 9, 18, 0, 0, 0, 0, time.UTC)
var current = now
s, err := Open(":memory:")
if err != nil {
t.Fatal(err)
}
defer s.Close()
s.now = func() time.Time { return current }
if _, err := s.AcquireLease("lease-a", "dispatcher", "holder-a", time.Minute); err != nil {
t.Fatal(err)
}
if _, err := s.AcquireLease("lease-b", "dispatcher", "holder-b", time.Minute); !errors.Is(err, ErrLeaseHeld) {
t.Fatalf("second holder error = %v", err)
}
current = current.Add(2 * time.Minute)
if _, err := s.AcquireLease("lease-b", "dispatcher", "holder-b", time.Minute); err != nil {
t.Fatal(err)
}
if err := s.ReleaseLease("lease-b"); err != nil {
t.Fatal(err)
}
}
func TestRecoverOutboxRequeuesClaimedRows(t *testing.T) {
s := testStore(t)
if _, err := s.DB().Exec(`INSERT INTO outbox(event_id, tenant_key, exchange, routing_key, body, status, created_at) VALUES('e1', 'tenant', 'agent-call.events.v1', 'rk', '{}', 'dispatching', '2026-09-18T00:00:00Z')`); err != nil {
t.Fatal(err)
}
if err := s.RecoverOutbox(); err != nil {
t.Fatal(err)
}
var status, lastError string
if err := s.DB().QueryRow(`SELECT status, last_error FROM outbox WHERE event_id = 'e1'`).Scan(&status, &lastError); err != nil {
t.Fatal(err)
}
if status != "retry" || lastError != "recovered_after_restart" {
t.Fatalf("status=%q error=%q", status, lastError)
}
}
func TestOutboxRecoverySurvivesSQLiteReopen(t *testing.T) {
path := filepath.Join(t.TempDir(), "dispatcher.db")
first, err := Open(path)
if err != nil {
t.Fatal(err)
}
firstClosed := false
t.Cleanup(func() {
if !firstClosed {
if err := first.Close(); err != nil {
t.Error(err)
}
}
})
result, err := first.DB().Exec(`INSERT INTO outbox(event_id, tenant_key, exchange, routing_key, body, status, created_at) VALUES('restart-e1', 'tenant', 'agent-call.events.v1', 'rk', '{}', 'dispatching', '2026-09-18T00:00:00Z')`)
if err != nil {
t.Fatal(err)
}
if rows, err := result.RowsAffected(); err != nil || rows != 1 {
t.Fatalf("inserted rows=%d err=%v, want 1", rows, err)
}
if err := first.Close(); err != nil {
t.Fatal(err)
}
firstClosed = true
second, err := Open(path)
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
if err := second.Close(); err != nil {
t.Error(err)
}
})
var status, lastError string
if err := second.DB().QueryRow(`SELECT status, last_error FROM outbox WHERE event_id = 'restart-e1'`).Scan(&status, &lastError); err != nil {
t.Fatal(err)
}
if status != "retry" || lastError != "recovered_after_restart" {
t.Fatalf("status=%q error=%q after reopen", status, lastError)
}
}