Add unit tests for RabbitMq and Udp transport servers and clients
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Implemented comprehensive unit tests for RabbitMqTransportServer, covering constructor, disposal, connection management, event handlers, and exception handling.
- Added configuration tests for RabbitMqTransportServer to validate SSL, durable queues, auto-recovery, and custom virtual host options.
- Created unit tests for UdpFrameProtocol, including frame parsing and serialization, header size validation, and round-trip data preservation.
- Developed tests for UdpTransportClient, focusing on connection handling, event subscriptions, and exception scenarios.
- Established tests for UdpTransportServer, ensuring proper start/stop behavior, connection state management, and event handling.
- Included tests for UdpTransportOptions to verify default values and modification capabilities.
- Enhanced service registration tests for Udp transport services in the dependency injection container.
This commit is contained in:
master
2025-12-05 19:01:12 +02:00
parent 53508ceccb
commit cc69d332e3
245 changed files with 22440 additions and 27719 deletions

View File

@@ -1,6 +1,7 @@
using System.Text.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StellaOps.Microservice.Validation;
using StellaOps.Router.Common.Frames;
using StellaOps.Router.Common.Models;
@@ -15,6 +16,8 @@ public sealed class RequestDispatcher
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<RequestDispatcher> _logger;
private readonly JsonSerializerOptions _jsonOptions;
private readonly ISchemaRegistry? _schemaRegistry;
private readonly IRequestSchemaValidator? _schemaValidator;
/// <summary>
/// Initializes a new instance of the <see cref="RequestDispatcher"/> class.
@@ -22,16 +25,22 @@ public sealed class RequestDispatcher
/// <param name="registry">The endpoint registry.</param>
/// <param name="serviceProvider">The service provider for resolving handlers.</param>
/// <param name="logger">The logger.</param>
/// <param name="schemaRegistry">Optional schema registry for validation.</param>
/// <param name="schemaValidator">Optional schema validator.</param>
/// <param name="jsonOptions">Optional JSON serialization options.</param>
public RequestDispatcher(
IEndpointRegistry registry,
IServiceProvider serviceProvider,
ILogger<RequestDispatcher> logger,
ISchemaRegistry? schemaRegistry = null,
IRequestSchemaValidator? schemaValidator = null,
JsonSerializerOptions? jsonOptions = null)
{
_registry = registry;
_serviceProvider = serviceProvider;
_logger = logger;
_schemaRegistry = schemaRegistry;
_schemaValidator = schemaValidator;
_jsonOptions = jsonOptions ?? new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
@@ -180,6 +189,60 @@ public sealed class RequestDispatcher
{
try
{
// Schema validation (before deserialization)
if (_schemaRegistry is not null && _schemaValidator is not null &&
_schemaRegistry.HasSchema(context.Method, context.Path, SchemaDirection.Request))
{
if (context.Body == Stream.Null || context.Body.Length == 0)
{
return ValidationProblemDetails.Create(
context.Method,
context.Path,
SchemaDirection.Request,
[new SchemaValidationError("/", "#", "Request body is required", "required")],
context.CorrelationId
).ToRawResponse();
}
context.Body.Position = 0;
JsonDocument doc;
try
{
doc = await JsonDocument.ParseAsync(context.Body, cancellationToken: cancellationToken);
}
catch (JsonException ex)
{
return ValidationProblemDetails.Create(
context.Method,
context.Path,
SchemaDirection.Request,
[new SchemaValidationError("/", "#", $"Invalid JSON: {ex.Message}", "json")],
context.CorrelationId
).ToRawResponse();
}
var schema = _schemaRegistry.GetRequestSchema(context.Method, context.Path);
if (schema is not null && !_schemaValidator.TryValidate(doc, schema, out var errors))
{
_logger.LogInformation(
"Schema validation failed for {Method} {Path}: {ErrorCount} errors",
context.Method,
context.Path,
errors.Count);
return ValidationProblemDetails.Create(
context.Method,
context.Path,
SchemaDirection.Request,
errors,
context.CorrelationId
).ToRawResponse();
}
// Reset stream for deserialization
context.Body.Position = 0;
}
// Deserialize request
object? request;
if (context.Body == Stream.Null || context.Body.Length == 0)