示例#1
0
        public async Task DownloadInternalAsync_Raises_Expected_Final_Event_On_Cancellation(string username, IPAddress ip, int port, string filename, int token, int size)
        {
            var options = new SoulseekClientOptions(messageTimeout: 5);

            var response        = new PeerTransferResponse(token, false, size, string.Empty);
            var responseWaitKey = new WaitKey(MessageCode.PeerTransferResponse, username, token);

            var request = new PeerTransferRequest(TransferDirection.Download, token, filename, size);

            var transferConn = new Mock <IConnection>();

            transferConn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>()))
            .Returns(Task.CompletedTask);

            var waiter = new Mock <IWaiter>();

            waiter.Setup(m => m.Wait <PeerTransferResponse>(It.Is <WaitKey>(w => w.Equals(responseWaitKey)), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(response));
            waiter.Setup(m => m.WaitIndefinitely <PeerTransferRequest>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(request));
            waiter.Setup(m => m.Wait(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.CompletedTask);
            waiter.Setup(m => m.WaitIndefinitely <byte[]>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromException <byte[]>(new OperationCanceledException()));
            waiter.Setup(m => m.Wait <IConnection>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(transferConn.Object));
            waiter.Setup(m => m.Wait <GetPeerAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(new GetPeerAddressResponse(username, ip, port)));

            var conn = new Mock <IMessageConnection>();

            var connFactory = new Mock <IMessageConnectionFactory>();

            connFactory.Setup(m => m.GetMessageConnection(It.IsAny <MessageConnectionType>(), It.IsAny <string>(), It.IsAny <IPAddress>(), It.IsAny <int>(), It.IsAny <ConnectionOptions>()))
            .Returns(conn.Object);

            var s = new SoulseekClient("127.0.0.1", 1, options, messageWaiter: waiter.Object, messageConnectionFactory: connFactory.Object);

            s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn);

            var events = new List <DownloadStateChangedEventArgs>();

            s.DownloadStateChanged += (sender, e) =>
            {
                events.Add(e);
            };

            var ex = await Record.ExceptionAsync(async() => await s.InvokeMethod <Task <byte[]> >("DownloadInternalAsync", username, filename, token, null));

            Assert.NotNull(ex);
            Assert.IsType <DownloadException>(ex);
            Assert.IsType <OperationCanceledException>(ex.InnerException);

            Assert.Equal(DownloadStates.Cancelled, events[events.Count - 1].PreviousState);
            Assert.Equal(DownloadStates.Completed | DownloadStates.Cancelled, events[events.Count - 1].State);
        }
