public IEnumerator SendOne() { Task <RunNode.Result> task = RunNode.RunAsync("ReceiveMessages.js"); yield return(server.WaitForConnection); byte[] bytes = new byte[] { 1, 2, 3, 4, 5 }; var segment = new ArraySegment <byte>(bytes); server.ServerSend(new List <int> { 1 }, Channels.DefaultReliable, segment); yield return(new WaitForSeconds(0.5f)); server.ServerDisconnect(1); yield return(new WaitUntil(() => task.IsCompleted)); RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetOutput( "length: 5 msg: 01 02 03 04 05" ); result.AssetErrors(); }
public IEnumerator ManyConnect(int count) { int connectIndex = 1; server.OnServerConnected = ((connId) => { Assert.That(connId, Is.EqualTo(connectIndex), "Clients should be connected in order with the next index"); connectIndex++; }); Task <RunNode.Result> task = RunNode.RunAsync("ConnectAndCloseMany.js", arg0: count.ToString(), msTimeout: 10000); // 10 seconds should be enough time for clients to connect then close themselves yield return(new WaitForSeconds(10)); Assert.That(server.onConnect, Has.Count.EqualTo(count), "All should be connectted"); Assert.That(server.onDisconnect, Has.Count.EqualTo(count), "All should be disconnected called"); Assert.That(server.onData, Has.Count.EqualTo(0), "Data should not be called"); Assert.That(task.IsCompleted, Is.True, "Take should have been completed"); RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetErrors(); var expected = new List <string>(); for (int i = 0; i < count; i++) { expected.Add($"{i}: Connection opened"); expected.Add($"{i}: Closed after 2000ms"); } result.AssetOutputUnordered(expected.ToArray()); }
public IEnumerator SendDifferentSizes(int msgSize) { Task <RunNode.Result> task = RunNode.RunAsync("ReceiveMessages.js"); yield return(server.WaitForConnection); byte[] bytes = Enumerable.Range(1, msgSize).Select(x => (byte)x).ToArray(); var segment = new ArraySegment <byte>(bytes); server.ServerSend(new List <int> { 1 }, Channels.DefaultReliable, segment); yield return(new WaitForSeconds(0.5f)); server.ServerDisconnect(1); yield return(new WaitUntil(() => task.IsCompleted)); RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetOutput( $"length: {msgSize} msg: {BitConverter.ToString(bytes).Replace('-', ' ')}" ); result.AssetErrors(); }
public IEnumerator ReceiveAlmostLargeArrays() { // dont worry about result, run will timeout by itself _ = RunNode.RunAsync("SendAlmostLargeMessages.js"); yield return(server.WaitForConnection); // wait for message yield return(new WaitForSeconds(0.5f)); const int messageSize = 10000; Assert.That(server.onData, Has.Count.EqualTo(1), $"Should have 1 message"); (int connId, byte[] data) = server.onData[0]; Assert.That(connId, Is.EqualTo(1), "Connd id should be 1"); Assert.That(data.Length, Is.EqualTo(messageSize), "Should have 16384 bytes"); for (int i = 0; i < messageSize; i++) { // js sends i%255 for each byte Assert.That(data[i], Is.EqualTo(i % 255), "Data should match"); } }
public IEnumerator ReceiveManyArrays() { // dont worry about result, run will timeout by itself _ = RunNode.RunAsync("SendManyMessages.js"); yield return(server.WaitForConnection); // wait for message yield return(new WaitForSeconds(0.5f)); const int expectedCount = 100; const int messageSize = 10; Assert.That(server.onData, Has.Count.EqualTo(expectedCount), $"Should have {expectedCount} message"); for (int i = 0; i < expectedCount; i++) { (int connId, byte[] data) = server.onData[i]; Assert.That(connId, Is.EqualTo(1), "Connd id should be 1"); Assert.That(data.Length, Is.EqualTo(messageSize), "Should have 10 bytes"); Assert.That(data[0], Is.EqualTo(i), "Data should match: first bytes should be send index"); for (int j = 1; j < messageSize; j++) { // js sends i+10 for each byte Assert.That(data[j], Is.EqualTo(j + 10), "Data should match"); } } }
public IEnumerator SendLarge() { server.maxMessageSize = 100_000; server.ServerStart(); Task <RunNode.Result> task = RunNode.RunAsync("ReceiveMessages.js"); yield return(server.WaitForConnection); byte[] bytes = new byte[80_000];
public IEnumerator MultipleGoodAndBadClients() { int connectIndex = 1; #if MIRROR_29_0_OR_NEWER server.OnServerConnected = #else server.OnServerConnected.AddListener #endif ((connId) => { Assert.That(connId == connectIndex, "Clients should be connected in order with the next index"); connectIndex++; }); const int clientCount = 10; for (int i = 0; i < clientCount; i++) { ExpectHandshakeFailedError(); // alternate between good and bad clients Task <TcpClient> createTask = CreateBadClient(); while (!createTask.IsCompleted) { yield return(null); } TcpClient client = createTask.Result; Assert.That(client.Connected, Is.True, "Client should have connected"); badClients.Add(client); } Task <RunNode.Result> task = RunNode.RunAsync("ConnectAndCloseMany.js", arg0: clientCount.ToString()); // wait for timeout + extra so bad clients disconnect yield return(new WaitForSeconds(2 * timeout / 1000)); Assert.That(server.onConnect, Has.Count.EqualTo(clientCount), "Connect should not be called"); Assert.That(server.onDisconnect, Has.Count.EqualTo(clientCount), "Disconnect should not be called"); Assert.That(server.onData, Has.Count.EqualTo(0), "Data should not be called"); Assert.That(task.IsCompleted, Is.True, "Take should have been completed"); RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetErrors(); List <string> expected = new List <string>(); for (int i = 0; i < clientCount; i++) { expected.Add($"{i}: Connection opened"); expected.Add($"{i}: Closed after 2000ms"); } result.AssetOutputUnordered(expected.ToArray()); }
public IEnumerator CanKickConnection() { Task <RunNode.Result> task = RunNode.RunAsync("Disconnect.js"); yield return(server.WaitForConnection); server.ServerDisconnect(1); yield return(new WaitUntil(() => task.IsCompleted)); RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetOutput( "Connection closed" ); result.AssetErrors(); }
public IEnumerator ReceiveManyLargeArrays() { // dont worry about result, run will timeout by itself Task <RunNode.Result> task = RunNode.RunAsync("SendManyLargeMessages.js", 10000); yield return(server.WaitForConnection); // wait for messages yield return(new WaitForSeconds(5f)); const int expectedCount = 100; const int messageSize = 16384; yield return(new WaitUntil(() => task.IsCompleted)); RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetOutput(); result.AssetErrors(); Assert.That(server.onData, Has.Count.EqualTo(expectedCount), $"Should have {expectedCount} message"); // expected after index 1 // index 0 is the message index int[] expected = new int[messageSize - 1]; for (int i = 1; i < messageSize; i++) { expected[i - 1] = i % 255; } for (int i = 0; i < expectedCount; i++) { (int connId, byte[] data) = server.onData[i]; Assert.That(connId, Is.EqualTo(1), "Connd id should be 1"); Assert.That(data.Length, Is.EqualTo(messageSize), "Should have 10 bytes"); Assert.That(data[0], Is.EqualTo(i), "Data should match: first bytes should be send index"); CollectionAssert.AreEqual(expected, new ArraySegment <byte>(data, 1, data.Length - 1), "Data should match"); } }
public IEnumerator OtherClientsCanConnectWhileWaitingForBadClient() { ExpectHandshakeFailedError(); // connect bad client Task <TcpClient> createTask = CreateBadClient(); while (!createTask.IsCompleted) { yield return(null); } tcpClient = createTask.Result; Assert.That(tcpClient.Connected, Is.True, "Client should have connected"); // connect good client Task <RunNode.Result> task = RunNode.RunAsync("ConnectAndClose.js"); while (!task.IsCompleted) { yield return(null); } // check good client connected and then closed by itself RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetOutput( "Connection opened", "Closed after 2000ms" ); result.AssetErrors(); // check server events Assert.That(server.onConnect, Has.Count.EqualTo(1), "Connect should have been called once"); Assert.That(server.onDisconnect, Has.Count.EqualTo(1), "Disconnect should have been called once"); Assert.That(server.onData, Has.Count.EqualTo(0), "Data should not be called"); // wait for timeout yield return(new WaitForSeconds(timeout / 1000)); Assert.That(HasDisconnected(tcpClient), Is.True, "Client should have been disconnected"); }
public IEnumerator ShouldTimeoutClientAfterNoMessage() { // make sure doesn't timeout Task <RunNode.Result> task = RunNode.RunAsync("Connect.js", timeout * 10); // wait for timeout yield return(new WaitForSeconds(2 * timeout / 1000)); Assert.That(server.onConnect, Has.Count.EqualTo(1), "Connect should be called once"); Assert.That(server.onDisconnect, Has.Count.EqualTo(1), "Disconnected should be called once"); Assert.That(task.IsCompleted, Is.True, "Connect.js should have stopped after connection was closed by timeout"); RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetOutput( "Connection opened", $"Connection closed" ); result.AssetErrors(); }
public IEnumerator ReceiveTooLargeArrays() { ExpectInvalidDataError(); // dont worry about result, run will timeout by itself _ = RunNode.RunAsync("SendTooLargeMessages.js"); yield return(server.WaitForConnection); // wait for message yield return(new WaitForSeconds(2f)); Assert.That(server.onData, Has.Count.EqualTo(0), $"Should have 0 message"); Assert.That(server.onDisconnect, Has.Count.EqualTo(1), $"Should have 1 disconnect"); Assert.That(server.onDisconnect[0], Is.EqualTo(1), $"connId should be 1"); Assert.That(server.onError, Has.Count.EqualTo(1), $"Should have 1 error, Errors:\n{WriteErrors(server.onError)}"); Assert.That(server.onError[0].connId, Is.EqualTo(1), $"connId should be 1"); Assert.That(server.onError[0].exception, Is.TypeOf <InvalidDataException>(), $"Should be InvalidDataException"); }
public IEnumerator ClientCanConnectOverWss() { Task <RunNode.Result> task = RunNode.RunAsync("WssConnectAndClose.js"); while (!task.IsCompleted) { yield return(null); } RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetOutput( "Connection opened", "Closed after 2000ms" ); result.AssetErrors(); // wait for message to be processed yield return(new WaitForSeconds(0.2f)); Assert.That(server.onConnect, Has.Count.EqualTo(1), "Connect should be called once"); }
public IEnumerator SendMany() { Task <RunNode.Result> task = RunNode.RunAsync("ReceiveManyMessages.js", 5_000); yield return(server.WaitForConnection); const int messageCount = 100; for (int i = 0; i < messageCount; i++) { using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter()) { writer.WriteByte((byte)i); writer.WriteInt32(100); ArraySegment <byte> segment = writer.ToArraySegment(); server.ServerSend(new List <int> { 1 }, Channels.DefaultReliable, segment); } } yield return(new WaitForSeconds(1)); server.ServerDisconnect(1); yield return(new WaitUntil(() => task.IsCompleted)); RunNode.Result result = task.Result; string expectedFormat = "length: 5 msg: {0:X2} 64 00 00 00"; IEnumerable <string> expected = Enumerable.Range(0, messageCount).Select(i => string.Format(expectedFormat, i)); result.AssetTimeout(false); result.AssetOutput(expected.ToArray()); result.AssetErrors(); }
public IEnumerator ShouldTimeoutClientAfterClientProcessIsKilled() { // kill js early so it doesn't send close message Task <RunNode.Result> task = RunNode.RunAsync("Connect.js", 2000); while (!task.IsCompleted) { yield return(null); } RunNode.Result result = task.Result; result.AssetTimeout(true); result.AssetOutput( "Connection opened" ); result.AssetErrors(); // wait for timeout yield return(new WaitForSeconds(2 * timeout / 1000)); Assert.That(server.onConnect, Has.Count.EqualTo(1), "Connect should be called once"); Assert.That(server.onDisconnect, Has.Count.EqualTo(1), "Disconnected should be called once"); }
public IEnumerator ManyPings(int count) { int connectIndex = 1; server.OnServerConnected = ((connId) => { Assert.That(connId == connectIndex, "Clients should be connected in order with the next index"); connectIndex++; }); Task <RunNode.Result> task = RunNode.RunAsync("Ping.js", arg0: count.ToString(), msTimeout: 30_000); // 4 seconds should be enough time for clients to connect then close themselves yield return(new WaitForSeconds(4)); Assert.That(server.onConnect, Has.Count.EqualTo(count), "All should be connectted"); // make sure all clients start connected for a while const int seconds = 10; for (float i = 0; i < seconds; i += Time.deltaTime) { Assert.That(server.onDisconnect, Has.Count.EqualTo(0), "no clients should be disconnected"); yield return(null); } for (int i = 0; i < count; i++) { // 1 indexed server.ServerDisconnect(i + 1); } // wait for all to disconnect yield return(new WaitForSeconds(1)); Assert.That(server.onDisconnect, Has.Count.EqualTo(count), "no clients should be disconnected"); // check all tasks finished with no logs Assert.That(task.IsCompleted, Is.True, "Take should have been completed"); RunNode.Result result = task.Result; result.AssetTimeout(false); result.AssetOutput(); result.AssetErrors(); List <byte[]>[] messageForClients = sortMessagesForClients(count, server.onData); for (int i = 0; i < count; i++) { List <byte[]> messages = messageForClients[i]; int expected = seconds - 1; Assert.That(messages, Has.Count.AtLeast(expected), $"Should have atleast {expected} ping messages"); foreach (byte[] message in messages) { Assert.That(message[0], Is.EqualTo(10), "first byte should be 10"); Assert.That(message[1], Is.EqualTo(11), "second byte should be 11"); Assert.That(message[2], Is.EqualTo(12), "thrid byte should be 12"); Assert.That(message[3], Is.EqualTo(13), "fourth byte should be 13"); } } }