// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.Network.Tests; using System.Net; using System.Net.Sockets; using System.Threading; using Microsoft.Extensions.Logging.Abstractions; using Pipelines.Sockets.Unofficial; /// /// Test of the async connection implementation. /// [TestFixture] [Ignore("It's using real sockets")] public class SocketConnectionTest { /// /// Tests the receive function with a pipelined connection object. /// [Test] public void TestReceivePipelined() { this.TestReceivePipelined(socket => new Connection(SocketConnection.Create(socket), null, null, new NullLogger())); } /// /// Tests the receive function with a pipelined connection object with encryptor/decryptor. /// [Test] public void TestReceivePipelinedWithEncryption() { this.TestReceivePipelined(socket => { var socketConnection = SocketConnection.Create(socket); return new Connection(socketConnection, new PipelinedDecryptor(socketConnection.Input), new PipelinedEncryptor(socketConnection.Output), new NullLogger()); }); } /// /// Tests if the connection is disconnected after sending invalid data. /// [Test] public async Task TestDisconnectOnInvalidHeaderSentAsync() { IConnection? connection = null; var server = new TcpListener(IPAddress.Any, 5000); server.Start(); try { server.BeginAcceptSocket( asyncResult => { var clientSocket = server.EndAcceptSocket(asyncResult); var socketConnection = SocketConnection.Create(clientSocket); connection = new Connection(socketConnection, new PipelinedDecryptor(socketConnection.Input), new PipelinedEncryptor(socketConnection.Output), new NullLogger()); }, null); using var client = new TcpClient("127.0.0.1", 5000); while (connection == null) { Thread.Sleep(10); } #pragma warning disable 4014 connection.BeginReceiveAsync(); #pragma warning restore 4014 var packet = new byte[22222]; packet[0] = 0xDE; packet[1] = 0xAD; packet[2] = 0xBE; packet[3] = 0xAF; await connection.Output.WriteAsync(packet).ConfigureAwait(false); await Task.Delay(1000).ConfigureAwait(false); Assert.That(connection.Connected, Is.False); } finally { server.Stop(); } } /// /// Tests if the connection is disconnected after receiving invalid data. /// [Test] public void TestDisconnectOnInvalidHeaderReceived() { var server = new TcpListener(IPAddress.Any, 5000); server.Start(); try { server.BeginAcceptSocket( asyncResult => { var clientSocket = server.EndAcceptSocket(asyncResult); var packet = new byte[] { 0xDE, 0xAD, 0xBE, 0xEF, 0, 0, 0, 0, 0, 0 }; clientSocket.BeginSend(packet, 0, packet.Length, SocketFlags.None, null, null); }, null); using var client = new TcpClient("127.0.0.1", 5000); var socketConnection = SocketConnection.Create(client.Client); var connection = new Connection(socketConnection, new PipelinedDecryptor(socketConnection.Input), new PipelinedEncryptor(socketConnection.Output), new NullLogger()); _ = connection.BeginReceiveAsync(); Thread.Sleep(100); Assert.That(connection.Connected, Is.False); } finally { server.Stop(); } } /// /// Tests the receiving of data with any implementation. /// /// The connection creator. private void TestReceivePipelined(Func connectionCreator) { const int maximumPacketCount = 1000; IConnection? connection = null; var server = new TcpListener(IPAddress.Any, 5000); server.Start(); server.BeginAcceptSocket( asyncResult => { var clientSocket = server.EndAcceptSocket(asyncResult); connection = connectionCreator(clientSocket); }, null); using (var client = new TcpClient("127.0.0.1", 5000)) { while (connection == null) { Thread.Sleep(10); } int packetCount = 0; connection.PacketReceived += async p => Interlocked.Increment(ref packetCount); _ = connection.BeginReceiveAsync(); var packet = new byte[] { 0xC1, 10, 0, 0, 0, 0, 0, 0, 0, 0 }; for (int i = 0; i < maximumPacketCount; i++) { client.Client.BeginSend(packet, 0, packet.Length, SocketFlags.None, null, null); } while (packetCount < maximumPacketCount) { Thread.Sleep(1); } } server.Stop(); } }