136 lines
4.8 KiB
C#
136 lines
4.8 KiB
C#
using System.Net;
|
|
using System.Text;
|
|
using FinalFactory.Rendezvous.TestClient;
|
|
using LiteNetLib;
|
|
|
|
namespace FinalFactory.Rendezvous.Tests.TestClient;
|
|
|
|
public sealed class DirectEchoProtocolTests
|
|
{
|
|
[Fact]
|
|
public async Task HostReleasesPendingNonceWhenPeerDisconnectsBeforeAcknowledgement()
|
|
{
|
|
using CancellationTokenSource timeout = new(TimeSpan.FromSeconds(3));
|
|
EventBasedNetListener hostEvents = new();
|
|
EventBasedNetListener clientEvents = new();
|
|
hostEvents.ConnectionRequestEvent += request => request.Accept();
|
|
NetPeer? clientPeer = null;
|
|
clientEvents.PeerConnectedEvent += peer => clientPeer = peer;
|
|
NetManager hostManager = new(hostEvents);
|
|
NetManager clientManager = new(clientEvents);
|
|
try
|
|
{
|
|
Assert.True(hostManager.Start(0));
|
|
Assert.True(clientManager.Start(0));
|
|
clientManager.Connect(
|
|
new IPEndPoint(IPAddress.Loopback, hostManager.LocalPort),
|
|
"echo-test");
|
|
await PumpUntilAsync(
|
|
() => clientPeer is not null,
|
|
hostManager,
|
|
clientManager,
|
|
clientManager,
|
|
timeout.Token);
|
|
using DirectEchoProtocol host = new(hostEvents, host: true);
|
|
clientPeer!.Send(
|
|
Encoding.ASCII.GetBytes("rv1-ping:00112233445566778899aabbccddeeff"),
|
|
DeliveryMethod.ReliableOrdered);
|
|
await PumpUntilAsync(
|
|
() => host.PendingHostExchangeCount == 1,
|
|
hostManager,
|
|
clientManager,
|
|
clientManager,
|
|
timeout.Token);
|
|
|
|
clientPeer.Disconnect();
|
|
await PumpUntilAsync(
|
|
() => host.PendingHostExchangeCount == 0,
|
|
hostManager,
|
|
clientManager,
|
|
clientManager,
|
|
timeout.Token);
|
|
|
|
Assert.Equal(0, host.PendingHostExchangeCount);
|
|
}
|
|
finally
|
|
{
|
|
clientManager.Stop();
|
|
hostManager.Stop();
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task HostVerifiesOverlappingPeersAgainstTheirOwnNonces()
|
|
{
|
|
using CancellationTokenSource timeout = new(TimeSpan.FromSeconds(3));
|
|
EventBasedNetListener hostEvents = new();
|
|
EventBasedNetListener firstEvents = new();
|
|
EventBasedNetListener secondEvents = new();
|
|
hostEvents.ConnectionRequestEvent += request => request.Accept();
|
|
NetPeer? firstPeer = null;
|
|
NetPeer? secondPeer = null;
|
|
firstEvents.PeerConnectedEvent += peer => firstPeer = peer;
|
|
secondEvents.PeerConnectedEvent += peer => secondPeer = peer;
|
|
NetManager hostManager = new(hostEvents);
|
|
NetManager firstManager = new(firstEvents);
|
|
NetManager secondManager = new(secondEvents);
|
|
try
|
|
{
|
|
Assert.True(hostManager.Start(0));
|
|
Assert.True(firstManager.Start(0));
|
|
Assert.True(secondManager.Start(0));
|
|
IPEndPoint hostEndpoint = new(IPAddress.Loopback, hostManager.LocalPort);
|
|
firstManager.Connect(hostEndpoint, "echo-test");
|
|
secondManager.Connect(hostEndpoint, "echo-test");
|
|
await PumpUntilAsync(
|
|
() => firstPeer is not null && secondPeer is not null,
|
|
hostManager,
|
|
firstManager,
|
|
secondManager,
|
|
timeout.Token);
|
|
|
|
using DirectEchoProtocol host = new(hostEvents, host: true);
|
|
using DirectEchoProtocol first = new(firstEvents, host: false);
|
|
using DirectEchoProtocol second = new(secondEvents, host: false);
|
|
int hostCompletions = 0;
|
|
host.ExchangeCompleted += _ => hostCompletions++;
|
|
first.BeginJoin(firstPeer!);
|
|
second.BeginJoin(secondPeer!);
|
|
|
|
await PumpUntilAsync(
|
|
() => first.Completion.IsCompleted
|
|
&& second.Completion.IsCompleted
|
|
&& hostCompletions == 2,
|
|
hostManager,
|
|
firstManager,
|
|
secondManager,
|
|
timeout.Token);
|
|
|
|
Assert.Equal(2, hostCompletions);
|
|
}
|
|
finally
|
|
{
|
|
firstManager.Stop();
|
|
secondManager.Stop();
|
|
hostManager.Stop();
|
|
}
|
|
}
|
|
|
|
private static async Task PumpUntilAsync(
|
|
Func<bool> predicate,
|
|
NetManager host,
|
|
NetManager first,
|
|
NetManager second,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
while (!predicate())
|
|
{
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
host.PollEvents();
|
|
first.PollEvents();
|
|
second.PollEvents();
|
|
await Task.Delay(2, cancellationToken);
|
|
}
|
|
}
|
|
}
|