Implement InMemory Transport Layer for StellaOps Router
- Added InMemoryTransportOptions class for configuration settings including timeouts and latency. - Developed InMemoryTransportServer class to handle connections, frame processing, and event management. - Created ServiceCollectionExtensions for easy registration of InMemory transport services. - Established project structure and dependencies for InMemory transport library. - Implemented comprehensive unit tests for endpoint discovery, connection management, request/response flow, and streaming capabilities. - Ensured proper handling of cancellation, heartbeat, and hello frames within the transport layer.
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
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 InMemoryChannelTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task ToMicroservice_WritesAndReads()
|
||||
{
|
||||
// Arrange
|
||||
using var channel = new InMemoryChannel("test-1");
|
||||
var frame = new Frame
|
||||
{
|
||||
Type = FrameType.Request,
|
||||
CorrelationId = "corr-1",
|
||||
Payload = ReadOnlyMemory<byte>.Empty
|
||||
};
|
||||
|
||||
// Act
|
||||
await channel.ToMicroservice.Writer.WriteAsync(frame);
|
||||
var readFrame = await channel.ToMicroservice.Reader.ReadAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(FrameType.Request, readFrame.Type);
|
||||
Assert.Equal("corr-1", readFrame.CorrelationId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ToGateway_WritesAndReads()
|
||||
{
|
||||
// Arrange
|
||||
using var channel = new InMemoryChannel("test-1");
|
||||
var frame = new Frame
|
||||
{
|
||||
Type = FrameType.Response,
|
||||
CorrelationId = "corr-1",
|
||||
Payload = ReadOnlyMemory<byte>.Empty
|
||||
};
|
||||
|
||||
// Act
|
||||
await channel.ToGateway.Writer.WriteAsync(frame);
|
||||
var readFrame = await channel.ToGateway.Reader.ReadAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(FrameType.Response, readFrame.Type);
|
||||
Assert.Equal("corr-1", readFrame.CorrelationId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dispose_CancelsLifetimeToken()
|
||||
{
|
||||
// Arrange
|
||||
var channel = new InMemoryChannel("test-1");
|
||||
|
||||
// Act
|
||||
channel.Dispose();
|
||||
|
||||
// Assert
|
||||
Assert.True(channel.LifetimeToken.IsCancellationRequested);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dispose_CompletesChannels()
|
||||
{
|
||||
// Arrange
|
||||
var channel = new InMemoryChannel("test-1");
|
||||
|
||||
// Act
|
||||
channel.Dispose();
|
||||
|
||||
// Assert
|
||||
Assert.True(channel.ToMicroservice.Reader.Completion.IsCompleted);
|
||||
Assert.True(channel.ToGateway.Reader.Completion.IsCompleted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BoundedChannel_RespectsBufferSize()
|
||||
{
|
||||
// Arrange & Act
|
||||
using var channel = new InMemoryChannel("test-1", bufferSize: 5);
|
||||
|
||||
// Assert - no exception means it was created successfully
|
||||
Assert.NotNull(channel);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Instance_CanBeSetAndRetrieved()
|
||||
{
|
||||
// Arrange
|
||||
using var channel = new InMemoryChannel("test-1");
|
||||
var instance = new InstanceDescriptor
|
||||
{
|
||||
InstanceId = "inst-1",
|
||||
ServiceName = "test-service",
|
||||
Version = "1.0.0",
|
||||
Region = "eu1"
|
||||
};
|
||||
|
||||
// Act
|
||||
channel.Instance = instance;
|
||||
|
||||
// Assert
|
||||
Assert.Same(instance, channel.Instance);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user