ProjectZ/Assets/Mirror/Tests/Editor/MessagePackingTest.cs
2024-02-19 21:00:36 +03:00

144 lines
4.3 KiB
C#

using System;
using Mirror.Tests.MessageTests;
using NUnit.Framework;
using UnityEngine;
namespace Mirror.Tests
{
[TestFixture]
public class MessagePackingTest
{
public struct EmptyMessage : NetworkMessage {}
// helper function to pack message into a simple byte[]
public static byte[] PackToByteArray<T>(T message)
where T : struct, NetworkMessage
{
using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
{
MessagePacking.Pack(message, writer);
return writer.ToArray();
}
}
// unpack a message we received
public static T UnpackFromByteArray<T>(byte[] data)
where T : struct, NetworkMessage
{
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(data))
{
int msgType = MessagePacking.GetId<T>();
int id = networkReader.ReadUShort();
if (id != msgType)
throw new FormatException($"Invalid message, could not unpack {typeof(T).FullName}");
return networkReader.Read<T>();
}
}
// message id is generated from message.FullName.
// should be consistent across all platforms.
[Test]
public void GetId()
{
// "Mirror.Tests.MessageTests.TestMessage"
Debug.Log(typeof(TestMessage).FullName);
Assert.That(MessagePacking.GetId<TestMessage>(), Is.EqualTo(0x8706));
}
[Test]
public void TestPacking()
{
TestMessage message = new TestMessage()
{
IntValue = 42,
StringValue = "Hello world"
};
byte[] data = PackToByteArray(message);
TestMessage unpacked = UnpackFromByteArray<TestMessage>(data);
Assert.That(unpacked.StringValue, Is.EqualTo("Hello world"));
Assert.That(unpacked.IntValue, Is.EqualTo(42));
}
[Test]
public void UnpackWrongMessage()
{
SpawnMessage message = new SpawnMessage();
byte[] data = PackToByteArray(message);
Assert.Throws<FormatException>(() =>
{
ReadyMessage unpacked = UnpackFromByteArray<ReadyMessage>(data);
});
}
[Test]
public void TestUnpackIdMismatch()
{
// Unpack<T> has a id != msgType case that throws a FormatException.
// let's try to trigger it.
TestMessage message = new TestMessage()
{
IntValue = 42,
StringValue = "Hello world"
};
byte[] data = PackToByteArray(message);
// overwrite the id
data[0] = 0x01;
data[1] = 0x02;
Assert.Throws<FormatException>(() =>
{
TestMessage unpacked = UnpackFromByteArray<TestMessage>(data);
});
}
[Test]
public void TestUnpackMessageNonGeneric()
{
// try a regular message
TestMessage message = new TestMessage()
{
IntValue = 42,
StringValue = "Hello world"
};
byte[] data = PackToByteArray(message);
NetworkReader reader = new NetworkReader(data);
bool result = MessagePacking.Unpack(reader, out ushort msgType);
Assert.That(result, Is.EqualTo(true));
Assert.That(msgType, Is.EqualTo(BitConverter.ToUInt16(data, 0)));
}
[Test]
public void UnpackInvalidMessage()
{
// try an invalid message
NetworkReader reader2 = new NetworkReader(new byte[0]);
bool result2 = MessagePacking.Unpack(reader2, out ushort msgType2);
Assert.That(result2, Is.EqualTo(false));
Assert.That(msgType2, Is.EqualTo(0));
}
[Test]
public void MessageIdIsCorrectLength()
{
NetworkWriter writer = new NetworkWriter();
MessagePacking.Pack(new EmptyMessage(), writer);
ArraySegment<byte> segment = writer.ToArraySegment();
Assert.That(segment.Count, Is.EqualTo(MessagePacking.HeaderSize), "Empty message should have same size as HeaderSize");
}
}
}