Files
agent-framework/dotnet/tests/Microsoft.Agents.Workflows.UnitTests/StreamingAggregatorsTests.cs
T
Jacob Alber d7c39d72cc .NET: feat: Implement Checkpointing API (#420)
* feat: Implement Checkpointing API

* refactor: Normalzie Namespaces and break out multi-class files

* feat: Support checkpointing in AIAgentHostExecutor

* test: Representation tests

* feat: Add Step-level Tracing and WorkflowEvents

* feat: Add Checkpointing Sample and Smoke Test

* Fixes an issue where StateManager was not properly clearing the incoming queued updates.
* Fixes order of checkpointing and in-step event publication
* Adds import of RunContext state on LoadCheckpoint
* Add re-firing of events for unserviced ExternalRequests on Checkpoint load

* docs: Add documentation to publics

* Also adds documentation to ICheckpointManager which may go public

* refactor: Fix Union Aggregators and add Tests

* fix: Fix issues raised in PR comments and remove dead code
2025-08-25 23:04:38 +00:00

119 lines
4.5 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
namespace Microsoft.Agents.Workflows.UnitTests;
public class StreamingAggregatorsTests
{
private static TResult? ApplyStreamingAggregator<TInput, TResult>(
StreamingAggregator<TInput, TResult> aggregator,
IEnumerable<TInput> inputs,
TResult? runningResult = default)
{
foreach (TInput input in inputs)
{
runningResult = aggregator(input, runningResult);
}
return runningResult!;
}
[Fact]
public void Test_StreamingAggregators_First()
{
IEnumerable<int> inputs = [1, 2, 3];
StreamingAggregator<int, int> aggregator = StreamingAggregators.First<int>();
int? runningResult = ApplyStreamingAggregator(aggregator, inputs);
runningResult.Should().Be(1);
// Ensure that subsequent inputs do not change the result
ApplyStreamingAggregator(aggregator, inputs.Skip(1), runningResult.Value)
.Should()
.Be(1, "subsequent inputs should not change the result of First aggregator");
}
[Fact]
public void Test_StreamingAggregators_First_WithConversion()
{
IEnumerable<int> inputs = [2, 4, 6];
StreamingAggregator<int, int> aggregator = StreamingAggregators.First<int, int>(input => input / 2);
int? runningResult = ApplyStreamingAggregator(aggregator, inputs);
runningResult.Should().Be(1);
// Ensure that subsequent inputs do not change the result
ApplyStreamingAggregator(aggregator, inputs.Skip(1), runningResult.Value)
.Should()
.Be(1, "subsequent inputs should not change the result of First aggregator with conversion");
}
[Fact]
public void Test_StreamingAggregators_Last()
{
IEnumerable<int> inputs = [1, 2, 3];
StreamingAggregator<int, int> aggregator = StreamingAggregators.Last<int>();
int? runningResult = ApplyStreamingAggregator(aggregator, inputs);
runningResult.Should().Be(3);
// Ensure that subsequent inputs do change the result
ApplyStreamingAggregator(aggregator, inputs.Take(2), runningResult.Value)
.Should()
.Be(2, "subsequent inputs should change the result of Last aggregator");
}
[Fact]
public void Test_StreamingAggregators_Last_WithConversion()
{
IEnumerable<int> inputs = [2, 4, 6];
StreamingAggregator<int, int> aggregator = StreamingAggregators.Last<int, int>(input => input / 2);
int? runningResult = ApplyStreamingAggregator(aggregator, inputs);
runningResult.Should().Be(3);
// Ensure that subsequent inputs do change the result
ApplyStreamingAggregator(aggregator, inputs.Take(2), runningResult.Value)
.Should()
.Be(2, "subsequent inputs should change the result of Last aggregator");
}
[Fact]
public void Test_StreamingAggregators_Union()
{
IEnumerable<int> inputs = [1, 2, 3];
StreamingAggregator<int, IEnumerable<int>> aggregator = StreamingAggregators.Union<int>();
IEnumerable<int>? runningResult = ApplyStreamingAggregator(aggregator, inputs);
runningResult.Should().BeEquivalentTo([1, 2, 3], "Union should accumulate all inputs in order");
// Ensure that subsequent inputs concatenate to the existing results
inputs = [4, 5];
ApplyStreamingAggregator(aggregator, inputs, runningResult)
.Should()
.BeEquivalentTo([1, 2, 3, 4, 5], "Union should accumulate all inputs in order including subsequent inputs");
}
[Fact]
public void Test_StreamingAggregators_Union_WithConversion()
{
IEnumerable<int> inputs = [2, 4, 6];
StreamingAggregator<int, IEnumerable<int>> aggregator = StreamingAggregators.Union<int, int>(input => input / 2);
IEnumerable<int>? runningResult = ApplyStreamingAggregator(aggregator, inputs);
runningResult.Should().BeEquivalentTo([1, 2, 3],
"Union with conversion should accumulate all converted inputs in order");
// Ensure that subsequent inputs concatenate to the existing results
inputs = [8, 10];
ApplyStreamingAggregator(aggregator, inputs, runningResult)
.Should()
.BeEquivalentTo([1, 2, 3, 4, 5],
"Union with conversion should accumulate all converted inputs in order including subsequent inputs");
}
}