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 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 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 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();
        }
Example #6
0
        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");
            }
        }
Example #7
0
        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 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");
        }
Example #10
0
        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");
                }
            }
        }