示例#2
0
        public async Task DownloadInternalAsync_Raises_DownloadProgressUpdated_Event_On_Data_Read(string username, IPAddress ip, int port, string filename, int token, int size)
        {
            var options = new SoulseekClientOptions(messageTimeout: 5);

            var response        = new PeerTransferResponse(1, false, 1, string.Empty);
            var responseWaitKey = new WaitKey(MessageCode.PeerTransferResponse, username, token);

            var request = new PeerTransferRequest(TransferDirection.Download, token, filename, size);

            var transferConn = new Mock <IConnection>();

            transferConn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>()))
            .Returns(Task.CompletedTask);
            transferConn.Setup(m => m.ReadAsync(It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(BitConverter.GetBytes(token)))
            .Raises(m => m.DataRead += null, this, new ConnectionDataEventArgs(Array.Empty <byte>(), 1, 1));

            var data = new byte[] { 0x0, 0x1, 0x2, 0x3 };

            var waiter = new Mock <IWaiter>();

            waiter.Setup(m => m.Wait <PeerTransferResponse>(It.Is <WaitKey>(w => w.Equals(responseWaitKey)), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(response));
            waiter.Setup(m => m.WaitIndefinitely <PeerTransferRequest>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(request));
            waiter.Setup(m => m.Wait(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.CompletedTask);
            waiter.Setup(m => m.WaitIndefinitely <byte[]>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult <byte[]>(data));
            waiter.Setup(m => m.Wait <IConnection>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(transferConn.Object));
            waiter.Setup(m => m.Wait <GetPeerAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(new GetPeerAddressResponse(username, ip, port)));

            var conn = new Mock <IMessageConnection>();

            conn.Setup(m => m.State)
            .Returns(ConnectionState.Connected);
            var connFactory = new Mock <IMessageConnectionFactory>();

            connFactory.Setup(m => m.GetMessageConnection(It.IsAny <MessageConnectionType>(), It.IsAny <string>(), It.IsAny <IPAddress>(), It.IsAny <int>(), It.IsAny <ConnectionOptions>()))
            .Returns(conn.Object);

            var s = new SoulseekClient("127.0.0.1", 1, options, messageWaiter: waiter.Object, messageConnectionFactory: connFactory.Object);

            s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn);

            var events = new List <DownloadProgressUpdatedEventArgs>();

            s.DownloadProgressUpdated += (d, e) => events.Add(e);

            await s.InvokeMethod <Task <byte[]> >("DownloadInternalAsync", username, filename, token, null);

            Assert.Single(events);
            Assert.Equal(1, events[0].BytesDownloaded);
        }
示例#3
0
        public void Parse_Throws_MessageReadException_On_Missing_Data()
        {
            var msg = new MessageBuilder()
                      .Code(MessageCode.PeerTransferRequest)
                      .Build();

            var ex = Record.Exception(() => PeerTransferRequest.Parse(msg));

            Assert.NotNull(ex);
            Assert.IsType <MessageReadException>(ex);
        }
示例#4
0
        public async Task DownloadInternalAsync_Throws_DownloadException_And_ConnectionException_On_Transfer_Exception(string username, IPAddress ip, int port, string filename, int token, int size)
        {
            var options = new SoulseekClientOptions(messageTimeout: 5);

            var response        = new PeerTransferResponse(1, false, 1, string.Empty);
            var responseWaitKey = new WaitKey(MessageCode.PeerTransferResponse, username, token);

            var request = new PeerTransferRequest(TransferDirection.Download, token, filename, size);

            var transferConn = new Mock <IConnection>();

            transferConn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>()))
            .Returns(Task.CompletedTask);
            transferConn.Setup(m => m.ReadAsync(It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromException <byte[]>(new NullReferenceException()));

            var waiter = new Mock <IWaiter>();

            waiter.Setup(m => m.Wait <PeerTransferResponse>(It.Is <WaitKey>(w => w.Equals(responseWaitKey)), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(response));
            waiter.Setup(m => m.WaitIndefinitely <PeerTransferRequest>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(request));
            waiter.Setup(m => m.Wait(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.CompletedTask);

            waiter.Setup(m => m.WaitIndefinitely <byte[]>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromException <byte[]>(new ConnectionException("foo", new NullReferenceException())));

            waiter.Setup(m => m.Wait <IConnection>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(transferConn.Object));
            waiter.Setup(m => m.Wait <GetPeerAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(new GetPeerAddressResponse(username, ip, port)));

            var conn = new Mock <IMessageConnection>();

            conn.Setup(m => m.State)
            .Returns(ConnectionState.Connected);
            var connFactory = new Mock <IMessageConnectionFactory>();

            connFactory.Setup(m => m.GetMessageConnection(It.IsAny <MessageConnectionType>(), It.IsAny <string>(), It.IsAny <IPAddress>(), It.IsAny <int>(), It.IsAny <ConnectionOptions>()))
            .Returns(conn.Object);

            var s = new SoulseekClient("127.0.0.1", 1, options, messageWaiter: waiter.Object, messageConnectionFactory: connFactory.Object);

            s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn);

            var ex = await Record.ExceptionAsync(async() => await s.InvokeMethod <Task <byte[]> >("DownloadInternalAsync", username, filename, token, null));

            Assert.NotNull(ex);
            Assert.IsType <DownloadException>(ex);
            Assert.IsType <ConnectionException>(ex.InnerException);
            Assert.IsType <NullReferenceException>(ex.InnerException.InnerException);
        }
示例#5
0
        public void Instantiates_With_The_Given_Data()
        {
            var dir   = (TransferDirection)Random.Next(2);
            var token = Random.Next();
            var file  = Guid.NewGuid().ToString();
            var size  = Random.Next();

            PeerTransferRequest response = null;

            var ex = Record.Exception(() => response = new PeerTransferRequest(dir, token, file, size));

            Assert.Null(ex);

            Assert.Equal(dir, response.Direction);
            Assert.Equal(token, response.Token);
            Assert.Equal(file, response.Filename);
            Assert.Equal(size, response.FileSize);
        }
示例#6
0
        public void ToMessage_Constructs_The_Correct_Message()
        {
            var rnd = new Random();

            var dir   = TransferDirection.Download;
            var token = rnd.Next();
            var file  = Guid.NewGuid().ToString();
            var size  = rnd.Next();
            var a     = new PeerTransferRequest(dir, token, file, size);
            var msg   = a.ToMessage();

            Assert.Equal(MessageCode.PeerTransferRequest, msg.Code);
            Assert.Equal(4 + 4 + 4 + 4 + file.Length + 4, msg.Length);

            var reader = new MessageReader(msg);

            Assert.Equal(0, reader.ReadInteger()); // direction
            Assert.Equal(token, reader.ReadInteger());
            Assert.Equal(file, reader.ReadString());
            Assert.Equal(size, reader.ReadInteger());
        }
        public void Completes_Wait_For_PeerTransferRequest(string username, IPAddress ip, int port, int token, string filename)
        {
            var conn = new Mock <IMessageConnection>();

            conn.Setup(m => m.Username)
            .Returns(username);
            conn.Setup(m => m.IPAddress)
            .Returns(ip);
            conn.Setup(m => m.Port)
            .Returns(port);

            var waiter = new Mock <IWaiter>();

            var msg = new PeerTransferRequest(TransferDirection.Download, token, filename).ToMessage();

            var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object);

            s.InvokeMethod("PeerConnection_MessageRead", conn.Object, msg);

            waiter.Verify(m => m.Complete(new WaitKey(MessageCode.PeerTransferRequest, username, filename), It.Is <PeerTransferRequest>(r => r.Token == token)), Times.Once);
        }
