Files
satellite-provider/SatelliteProvider.Tests/RegionRequestQueueTests.cs
T
Oleksandr Bezdieniezhnykh 7822841587 [AZ-289] [AZ-290] Batch 3 tests: integration ZIP cap, perf, security, queue
AZ-289 — RL-01 50MB ZIP cap added to RunRouteWithTilesZipTest;
existing integration tests already cover BT-08/BT-09 + AC-1/AC-2.

AZ-290:
- scripts/run-performance-tests.sh extended with PT-01/03/04/05
- SatelliteProvider.IntegrationTests/SecurityTests.cs (SEC-01..SEC-04),
  wired into Program.cs
- SatelliteProvider.Tests/RegionRequestQueueTests.cs covering RS-04 /
  RL-02 queue capacity behavior

Notes:
- RS-04 spec wording ("rejects overflow") drifts from the channel's
  BoundedChannelFullMode.Wait back-pressure semantics. Tests assert
  the actual behavior; spec to be reconciled in Step 12 (Test-Spec
  Sync). Tracked as Low/Spec-Gap in batch_03_review.md.
- Unit tests: 35/35 passed (Docker .NET 8 SDK).
- Integration test project builds clean (0 warnings, 0 errors).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-10 05:10:30 +03:00

86 lines
2.6 KiB
C#

using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using SatelliteProvider.Common.DTO;
using SatelliteProvider.Services;
namespace SatelliteProvider.Tests;
public class RegionRequestQueueTests
{
private static RegionRequest BuildRequest() => new()
{
Id = Guid.NewGuid(),
Latitude = 47.461747,
Longitude = 37.647063,
SizeMeters = 200,
ZoomLevel = 18,
StitchTiles = false
};
[Fact]
public async Task EnqueueAsync_RespectsCapacity_WritesUpToCapacityWithoutBlocking_RS04()
{
const int capacity = 10;
var queue = new RegionRequestQueue(capacity, NullLogger<RegionRequestQueue>.Instance);
for (var i = 0; i < capacity; i++)
{
await queue.EnqueueAsync(BuildRequest());
}
queue.Count.Should().Be(capacity);
}
[Fact]
public async Task EnqueueAsync_BlocksWhenAtCapacity_UntilDequeue_RL02()
{
const int capacity = 2;
var queue = new RegionRequestQueue(capacity, NullLogger<RegionRequestQueue>.Instance);
await queue.EnqueueAsync(BuildRequest());
await queue.EnqueueAsync(BuildRequest());
var overflow = queue.EnqueueAsync(BuildRequest()).AsTask();
var completedFirst = await Task.WhenAny(overflow, Task.Delay(150));
completedFirst.Should().NotBeSameAs(overflow, "overflow enqueue must wait while queue is full");
var dequeued = await queue.DequeueAsync();
dequeued.Should().NotBeNull();
await overflow.WaitAsync(TimeSpan.FromSeconds(1));
queue.Count.Should().Be(capacity);
}
[Fact]
public async Task EnqueueAsync_HonorsCancellation_WhenFull()
{
var queue = new RegionRequestQueue(1, NullLogger<RegionRequestQueue>.Instance);
await queue.EnqueueAsync(BuildRequest());
using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(150));
Func<Task> act = async () => await queue.EnqueueAsync(BuildRequest(), cts.Token);
await act.Should().ThrowAsync<OperationCanceledException>();
}
[Fact]
public async Task DequeueAsync_ReturnsItemsInFifoOrder()
{
var queue = new RegionRequestQueue(8, NullLogger<RegionRequestQueue>.Instance);
var first = BuildRequest();
var second = BuildRequest();
await queue.EnqueueAsync(first);
await queue.EnqueueAsync(second);
var dequeued1 = await queue.DequeueAsync();
var dequeued2 = await queue.DequeueAsync();
dequeued1!.Id.Should().Be(first.Id);
dequeued2!.Id.Should().Be(second.Id);
queue.Count.Should().Be(0);
}
}