87 lines
3.5 KiB
C#
87 lines
3.5 KiB
C#
using AxCopilot.Services;
|
|
using FluentAssertions;
|
|
using Xunit;
|
|
|
|
namespace AxCopilot.Tests.Services;
|
|
|
|
public class DraftQueueProcessorServiceTests
|
|
{
|
|
[Fact]
|
|
public void TryStartNext_PicksPreferredDraftAndMarksItRunning()
|
|
{
|
|
var session = new ChatSessionStateService();
|
|
var processor = new DraftQueueProcessorService();
|
|
var first = session.EnqueueDraft("Chat", "first", "next");
|
|
var second = session.EnqueueDraft("Chat", "second", "later");
|
|
|
|
var started = processor.TryStartNext(session, "Chat", preferredDraftId: second!.Id);
|
|
|
|
started.Should().NotBeNull();
|
|
started!.Id.Should().Be(second.Id);
|
|
session.GetDraftQueueItems("Chat").Single(x => x.Id == second.Id).State.Should().Be("running");
|
|
session.GetDraftQueueItems("Chat").Single(x => x.Id == first!.Id).State.Should().Be("queued");
|
|
}
|
|
|
|
[Fact]
|
|
public void HandleFailure_SchedulesRetryBeforeRetryLimit()
|
|
{
|
|
var session = new ChatSessionStateService();
|
|
var processor = new DraftQueueProcessorService();
|
|
var item = session.EnqueueDraft("Chat", "retry me", "next");
|
|
processor.TryStartNext(session, "Chat", preferredDraftId: item!.Id);
|
|
|
|
var handled = processor.HandleFailure(session, "Chat", item.Id, "boom", cancelled: false, maxAutoRetries: 3);
|
|
|
|
handled.Should().BeTrue();
|
|
var stored = session.GetDraftQueueItems("Chat").Single(x => x.Id == item.Id);
|
|
stored.State.Should().Be("queued");
|
|
stored.NextRetryAt.Should().NotBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void PromoteReadyBlockedItems_ClearsExpiredRetryWindow()
|
|
{
|
|
var session = new ChatSessionStateService();
|
|
var processor = new DraftQueueProcessorService();
|
|
var item = session.EnqueueDraft("Chat", "retry me", "next");
|
|
processor.TryStartNext(session, "Chat", preferredDraftId: item!.Id);
|
|
processor.HandleFailure(session, "Chat", item.Id, "boom", cancelled: false, maxAutoRetries: 3);
|
|
session.CurrentConversation!.DraftQueueItems[0].NextRetryAt = DateTime.Now.AddSeconds(-1);
|
|
|
|
var promoted = processor.PromoteReadyBlockedItems(session, "Chat");
|
|
|
|
promoted.Should().Be(1);
|
|
session.CurrentConversation!.DraftQueueItems[0].NextRetryAt.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void ClearCompleted_RemovesCompletedItems()
|
|
{
|
|
var session = new ChatSessionStateService();
|
|
var processor = new DraftQueueProcessorService();
|
|
var item = session.EnqueueDraft("Chat", "done item", "next");
|
|
processor.TryStartNext(session, "Chat", preferredDraftId: item!.Id);
|
|
processor.Complete(session, "Chat", item.Id);
|
|
|
|
var removed = processor.ClearCompleted(session, "Chat");
|
|
|
|
removed.Should().Be(1);
|
|
session.GetDraftQueueItems("Chat").Should().BeEmpty();
|
|
}
|
|
|
|
[Fact]
|
|
public void TryStartNext_AndHandleFailure_RecordQueueTasks()
|
|
{
|
|
var session = new ChatSessionStateService();
|
|
var processor = new DraftQueueProcessorService();
|
|
var taskRuns = new TaskRunService();
|
|
var item = session.EnqueueDraft("Chat", "retry me", "next");
|
|
|
|
processor.TryStartNext(session, "Chat", preferredDraftId: item!.Id, taskRuns: taskRuns);
|
|
processor.HandleFailure(session, "Chat", item.Id, "boom", cancelled: false, maxAutoRetries: 3, taskRuns: taskRuns);
|
|
|
|
taskRuns.ActiveTasks.Should().BeEmpty();
|
|
taskRuns.RecentTasks.Should().ContainSingle(t => t.Kind == "queue" && t.Status == "blocked");
|
|
}
|
|
}
|