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:
StellaOps Bot
2025-12-05 01:00:10 +02:00
parent 8768c27f30
commit 175b750e29
111 changed files with 25407 additions and 19242 deletions

View File

@@ -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);
}
}