public async Task DownloadInternalAsync_Throws_DownloadException_On_PeerTransferRequest_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 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.FromException <PeerTransferRequest>(new OperationCanceledException())); 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 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); }
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.PeerTransferResponse) .Build(); var ex = Record.Exception(() => PeerTransferResponse.Parse(msg)); Assert.NotNull(ex); Assert.IsType <MessageReadException>(ex); }
public void Parse_Throws_MessageException_On_Code_Mismatch() { var msg = new MessageBuilder() .Code(MessageCode.PeerBrowseRequest) .Build(); var ex = Record.Exception(() => PeerTransferResponse.Parse(msg)); Assert.NotNull(ex); Assert.IsType <MessageException>(ex); }
public async Task DownloadInternalAsync_Returns_Expected_Data_On_Completion(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 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); byte[] downloadedData = null; var ex = await Record.ExceptionAsync(async() => downloadedData = await s.InvokeMethod <Task <byte[]> >("DownloadInternalAsync", username, filename, token, null)); Assert.Null(ex); Assert.Equal(data, downloadedData); }
public void Parse_Returns_Expected_Data_When_Allowed() { var token = Random.Next(); var size = Random.Next(); var msg = new MessageBuilder() .Code(MessageCode.PeerTransferResponse) .WriteInteger(token) .WriteByte(0x1) .WriteInteger(size) .Build(); var response = PeerTransferResponse.Parse(msg); Assert.Equal(token, response.Token); Assert.True(response.Allowed); Assert.Equal(size, response.FileSize); }
public void Instantiates_With_The_Given_Data() { var token = Random.Next(); var allowed = Random.Next() % 2 == 0; var msg = Guid.NewGuid().ToString(); var size = Random.Next(); PeerTransferResponse response = null; var ex = Record.Exception(() => response = new PeerTransferResponse(token, allowed, size, msg)); Assert.Null(ex); Assert.Equal(token, response.Token); Assert.Equal(allowed, response.Allowed); Assert.Equal(msg, response.Message); Assert.Equal(size, response.FileSize); }
public void Parse_Returns_Expected_Data_When_Disallowed() { var token = Random.Next(); var message = Guid.NewGuid().ToString(); var msg = new MessageBuilder() .Code(MessageCode.PeerTransferResponse) .WriteInteger(token) .WriteByte(0x0) .WriteString(message) .Build(); var response = PeerTransferResponse.Parse(msg); Assert.Equal(token, response.Token); Assert.False(response.Allowed); Assert.Equal(message, response.Message); }
public void ToMessage_Constructs_The_Correct_Message() { var rnd = new Random(); var token = rnd.Next(); var size = rnd.Next(); var message = Guid.NewGuid().ToString(); var a = new PeerTransferResponse(token, true, size, message); var msg = a.ToMessage(); Assert.Equal(MessageCode.PeerTransferResponse, msg.Code); Assert.Equal(4 + 4 + 1 + 4 + 4 + message.Length, msg.Length); var reader = new MessageReader(msg); Assert.Equal(token, reader.ReadInteger()); Assert.Equal(1, reader.ReadByte()); Assert.Equal(size, reader.ReadInteger()); Assert.Equal(message, reader.ReadString()); }
public void Completes_Wait_For_PeerTransferResponse(string username, IPAddress ip, int port, int token, bool allowed, int fileSize, string message) { 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 PeerTransferResponse(token, allowed, fileSize, message).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.PeerTransferResponse, username, token), It.Is <PeerTransferResponse>(r => r.Token == token)), Times.Once); }
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); }