TaskExecutionCompositeSelectionTests.cs 4.37 KB
using Rcs.Infrastructure.Services;
using Xunit;

namespace Rcs.Infrastructure.Tests;

public class TaskExecutionCompositeSelectionTests
{
    [Fact]
    public void SelectExecutionCandidate_UsesPriorityThenCompletionAsPrimaryRank()
    {
        var t1 = Guid.NewGuid();
        var t2 = Guid.NewGuid();

        var inputs = new[]
        {
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                t1, 100, 0.60d, 20d, 2000, 0d),
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                t2, 100, 0.20d, 1d, 1000, 50d)
        };

        var decision = TaskExecutionBackgroundService.SelectExecutionCandidate(inputs, 10d, 5d);

        Assert.NotNull(decision);
        Assert.Equal(t1, decision.Value.PrimaryTaskId);
        Assert.Equal(t1, decision.Value.SelectedTaskId);
        Assert.Equal(TaskExecutionBackgroundService.CandidateSelectionBucket.Primary, decision.Value.Bucket);
    }

    [Fact]
    public void SelectExecutionCandidate_PrefersEqualPriorityReplacementFirst()
    {
        var primaryTaskId = Guid.NewGuid();
        var equalA = Guid.NewGuid();
        var equalB = Guid.NewGuid();
        var lower = Guid.NewGuid();

        var inputs = new[]
        {
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                primaryTaskId, 100, 0.90d, 10d, 1000, 0d),
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                equalA, 100, 0.10d, 30d, 2000, 60d),
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                equalB, 100, 0.10d, 40d, 1500, 10d),
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                lower, 90, 0.10d, 20d, 900, 2d)
        };

        var decision = TaskExecutionBackgroundService.SelectExecutionCandidate(inputs, 100d, 20d);

        Assert.NotNull(decision);
        Assert.Equal(primaryTaskId, decision.Value.PrimaryTaskId);
        Assert.Equal(equalB, decision.Value.SelectedTaskId);
        Assert.Equal(TaskExecutionBackgroundService.CandidateSelectionBucket.EqualPriorityReplacement, decision.Value.Bucket);
    }

    [Fact]
    public void SelectExecutionCandidate_UsesLowerPriorityReplacementWhenNoEqualPriorityCandidatePassesThreshold()
    {
        var primaryTaskId = Guid.NewGuid();
        var equalNotQualified = Guid.NewGuid();
        var lowerA = Guid.NewGuid();
        var lowerB = Guid.NewGuid();

        var inputs = new[]
        {
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                primaryTaskId, 100, 0.80d, 12d, 1000, 0d),
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                equalNotQualified, 100, 0.10d, 15d, 800, 150d),
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                lowerA, 95, 0.10d, 25d, 1100, 18d),
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                lowerB, 90, 0.10d, 8d, 700, 6d)
        };

        var decision = TaskExecutionBackgroundService.SelectExecutionCandidate(inputs, 100d, 20d);

        Assert.NotNull(decision);
        Assert.Equal(primaryTaskId, decision.Value.PrimaryTaskId);
        Assert.Equal(lowerB, decision.Value.SelectedTaskId);
        Assert.Equal(TaskExecutionBackgroundService.CandidateSelectionBucket.LowerPriorityReplacement, decision.Value.Bucket);
    }

    [Fact]
    public void SelectExecutionCandidate_FallsBackToPrimaryWhenNoReplacementPassesThreshold()
    {
        var primaryTaskId = Guid.NewGuid();
        var equalTooLarge = Guid.NewGuid();
        var lowerTooLarge = Guid.NewGuid();

        var inputs = new[]
        {
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                primaryTaskId, 100, 0.40d, 8d, 1000, 0d),
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                equalTooLarge, 100, 0.30d, 6d, 900, 101d),
            new TaskExecutionBackgroundService.ExecutionCandidateInput(
                lowerTooLarge, 90, 0.30d, 5d, 800, 21d)
        };

        var decision = TaskExecutionBackgroundService.SelectExecutionCandidate(inputs, 100d, 20d);

        Assert.NotNull(decision);
        Assert.Equal(primaryTaskId, decision.Value.PrimaryTaskId);
        Assert.Equal(primaryTaskId, decision.Value.SelectedTaskId);
        Assert.Equal(TaskExecutionBackgroundService.CandidateSelectionBucket.Primary, decision.Value.Bucket);
    }
}