From: Forest Date: Sat, 31 Oct 2020 22:58:10 +0000 (-0700) Subject: Test UnityUdpClientConnection a little X-Git-Tag: 1.0.0~24 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=6956f32ad1950e3484cf40fc11a6257d50c08cee;p=rhonda%2Fimpostor.hazel.git Test UnityUdpClientConnection a little --- diff --git a/Hazel.UnitTests/Hazel.UnitTests.csproj b/Hazel.UnitTests/Hazel.UnitTests.csproj index e0d01fb..4b14efc 100644 --- a/Hazel.UnitTests/Hazel.UnitTests.csproj +++ b/Hazel.UnitTests/Hazel.UnitTests.csproj @@ -63,6 +63,7 @@ + diff --git a/Hazel.UnitTests/UnityUdpConnectionTests.cs b/Hazel.UnitTests/UnityUdpConnectionTests.cs new file mode 100644 index 0000000..5b84bbe --- /dev/null +++ b/Hazel.UnitTests/UnityUdpConnectionTests.cs @@ -0,0 +1,466 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Net; +using System.Threading; +using Hazel.Udp; +using System.Net.Sockets; + +namespace Hazel.UnitTests +{ + [TestClass] + public class UnityUdpConnectionTests + { + [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(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(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); + } + } + + /// + /// Tests the fields on UdpConnection. + /// + [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(ep)) + { + listener.Start(); + + connection.Connect(); + + //Connection fields + Assert.AreEqual(ep, connection.EndPoint); + + //UdpConnection fields + Assert.AreEqual(new IPEndPoint(IPAddress.Loopback, 4296), connection.RemoteEndPoint); + 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 (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + listener.Start(); + + MessageReader output = null; + listener.NewConnection += delegate (NewConnectionEventArgs e) + { + output = e.HandshakeData; + }; + + connection.Connect(TestData); + + Thread.Sleep(10); + 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(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()); + } + } + } + + /// + /// Tests IPv4 connectivity. + /// + [TestMethod] + public void UdpIPv4ConnectionTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + listener.Start(); + + connection.Connect(); + } + } + + /// + /// Tests dual mode connectivity. + /// + [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(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4296))) + { + connection.Connect(); + Assert.AreEqual(ConnectionState.Connected, connection.State); + } + + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.IPv6Loopback, 4296), IPMode.IPv6)) + { + connection.Connect(); + Assert.AreEqual(ConnectionState.Connected, connection.State); + } + } + } + + /// + /// Tests IPv4 resilience to non-hello connections. + /// + [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); + obj.HandshakeData.Recycle(); + }; + + 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); + } + } + + /// + /// Tests IPv4 resilience to multiple hellos. + /// + [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); + obj.HandshakeData.Recycle(); + }; + + 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); + } + } + + /// + /// Tests dual mode connectivity. + /// + [TestMethod] + public void UdpIPv6ConnectionTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.IPv6Any, 4296), IPMode.IPv6)) + { + listener.Start(); + + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4296), IPMode.IPv6)) + { + connection.Connect(); + } + } + } + + /// + /// Tests server to client unreliable communication on the UdpConnection. + /// + [TestMethod] + public void UdpUnreliableServerToClientTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + TestHelper.RunServerToClientTest(listener, connection, 10, SendOption.None); + } + } + + /// + /// Tests server to client reliable communication on the UdpConnection. + /// + [TestMethod] + public void UdpReliableServerToClientTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + TestHelper.RunServerToClientTest(listener, connection, 10, SendOption.Reliable); + } + } + + /// + /// Tests server to client unreliable communication on the UdpConnection. + /// + [TestMethod] + public void UdpUnreliableClientToServerTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + TestHelper.RunClientToServerTest(listener, connection, 10, SendOption.None); + } + } + + /// + /// Tests server to client reliable communication on the UdpConnection. + /// + [TestMethod] + public void UdpReliableClientToServerTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + TestHelper.RunClientToServerTest(listener, connection, 10, SendOption.Reliable); + } + } + + /// + /// Tests the keepalive functionality from the client, + /// + [TestMethod] + public void KeepAliveClientTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(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 + ); + } + } + + /// + /// Tests the keepalive functionality from the client, + /// + [TestMethod] + public void KeepAliveServerTest() + { + ManualResetEvent mutex = new ManualResetEvent(false); + + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(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 + ); + } + } + + /// + /// Tests disconnection from the client. + /// + [TestMethod] + public void ClientDisconnectTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + TestHelper.RunClientDisconnectTest(listener, connection); + } + } + + /// + /// Tests disconnection from the server. + /// + [TestMethod] + public void ServerDisconnectTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + TestHelper.RunServerDisconnectTest(listener, connection); + } + } + + /// + /// Tests disconnection from the server. + /// + [TestMethod] + public void ServerExtraDataDisconnectTest() + { + using (UdpConnectionListener listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, 4296))) + using (UdpConnection connection = new UnityUdpClientConnection(new IPEndPoint(IPAddress.Loopback, 4296))) + { + MessageReader received = null; + ManualResetEvent mutex = new ManualResetEvent(false); + + connection.Disconnected += delegate (object sender, DisconnectedEventArgs args) + { + received = args.Message; + mutex.Set(); + }; + + listener.NewConnection += delegate (NewConnectionEventArgs args) + { + 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.ReadString()); + } + } + } +} diff --git a/Hazel/Udp/UnityUdpClientConnection.cs b/Hazel/Udp/UnityUdpClientConnection.cs index fb5a57a..2a08859 100644 --- a/Hazel/Udp/UnityUdpClientConnection.cs +++ b/Hazel/Udp/UnityUdpClientConnection.cs @@ -80,7 +80,12 @@ namespace Hazel.Udp public override void Connect(byte[] bytes = null, int timeout = 5000) { - throw new NotImplementedException("Use ConnectAsync and check State != ConnectionState.Connecting instead."); + this.ConnectAsync(bytes); + for(int timer = 0; timer < timeout; timeout += 100) + { + if (this.State != ConnectionState.Connecting) return; + Thread.Sleep(100); + } } ///