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 HandshakeRegressionTests { /// /// Verifies that the server invokes the handshake service when a client connects. /// [Fact] public async Task Server_Should_Call_HandshakeService_On_Client_Connection() { // Arrange var oplogStore = Substitute.For(); oplogStore.GetLatestTimestampAsync(Arg.Any()) .Returns(new HlcTimestamp(0, 0, "node")); oplogStore.GetVectorClockAsync(Arg.Any()) .Returns(new VectorClock()); oplogStore.GetOplogAfterAsync(Arg.Any(), Arg.Any?>(), Arg.Any()) .Returns(Array.Empty()); oplogStore.GetOplogForNodeAfterAsync(Arg.Any(), Arg.Any(), Arg.Any?>(), Arg.Any()) .Returns(Array.Empty()); var configProvider = Substitute.For(); configProvider.GetConfiguration().Returns(new PeerNodeConfiguration { NodeId = "server-node", AuthToken = "auth-token", TcpPort = 0 }); var snapshotService = Substitute.For(); var documentStore = Substitute.For(); documentStore.InterestedCollection.Returns(["Users"]); var authenticator = Substitute.For(); authenticator.ValidateAsync(Arg.Any(), Arg.Any()).Returns(true); var handshakeService = Substitute.For(); handshakeService.HandshakeAsync(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns((CipherState?)null); var server = new TcpSyncServer( oplogStore, documentStore, snapshotService, configProvider, NullLogger.Instance, authenticator, handshakeService); await server.Start(); var port = server.ListeningPort ?? throw new Exception("Server did not start or report port"); // Act using (var client = new TcpClient()) { await client.ConnectAsync("127.0.0.1", port); await Task.Delay(500); } await server.Stop(); // Assert await handshakeService.Received(1) .HandshakeAsync(Arg.Any(), false, "server-node", Arg.Any()); } }