示例#8
0
        public void Parse_Returns_Expected_Data()
        {
            var dir   = Random.Next(2);
            var token = Random.Next();
            var file  = Guid.NewGuid().ToString();
            var size  = Random.Next();

            var msg = new MessageBuilder()
                      .Code(MessageCode.PeerTransferRequest)
                      .WriteInteger(dir)
                      .WriteInteger(token)
                      .WriteString(file)
                      .WriteInteger(size)
                      .Build();

            var response = PeerTransferRequest.Parse(msg);

            Assert.Equal(dir, (int)response.Direction);
            Assert.Equal(token, response.Token);
            Assert.Equal(file, response.Filename);
            Assert.Equal(size, response.FileSize);
        }
示例#9
0
        public async Task DownloadInternalAsync_Raises_Expected_Events_On_Success(string username, IPAddress ip, int port, string filename, int token, int size)
        {
            var options = new SoulseekClientOptions(messageTimeout: 5);

            var response        = new PeerTransferResponse(1, false, 1, string.Empty);
            var responseWaitKey = new WaitKey(MessageCode.PeerTransferResponse, username, token);

            var request = new PeerTransferRequest(TransferDirection.Download, token, filename, size);

            var transferConn = new Mock <IConnection>();

            transferConn.Setup(m => m.WriteAsync(It.IsAny <byte[]>(), It.IsAny <CancellationToken>()))
            .Returns(Task.CompletedTask);

            var data = new byte[] { 0x0, 0x1, 0x2, 0x3 };

            var waiter = new Mock <IWaiter>();

            waiter.Setup(m => m.Wait <PeerTransferResponse>(It.Is <WaitKey>(w => w.Equals(responseWaitKey)), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(response));
            waiter.Setup(m => m.WaitIndefinitely <PeerTransferRequest>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(request));
            waiter.Setup(m => m.Wait(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.CompletedTask);
            waiter.Setup(m => m.WaitIndefinitely <byte[]>(It.IsAny <WaitKey>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult <byte[]>(data));
            waiter.Setup(m => m.Wait <IConnection>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(transferConn.Object));
            waiter.Setup(m => m.Wait <GetPeerAddressResponse>(It.IsAny <WaitKey>(), null, It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(new GetPeerAddressResponse(username, ip, port)));

            var conn = new Mock <IMessageConnection>();

            conn.Setup(m => m.State)
            .Returns(ConnectionState.Connected);
            var connFactory = new Mock <IMessageConnectionFactory>();

            connFactory.Setup(m => m.GetMessageConnection(It.IsAny <MessageConnectionType>(), It.IsAny <string>(), It.IsAny <IPAddress>(), It.IsAny <int>(), It.IsAny <ConnectionOptions>()))
            .Returns(conn.Object);

            var s = new SoulseekClient("127.0.0.1", 1, options, messageWaiter: waiter.Object, messageConnectionFactory: connFactory.Object);

            s.SetProperty("State", SoulseekClientStates.Connected | SoulseekClientStates.LoggedIn);

            var events = new List <DownloadStateChangedEventArgs>();

            s.DownloadStateChanged += (sender, e) =>
            {
                events.Add(e);
            };

            await s.InvokeMethod <Task <byte[]> >("DownloadInternalAsync", username, filename, token, null);

            Assert.Equal(5, events.Count);

            Assert.Equal(DownloadStates.None, events[0].PreviousState);
            Assert.Equal(DownloadStates.Queued, events[0].State);

            Assert.Equal(DownloadStates.Queued, events[1].PreviousState);
            Assert.Equal(DownloadStates.Initializing, events[1].State);

            Assert.Equal(DownloadStates.Initializing, events[2].PreviousState);
            Assert.Equal(DownloadStates.InProgress, events[2].State);

            Assert.Equal(DownloadStates.InProgress, events[3].PreviousState);
            Assert.Equal(DownloadStates.Succeeded, events[3].State);

            Assert.Equal(DownloadStates.Succeeded, events[4].PreviousState);
            Assert.Equal(DownloadStates.Completed | DownloadStates.Succeeded, events[4].State);
        }