Closes #4
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
using FinalFactory.Rendezvous.Contracts;
|
||||
|
||||
namespace FinalFactory.Rendezvous.Tests.Contracts;
|
||||
|
||||
public sealed class UdpCodecTests
|
||||
{
|
||||
private static readonly Guid Handle = new("00112233-4455-6677-8899-aabbccddeeff");
|
||||
|
||||
[Fact]
|
||||
public void HostPresenceMatchesTheV1GoldenVector()
|
||||
{
|
||||
byte[] encoded = RendezvousUdpCodec.Encode(CreateDatagram());
|
||||
|
||||
Assert.Equal(ContractTestFiles.Read("udp-host-ipv4.hex"), Convert.ToHexString(encoded).ToLowerInvariant());
|
||||
Assert.True(RendezvousUdpCodec.TryDecode(encoded, out PresenceDatagram? decoded, out UdpDecodeError error));
|
||||
Assert.Equal(UdpDecodeError.None, error);
|
||||
Assert.NotNull(decoded);
|
||||
Assert.Equal(Handle, decoded.MediationHandle.Value);
|
||||
Assert.Equal("192.0.2.10", decoded.LocalAddress);
|
||||
Assert.Equal(9050, decoded.LocalPort);
|
||||
Assert.Equal("Abc_123-xYz", decoded.Capability);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Ipv6RoundtripsWithoutLosingItsAddressFamily()
|
||||
{
|
||||
PresenceDatagram original = CreateDatagram();
|
||||
original.MessageType = UdpPresenceMessageType.ClientPresence;
|
||||
original.AddressFamily = AddressFamilyKind.Ipv6;
|
||||
original.LocalAddress = "2001:db8::10";
|
||||
|
||||
byte[] encoded = RendezvousUdpCodec.Encode(original);
|
||||
|
||||
Assert.True(RendezvousUdpCodec.TryDecode(encoded, out PresenceDatagram? decoded, out _));
|
||||
Assert.NotNull(decoded);
|
||||
Assert.Equal(AddressFamilyKind.Ipv6, decoded.AddressFamily);
|
||||
Assert.Equal("2001:db8::10", decoded.LocalAddress);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EncoderRejectsAnAddressFamilyMismatch()
|
||||
{
|
||||
PresenceDatagram datagram = CreateDatagram();
|
||||
datagram.AddressFamily = AddressFamilyKind.Ipv4;
|
||||
datagram.LocalAddress = "2001:db8::10";
|
||||
|
||||
Assert.Throws<ArgumentException>(() => RendezvousUdpCodec.Encode(datagram));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(2, 2, UdpDecodeError.UnsupportedVersion)]
|
||||
[InlineData(3, 3, UdpDecodeError.UnknownMessageType)]
|
||||
[InlineData(4, 1, UdpDecodeError.InvalidFlags)]
|
||||
[InlineData(21, 5, UdpDecodeError.InvalidAddressFamily)]
|
||||
public void DecoderReturnsStableErrorsForUnknownHeaderValues(
|
||||
int offset,
|
||||
byte replacement,
|
||||
UdpDecodeError expected)
|
||||
{
|
||||
byte[] encoded = RendezvousUdpCodec.Encode(CreateDatagram());
|
||||
encoded[offset] = replacement;
|
||||
|
||||
Assert.False(RendezvousUdpCodec.TryDecode(encoded, out _, out UdpDecodeError actual));
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DecoderRejectsTruncationTrailingDataAndOversizedPackets()
|
||||
{
|
||||
byte[] encoded = RendezvousUdpCodec.Encode(CreateDatagram());
|
||||
byte[] trailing = [.. encoded, 0];
|
||||
byte[] oversized = new byte[ContractLimits.UdpDatagramMaxBytes + 1];
|
||||
|
||||
Assert.False(RendezvousUdpCodec.TryDecode(encoded.AsSpan(0, encoded.Length - 1), out _, out UdpDecodeError truncated));
|
||||
Assert.Equal(UdpDecodeError.Truncated, truncated);
|
||||
Assert.False(RendezvousUdpCodec.TryDecode(trailing, out _, out UdpDecodeError trailingError));
|
||||
Assert.Equal(UdpDecodeError.TrailingData, trailingError);
|
||||
Assert.False(RendezvousUdpCodec.TryDecode(oversized, out _, out UdpDecodeError oversizedError));
|
||||
Assert.Equal(UdpDecodeError.DatagramTooLarge, oversizedError);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DecoderRejectsNonBase64UrlCapabilities()
|
||||
{
|
||||
byte[] encoded = RendezvousUdpCodec.Encode(CreateDatagram());
|
||||
encoded[^1] = (byte)'+';
|
||||
|
||||
Assert.False(RendezvousUdpCodec.TryDecode(encoded, out _, out UdpDecodeError error));
|
||||
Assert.Equal(UdpDecodeError.InvalidCapability, error);
|
||||
}
|
||||
|
||||
private static PresenceDatagram CreateDatagram() => new()
|
||||
{
|
||||
MessageType = UdpPresenceMessageType.HostPresence,
|
||||
MediationHandle = new MediationHandle(Handle),
|
||||
AddressFamily = AddressFamilyKind.Ipv4,
|
||||
LocalAddress = "192.0.2.10",
|
||||
LocalPort = 9050,
|
||||
Capability = "Abc_123-xYz",
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user