using System.Text; using Microsoft.Extensions.DependencyInjection; using StellaOps.Router.Common.Enums; using StellaOps.Router.Common.Models; using StellaOps.Router.Transport.InMemory; using Xunit; namespace StellaOps.Router.Transport.InMemory.Tests; public class RequestResponseFlowTests { private readonly InMemoryConnectionRegistry _registry; private readonly InMemoryTransportServer _server; private readonly InMemoryTransportClient _client; public RequestResponseFlowTests() { var services = new ServiceCollection(); services.AddLogging(); services.AddInMemoryTransport(); var provider = services.BuildServiceProvider(); _registry = provider.GetRequiredService(); _server = provider.GetRequiredService(); _client = provider.GetRequiredService(); } [Fact] public async Task RequestResponse_RoundTrip() { // Arrange var instance = new InstanceDescriptor { InstanceId = "inst-1", ServiceName = "test-service", Version = "1.0.0", Region = "eu1" }; var endpoints = new List { new() { ServiceName = "test-service", Version = "1.0.0", Method = "GET", Path = "/api/echo" } }; await _server.StartAsync(CancellationToken.None); await _client.ConnectAsync(instance, endpoints, CancellationToken.None); // Setup request handler that echoes the payload _client.OnRequestReceived += (frame, ct) => { var response = new Frame { Type = FrameType.Response, CorrelationId = frame.CorrelationId, Payload = frame.Payload }; return Task.FromResult(response); }; // Start listening to the connection var connectionId = _registry.ConnectionIds.First(); _server.StartListeningToConnection(connectionId); // Give server time to start listening await Task.Delay(50); // Get connection state var connections = _registry.GetAllConnections(); var connection = connections[0]; // Act - send request from server to microservice var requestPayload = Encoding.UTF8.GetBytes("Hello, World!"); var requestFrame = new Frame { Type = FrameType.Request, CorrelationId = Guid.NewGuid().ToString("N"), Payload = requestPayload }; await _server.SendToMicroserviceAsync(connectionId, requestFrame, CancellationToken.None); // Wait for response await Task.Delay(200); // Assert - we sent the request successfully // In a full implementation, we'd capture the response via events Assert.Equal(1, _registry.Count); } [Fact] public async Task SendRequestAsync_TimesOut() { // Arrange var instance = new InstanceDescriptor { InstanceId = "inst-1", ServiceName = "test-service", Version = "1.0.0", Region = "eu1" }; await _server.StartAsync(CancellationToken.None); await _client.ConnectAsync(instance, [], CancellationToken.None); // No handler registered - request will never be answered var connectionId = _registry.ConnectionIds.First(); _server.StartListeningToConnection(connectionId); var connections = _registry.GetAllConnections(); var connection = connections[0]; var requestFrame = new Frame { Type = FrameType.Request, CorrelationId = Guid.NewGuid().ToString("N"), Payload = ReadOnlyMemory.Empty }; // Act & Assert await Assert.ThrowsAsync(() => _client.SendRequestAsync(connection, requestFrame, TimeSpan.FromMilliseconds(100), CancellationToken.None)); } }