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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }