public async Task Connected_Handler_Of_Server_Connection_Starts_Reading(IPEndPoint endpoint)
        {
            var streamMock = new Mock <INetworkStream>();

            streamMock.Setup(s => s.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromException <int>(new Exception()));

            var tcpMock = new Mock <ITcpClient>();

            using (var socket = new Socket(SocketType.Stream, ProtocolType.IP))
            {
                tcpMock.Setup(m => m.Client).Returns(socket);
                tcpMock.Setup(s => s.GetStream()).Returns(streamMock.Object);

                using (var c = new MessageConnection(endpoint, tcpClient: tcpMock.Object))
                {
                    await c.ConnectAsync();

                    // because the reading takes place in a separate task,
                    // and we need it to fail so it doesn't keep looping,
                    // and because ReadingContinuously is set to false when it fails,
                    // the best way to make sure this is actually starting the reading is to
                    // check the stream after a delay.
                    await Task.Delay(500);

                    streamMock.Verify(s => s.Close(), Times.Once);
                }
            }
        }
        public async Task Codes_Normalized_For_Peer_Connections(string username, IPAddress ipAddress, int port)
        {
            int code = 0;

            var streamMock = new Mock <INetworkStream>();

            streamMock.Setup(s => s.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Returns(Task.Run(() => 1));
            streamMock.Setup(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Callback <byte[], int, int, CancellationToken>((bytes, offset, length, token) => code = BitConverter.ToInt32(bytes, 4))
            .Returns(Task.CompletedTask);

            var tcpMock = new Mock <ITcpClient>();

            tcpMock.Setup(s => s.Connected).Returns(true);
            tcpMock.Setup(s => s.GetStream()).Returns(streamMock.Object);

            var msg = new MessageBuilder()
                      .Code(MessageCode.PeerInfoRequest)
                      .Build();

            var c = new MessageConnection(MessageConnectionType.Peer, username, ipAddress, port, tcpClient: tcpMock.Object);
            await c.ConnectAsync();

            await c.WriteMessageAsync(msg);

            Assert.Equal((int)MessageCode.PeerInfoRequest - 20000, code);

            streamMock.Verify(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()), Times.Once);
        }
        public async Task WriteMessageAsync_Throws_ConnectionWriteException_When_Stream_WriteAsync_Throws(IPAddress ipAddress, int port)
        {
            var streamMock = new Mock <INetworkStream>();

            streamMock.Setup(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Throws(new IOException());
            streamMock.Setup(s => s.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Returns(Task.Run(() => 1));

            var tcpMock = new Mock <ITcpClient>();

            tcpMock.Setup(s => s.Connected).Returns(true);
            tcpMock.Setup(s => s.GetStream()).Returns(streamMock.Object);

            var msg = new MessageBuilder()
                      .Code(MessageCode.PeerBrowseRequest)
                      .Build();

            var c = new MessageConnection(MessageConnectionType.Server, ipAddress, port, tcpClient: tcpMock.Object);

            await c.ConnectAsync();

            var ex = await Record.ExceptionAsync(async() => await c.WriteMessageAsync(msg));

            Assert.NotNull(ex);
            Assert.IsType <ConnectionWriteException>(ex);
            Assert.IsType <IOException>(ex.InnerException);

            streamMock.Verify(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()), Times.Once);
        }
Esempio n. 4
0
        public async Task Deferred_Messages_Are_Sent_On_Connected(IPAddress ipAddress, int port)
        {
            var streamMock = new Mock <INetworkStream>();

            streamMock.Setup(s => s.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Returns(Task.Run(() => 1));

            var tcpMock = new Mock <ITcpClient>();

            tcpMock.Setup(s => s.Connected).Returns(true);
            tcpMock.Setup(s => s.GetStream()).Returns(streamMock.Object);

            var msg = new MessageBuilder()
                      .Code(MessageCode.PeerBrowseRequest)
                      .Build();

            var c = new MessageConnection(MessageConnectionType.Server, ipAddress, port, tcpClient: tcpMock.Object);

            await c.WriteMessageAsync(msg);

            await c.WriteMessageAsync(msg);

            var deferred1 = c.GetProperty <ConcurrentQueue <Message> >("DeferredMessages").Count;

            await c.ConnectAsync();

            var deferred2 = c.GetProperty <ConcurrentQueue <Message> >("DeferredMessages");

            Assert.Equal(2, deferred1);
            Assert.Empty(deferred2);

            streamMock.Verify(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()), Times.Exactly(2));
        }
        public async Task ReadContinuouslyAsync_Raises_MessageRead_On_Read(string username, IPAddress ipAddress, int port)
        {
            int callCount = 0;

            var streamMock = new Mock <INetworkStream>();

            streamMock.Setup(s => s.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Callback <byte[], int, int, CancellationToken>((bytes, offset, length, token) =>
            {
                if (callCount % 2 == 0)
                {
                    var data = BitConverter.GetBytes(4);
                    Array.Copy(data, bytes, data.Length);
                }
                else if (callCount % 2 == 1)
                {
                    var data = BitConverter.GetBytes((int)MessageCode.PeerInfoRequest - 20000);
                    Array.Copy(data, bytes, data.Length);
                }

                callCount++;
            })
            .Returns(Task.Run(() => 4));

            var tcpMock = new Mock <ITcpClient>();

            tcpMock.Setup(s => s.Connected).Returns(true);
            tcpMock.Setup(s => s.GetStream()).Returns(streamMock.Object);

            Message readMessage = null;

            var c = new MessageConnection(MessageConnectionType.Peer, username, ipAddress, port, tcpClient: tcpMock.Object);

            c.MessageRead += (sender, e) => readMessage = e;

            await c.ConnectAsync();

            Thread.Sleep(1000); // ReadContinuouslyAsync() runs in a separate task, so events won't arrive immediately after connect

            Assert.Equal(MessageCode.PeerInfoRequest, readMessage?.Code);
        }
        public async Task WriteMessageAsync_Writes_When_Connected(string username, IPAddress ipAddress, int port)
        {
            var streamMock = new Mock <INetworkStream>();

            streamMock.Setup(s => s.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Returns(Task.Run(() => 1));

            var tcpMock = new Mock <ITcpClient>();

            tcpMock.Setup(s => s.Connected).Returns(true);
            tcpMock.Setup(s => s.GetStream()).Returns(streamMock.Object);

            var msg = new MessageBuilder()
                      .Code(MessageCode.PeerBrowseRequest)
                      .Build();

            var c = new MessageConnection(MessageConnectionType.Peer, username, ipAddress, port, tcpClient: tcpMock.Object);
            await c.ConnectAsync();

            await c.WriteMessageAsync(msg);

            streamMock.Verify(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()), Times.Once);
        }