Initial import of the CBDDC codebase with docs and tests. Add a .NET-focused gitignore to keep generated artifacts out of source control.
Some checks failed
CI / verify (push) Has been cancelled
Some checks failed
CI / verify (push) Has been cancelled
This commit is contained in:
90
tests/ZB.MOM.WW.CBDDC.Network.Tests/ConnectionTests.cs
Normal file
90
tests/ZB.MOM.WW.CBDDC.Network.Tests/ConnectionTests.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
using ZB.MOM.WW.CBDDC.Core;
|
||||
using ZB.MOM.WW.CBDDC.Core.Network;
|
||||
using ZB.MOM.WW.CBDDC.Core.Storage;
|
||||
using ZB.MOM.WW.CBDDC.Network.Security;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace ZB.MOM.WW.CBDDC.Network.Tests;
|
||||
|
||||
public class ConnectionTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Verifies that the server rejects new clients when the configured connection limit is reached.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Server_Should_Reject_Clients_When_Limit_Reached()
|
||||
{
|
||||
// Arrange
|
||||
var oplogStore = Substitute.For<IOplogStore>();
|
||||
oplogStore.GetLatestTimestampAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(new HlcTimestamp(0, 0, "node"));
|
||||
oplogStore.GetVectorClockAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(new VectorClock());
|
||||
oplogStore.GetOplogAfterAsync(Arg.Any<HlcTimestamp>(), Arg.Any<IEnumerable<string>?>(), Arg.Any<CancellationToken>())
|
||||
.Returns(Array.Empty<OplogEntry>());
|
||||
oplogStore.GetOplogForNodeAfterAsync(Arg.Any<string>(), Arg.Any<HlcTimestamp>(), Arg.Any<IEnumerable<string>?>(), Arg.Any<CancellationToken>())
|
||||
.Returns(Array.Empty<OplogEntry>());
|
||||
|
||||
var configProvider = Substitute.For<IPeerNodeConfigurationProvider>();
|
||||
configProvider.GetConfiguration().Returns(new PeerNodeConfiguration
|
||||
{
|
||||
NodeId = "server-node",
|
||||
AuthToken = "auth-token",
|
||||
TcpPort = 0
|
||||
});
|
||||
|
||||
var snapshotService = Substitute.For<ISnapshotService>();
|
||||
|
||||
var documentStore = Substitute.For<IDocumentStore>();
|
||||
documentStore.InterestedCollection.Returns(["Users", "TodoLists"]);
|
||||
|
||||
var authenticator = Substitute.For<IAuthenticator>();
|
||||
authenticator.ValidateAsync(Arg.Any<string>(), Arg.Any<string>()).Returns(true);
|
||||
|
||||
var handshakeService = Substitute.For<IPeerHandshakeService>();
|
||||
handshakeService.HandshakeAsync(Arg.Any<Stream>(), Arg.Any<bool>(), Arg.Any<string>(), Arg.Any<CancellationToken>())
|
||||
.Returns((CipherState?)null);
|
||||
|
||||
var server = new TcpSyncServer(
|
||||
oplogStore,
|
||||
documentStore,
|
||||
snapshotService,
|
||||
configProvider,
|
||||
NullLogger<TcpSyncServer>.Instance,
|
||||
authenticator,
|
||||
handshakeService);
|
||||
|
||||
server.MaxConnections = 2;
|
||||
|
||||
await server.Start();
|
||||
var port = server.ListeningPort ?? throw new Exception("Server not started");
|
||||
|
||||
using var client1 = new TcpClient();
|
||||
using var client2 = new TcpClient();
|
||||
using var client3 = new TcpClient();
|
||||
|
||||
try
|
||||
{
|
||||
// Act
|
||||
await client1.ConnectAsync("127.0.0.1", port);
|
||||
await client2.ConnectAsync("127.0.0.1", port);
|
||||
await Task.Delay(100);
|
||||
await client3.ConnectAsync("127.0.0.1", port);
|
||||
|
||||
// Assert
|
||||
var stream3 = client3.GetStream();
|
||||
var buffer = new byte[10];
|
||||
var read = await stream3.ReadAsync(buffer, 0, 10);
|
||||
read.ShouldBe(0, "Server should close connection immediately for client 3");
|
||||
|
||||
client1.Connected.ShouldBeTrue();
|
||||
client2.Connected.ShouldBeTrue();
|
||||
}
|
||||
finally
|
||||
{
|
||||
await server.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user