47 lines
1.5 KiB
C#
47 lines
1.5 KiB
C#
using w4c_workflows.Services;
|
|
using w4c_workflows.Services.Messaging;
|
|
using Xunit;
|
|
|
|
namespace w4c_workflows.Tests;
|
|
|
|
/// <summary>
|
|
/// Backlog-bound regression tests: a stalled in-memory consumer must not be able
|
|
/// to grow server memory without limit. Both channels are bounded and drop the
|
|
/// oldest entry under pressure.
|
|
/// </summary>
|
|
public class BoundedChannelTests
|
|
{
|
|
[Fact]
|
|
public void RealtimeEventHub_bounds_the_per_client_backlog()
|
|
{
|
|
var hub = new RealtimeEventHub();
|
|
var (id, reader) = hub.AddClient("tenant-a");
|
|
|
|
for (var i = 0; i < 300; i++)
|
|
hub.Publish("tenant-a", "workflow", i.ToString(), DateTime.UtcNow);
|
|
|
|
var received = 0;
|
|
while (reader.TryRead(out _))
|
|
received++;
|
|
|
|
// Client channel capacity is 256 and DropOldest keeps the newest entries.
|
|
Assert.Equal(256, received);
|
|
|
|
hub.RemoveClient("tenant-a", id);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task InMemoryTransport_bounds_the_job_backlog()
|
|
{
|
|
var transport = new InMemoryTransport();
|
|
|
|
for (var i = 0; i < 10_500; i++)
|
|
await transport.EnqueueAsync("tenant-b", new Dictionary<string, string> { ["n"] = i.ToString() }, default);
|
|
|
|
var drained = await transport.ReadGroupAsync("tenant-b", "consumer", 20_000, default);
|
|
|
|
Assert.True(drained.Count > 0, "no messages were readable");
|
|
Assert.True(drained.Count <= 10_000, $"job backlog was not bounded: {drained.Count}");
|
|
}
|
|
}
|