aboutsummaryrefslogtreecommitdiff
path: root/Tools/Hazel-Networking/Hazel.UnitTests/UnityUdpConnectionTests.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Hazel-Networking/Hazel.UnitTests/UnityUdpConnectionTests.cs')
-rw-r--r--Tools/Hazel-Networking/Hazel.UnitTests/UnityUdpConnectionTests.cs489
1 files changed, 489 insertions, 0 deletions
diff --git a/Tools/Hazel-Networking/Hazel.UnitTests/UnityUdpConnectionTests.cs b/Tools/Hazel-Networking/Hazel.UnitTests/UnityUdpConnectionTests.cs
new file mode 100644
index 0000000..0745578
--- /dev/null
+++ b/Tools/Hazel-Networking/Hazel.UnitTests/UnityUdpConnectionTests.cs
@@ -0,0 +1,489 @@
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Net;
+using System.Threading;
+using Hazel.Udp;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+
+namespace Hazel.UnitTests
+{
+ [TestClass]
+ public class UnityUdpConnectionTests
+ {
+ private ILogger logger = new ConsoleLogger(true);
+
+ [TestMethod]
+ public void ServerDisposeDisconnectsTest()
+ {
+ IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 4296);
+
+ bool serverConnected = false;
+ bool serverDisconnected = false;
+ bool clientDisconnected = false;
+
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, ep))
+ {
+ listener.NewConnection += (evt) =>
+ {
+ serverConnected = true;
+ evt.Connection.Disconnected += (o, et) => serverDisconnected = true;
+ };
+ connection.Disconnected += (o, evt) => clientDisconnected = true;
+
+ listener.Start();
+ connection.Connect();
+
+ Thread.Sleep(100); // Gotta wait for the server to set up the events.
+ listener.Dispose();
+ Thread.Sleep(100);
+
+ Assert.IsTrue(serverConnected);
+ Assert.IsTrue(clientDisconnected);
+ Assert.IsFalse(serverDisconnected);
+ }
+ }
+
+ [TestMethod]
+ public void ClientServerDisposeDisconnectsTest()
+ {
+ IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 4296);
+
+ bool serverConnected = false;
+ bool serverDisconnected = false;
+ bool clientDisconnected = false;
+
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, ep))
+ {
+ listener.NewConnection += (evt) =>
+ {
+ serverConnected = true;
+ evt.Connection.Disconnected += (o, et) => serverDisconnected = true;
+ };
+
+ connection.Disconnected += (o, et) => clientDisconnected = true;
+
+ listener.Start();
+ connection.Connect();
+
+ Thread.Sleep(100); // Gotta wait for the server to set up the events.
+ connection.Dispose();
+
+ Thread.Sleep(100);
+
+ Assert.IsTrue(serverConnected);
+ Assert.IsTrue(serverDisconnected);
+ Assert.IsFalse(clientDisconnected);
+ }
+ }
+
+ /// <summary>
+ /// Tests the fields on UdpConnection.
+ /// </summary>
+ [TestMethod]
+ public void UdpFieldTest()
+ {
+ IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 4296);
+
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, ep))
+ {
+ listener.Start();
+
+ connection.Connect();
+
+ //Connection fields
+ Assert.AreEqual(ep, connection.EndPoint);
+
+ //UdpConnection fields
+ Assert.AreEqual(new IPEndPoint(IPAddress.Loopback, 4296), connection.EndPoint);
+ Assert.AreEqual(1, connection.Statistics.DataBytesSent);
+ Assert.AreEqual(0, connection.Statistics.DataBytesReceived);
+ }
+ }
+
+ [TestMethod]
+ public void UdpHandshakeTest()
+ {
+ byte[] TestData = new byte[] { 1, 2, 3, 4, 5, 6 };
+
+ using (ManualResetEventSlim mutex = new ManualResetEventSlim(false))
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ listener.Start();
+
+ MessageReader output = null;
+ listener.NewConnection += delegate (NewConnectionEventArgs e)
+ {
+ output = e.HandshakeData.Duplicate();
+ mutex.Set();
+ };
+
+ connection.Connect(TestData);
+ mutex.Wait(5000);
+
+ for (int i = 0; i < TestData.Length; ++i)
+ {
+ Assert.AreEqual(TestData[i], output.ReadByte());
+ }
+ }
+ }
+
+ [TestMethod]
+ public void UdpUnreliableMessageSendTest()
+ {
+ byte[] TestData = new byte[] { 1, 2, 3, 4, 5, 6 };
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ MessageReader output = null;
+ listener.NewConnection += delegate (NewConnectionEventArgs e)
+ {
+ e.Connection.DataReceived += delegate (DataReceivedEventArgs evt)
+ {
+ output = evt.Message;
+ };
+ };
+
+ listener.Start();
+ connection.Connect();
+
+ for (int i = 0; i < 4; ++i)
+ {
+ var msg = MessageWriter.Get(SendOption.None);
+ msg.Write(TestData);
+ connection.Send(msg);
+ msg.Recycle();
+ }
+
+ Thread.Sleep(10);
+ for (int i = 0; i < TestData.Length; ++i)
+ {
+ Assert.AreEqual(TestData[i], output.ReadByte());
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tests IPv4 connectivity.
+ /// </summary>
+ [TestMethod]
+ public void UdpIPv4ConnectionTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ listener.Start();
+
+ connection.Connect();
+ }
+ }
+
+ /// <summary>
+ /// Tests dual mode connectivity.
+ /// </summary>
+ [TestMethod]
+ public void MixedConnectionTest()
+ {
+ using (UdpConnectionListener listener2 = new UdpConnectionListener(new IPEndPoint(IPAddress.IPv6Any, 4296), IPMode.IPv6))
+ {
+ listener2.Start();
+
+ listener2.NewConnection += (evt) =>
+ {
+ Console.WriteLine("v6 connection: " + ((NetworkConnection)evt.Connection).GetIP4Address());
+ };
+
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4296)))
+ {
+ connection.Connect();
+ Assert.AreEqual(ConnectionState.Connected, connection.State);
+ }
+
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.IPv6Loopback, 4296), IPMode.IPv6))
+ {
+ connection.Connect();
+ Assert.AreEqual(ConnectionState.Connected, connection.State);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tests IPv4 resilience to non-hello connections.
+ /// </summary>
+ [TestMethod]
+ public void FalseConnectionTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
+ {
+ int connects = 0;
+ listener.NewConnection += (obj) =>
+ {
+ Interlocked.Increment(ref connects);
+ };
+
+ listener.Start();
+
+ socket.Bind(new IPEndPoint(IPAddress.Any, 0));
+ var bytes = new byte[2];
+ bytes[0] = (byte)32;
+ for (int i = 0; i < 10; ++i)
+ {
+ socket.SendTo(bytes, new IPEndPoint(IPAddress.Loopback, 4296));
+ }
+
+ Thread.Sleep(500);
+
+ Assert.AreEqual(0, connects);
+ }
+ }
+
+ /// <summary>
+ /// Tests IPv4 resilience to multiple hellos.
+ /// </summary>
+ [TestMethod]
+ public void ConnectLikeAJerkTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
+ {
+ int connects = 0;
+ listener.NewConnection += (obj) =>
+ {
+ Interlocked.Increment(ref connects);
+ };
+
+ listener.Start();
+
+ socket.Bind(new IPEndPoint(IPAddress.Any, 0));
+ var bytes = new byte[2];
+ bytes[0] = (byte)UdpSendOption.Hello;
+ for (int i = 0; i < 10; ++i)
+ {
+ socket.SendTo(bytes, new IPEndPoint(IPAddress.Loopback, 4296));
+ }
+
+ Thread.Sleep(500);
+
+ Assert.AreEqual(1, connects);
+ }
+ }
+
+ /// <summary>
+ /// Tests dual mode connectivity.
+ /// </summary>
+ [TestMethod]
+ public void UdpIPv6ConnectionTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.IPv6Any, 4296), IPMode.IPv6))
+ {
+ listener.Start();
+
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4296), IPMode.IPv6))
+ {
+ connection.Connect();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tests server to client unreliable communication on the UdpConnection.
+ /// </summary>
+ [TestMethod]
+ public void UdpUnreliableServerToClientTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ TestHelper.RunServerToClientTest(listener, connection, 10, SendOption.None);
+ }
+ }
+
+ /// <summary>
+ /// Tests server to client reliable communication on the UdpConnection.
+ /// </summary>
+ [TestMethod]
+ public void UdpReliableServerToClientTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ TestHelper.RunServerToClientTest(listener, connection, 10, SendOption.Reliable);
+ }
+ }
+
+ /// <summary>
+ /// Tests server to client unreliable communication on the UdpConnection.
+ /// </summary>
+ [TestMethod]
+ public void UdpUnreliableClientToServerTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ TestHelper.RunClientToServerTest(listener, connection, 10, SendOption.None);
+ }
+ }
+
+ /// <summary>
+ /// Tests server to client reliable communication on the UdpConnection.
+ /// </summary>
+ [TestMethod]
+ public void UdpReliableClientToServerTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ TestHelper.RunClientToServerTest(listener, connection, 10, SendOption.Reliable);
+ }
+ }
+
+ /// <summary>
+ /// Tests the keepalive functionality from the client,
+ /// </summary>
+ [TestMethod]
+ public void KeepAliveClientTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ listener.Start();
+
+ connection.Connect();
+ connection.KeepAliveInterval = 100;
+
+ Thread.Sleep(1050); //Enough time for ~10 keep alive packets
+
+ Assert.AreEqual(ConnectionState.Connected, connection.State);
+ Assert.IsTrue(
+ connection.Statistics.TotalBytesSent >= 30 &&
+ connection.Statistics.TotalBytesSent <= 50,
+ "Sent: " + connection.Statistics.TotalBytesSent
+ );
+ }
+ }
+
+ /// <summary>
+ /// Tests the keepalive functionality from the client,
+ /// </summary>
+ [TestMethod]
+ public void KeepAliveServerTest()
+ {
+ ManualResetEvent mutex = new ManualResetEvent(false);
+
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ UdpConnection client = null;
+ listener.NewConnection += delegate (NewConnectionEventArgs args)
+ {
+ client = (UdpConnection)args.Connection;
+ client.KeepAliveInterval = 100;
+
+ Thread.Sleep(1050); //Enough time for ~10 keep alive packets
+
+ mutex.Set();
+ };
+
+ listener.Start();
+
+ connection.Connect();
+
+ mutex.WaitOne();
+
+ Assert.AreEqual(ConnectionState.Connected, client.State);
+
+ Assert.IsTrue(
+ client.Statistics.TotalBytesSent >= 27 &&
+ client.Statistics.TotalBytesSent <= 50,
+ "Sent: " + client.Statistics.TotalBytesSent
+ );
+ }
+ }
+
+ /// <summary>
+ /// Tests disconnection from the client.
+ /// </summary>
+ [TestMethod]
+ public void ClientDisconnectTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ TestHelper.RunClientDisconnectTest(listener, connection);
+ }
+ }
+
+ /// <summary>
+ /// Test that a disconnect is sent when the client is disposed.
+ /// </summary>
+ public void ClientDisconnectOnDisposeTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ TestHelper.RunClientDisconnectOnDisposeTest(listener, connection);
+ }
+ }
+
+ /// <summary>
+ /// Tests disconnection from the server.
+ /// </summary>
+ [TestMethod]
+ public void ServerDisconnectTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ TestHelper.RunServerDisconnectTest(listener, connection);
+ }
+ }
+
+ /// <summary>
+ /// Tests disconnection from the server.
+ /// </summary>
+ [TestMethod]
+ public void ServerExtraDataDisconnectTest()
+ {
+ using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296)))
+ using (UdpConnection connection = new UnityUdpClientConnection(logger, new IPEndPoint(IPAddress.Loopback, 4296)))
+ {
+ string received = null;
+ ManualResetEvent mutex = new ManualResetEvent(false);
+
+ connection.Disconnected += delegate (object sender, DisconnectedEventArgs args)
+ {
+ // We don't own the message, we have to read the string now
+ received = args.Message.ReadString();
+ mutex.Set();
+ };
+
+ listener.NewConnection += delegate (NewConnectionEventArgs args)
+ {
+ // As it turns out, the UdpConnectionListener can have an issue on loopback where the disconnect can happen before the hello confirm
+ // Tossing it on a different thread makes this test more reliable. Perhaps something to think about elsewhere though.
+ Task.Run(async () =>
+ {
+ await Task.Delay(1);
+ MessageWriter writer = MessageWriter.Get(SendOption.None);
+ writer.Write("Goodbye");
+ args.Connection.Disconnect("Testing", writer);
+ });
+ };
+
+ listener.Start();
+
+ connection.Connect();
+
+ mutex.WaitOne();
+
+ Assert.IsNotNull(received);
+ Assert.AreEqual("Goodbye", received);
+ }
+ }
+ }
+}