package runner import ( "errors" "testing" "time" "github.com/easyai/easyai-ai-gateway/apps/api/internal/store" ) func TestLeaseRenewalFatalityDistinguishesTransientDatabaseErrors(t *testing.T) { now := time.Now() deadline := now.Add(time.Minute) transient := errors.New("lock timeout") if taskExecutionLeaseRenewalIsFatal(transient, now, deadline) { t.Fatal("transient task lease renewal error must be retried before expiry") } if concurrencyLeaseRenewalIsFatal(transient, now, deadline) { t.Fatal("transient concurrency lease renewal error must be retried before expiry") } if !taskExecutionLeaseRenewalIsFatal(store.ErrTaskExecutionLeaseLost, now, deadline) { t.Fatal("confirmed task lease ownership loss must be fatal") } if !concurrencyLeaseRenewalIsFatal(store.ErrConcurrencyLeaseLost, now, deadline) { t.Fatal("confirmed concurrency lease ownership loss must be fatal") } if !taskExecutionLeaseRenewalIsFatal(transient, deadline, deadline) { t.Fatal("task lease renewal error at expiry must be fatal") } if !concurrencyLeaseRenewalIsFatal(transient, deadline, deadline) { t.Fatal("concurrency lease renewal error at expiry must be fatal") } } func TestBindAttemptConcurrencyLeasesPreservesAdmissionLeaseAcrossRetry(t *testing.T) { attemptLease := store.ConcurrencyLease{ID: "attempt-lease", TTL: time.Minute} admissionLeases := []store.ConcurrencyLease{ {ID: "admission-user-group", TTL: 2 * time.Minute}, {ID: "admission-worker-capacity", TTL: 2 * time.Minute}, } active, release := bindAttemptConcurrencyLeases([]store.ConcurrencyLease{attemptLease}, admissionLeases) if len(active) != 3 || active[0].ID != attemptLease.ID || active[1].ID != admissionLeases[0].ID || active[2].ID != admissionLeases[1].ID { t.Fatalf("active leases must renew attempt and admission ownership together: %+v", active) } if len(release) != 1 || release[0].ID != attemptLease.ID { t.Fatalf("attempt cleanup must not release task-scoped admission leases: %+v", release) } // A same-platform retry receives the same admission lease IDs. The first // attempt cleanup must leave them renewable by the next attempt. retryActive, retryRelease := bindAttemptConcurrencyLeases(nil, admissionLeases) if len(retryActive) != 2 || retryActive[0].ID != admissionLeases[0].ID || retryActive[1].ID != admissionLeases[1].ID { t.Fatalf("retry must keep using the live admission leases: %+v", retryActive) } if len(retryRelease) != 0 { t.Fatalf("retry without attempt-owned leases must not release admission leases: %+v", retryRelease) } }