Replace timeout-polled in-world UDP receives with one cancellable caller-buffered socket operation. Transfer only right-sized pooled datagrams through the FIFO, return every ownership edge deterministically, and send caller spans without a transport copy while preserving handshake pacing and ACK order.
49 lines
1.3 KiB
C#
49 lines
1.3 KiB
C#
using System.Net;
|
|
|
|
namespace AcDream.Core.Net.Tests;
|
|
|
|
public sealed class WorldSessionConstructionTests
|
|
{
|
|
[Fact]
|
|
public void InvalidEndpointIsRejectedBeforeTransportAllocation()
|
|
{
|
|
int allocationCount = 0;
|
|
IWorldSessionTransport Allocate(IPEndPoint _)
|
|
{
|
|
allocationCount++;
|
|
return new TestTransport();
|
|
}
|
|
|
|
Assert.Throws<ArgumentNullException>(
|
|
() => new WorldSession(null!, Allocate));
|
|
Assert.Throws<ArgumentOutOfRangeException>(
|
|
() => new WorldSession(
|
|
new IPEndPoint(IPAddress.Loopback, ushort.MaxValue),
|
|
Allocate));
|
|
|
|
Assert.Equal(0, allocationCount);
|
|
}
|
|
|
|
private sealed class TestTransport : IWorldSessionTransport
|
|
{
|
|
public void Send(ReadOnlySpan<byte> datagram) { }
|
|
|
|
public void Send(IPEndPoint remote, ReadOnlySpan<byte> datagram) { }
|
|
|
|
public int Receive(
|
|
Span<byte> destination,
|
|
TimeSpan timeout,
|
|
out IPEndPoint? from)
|
|
{
|
|
from = null;
|
|
return -1;
|
|
}
|
|
|
|
public ValueTask<NetReceiveResult> ReceiveAsync(
|
|
Memory<byte> destination,
|
|
CancellationToken cancellationToken) =>
|
|
throw new OperationCanceledException(cancellationToken);
|
|
|
|
public void Dispose() { }
|
|
}
|
|
}
|