public async Task PersonCircuitLifetimeAsync() { using CancellationTokenSource timeoutCts = new(TimeSpan.FromMinutes(1)); PersonCircuit aliceCircuit = new(); using TorTcpConnection aliceConnection = new(null !, new MemoryStream(), aliceCircuit, true); Mock <TorTcpConnectionFactory> mockTcpConnectionFactory = new(MockBehavior.Strict, new IPEndPoint(IPAddress.Loopback, 7777)); _ = mockTcpConnectionFactory.Setup(c => c.ConnectAsync(It.IsAny <Uri>(), aliceCircuit, It.IsAny <CancellationToken>())).ReturnsAsync(aliceConnection); Mock <TorHttpPool> mockTorHttpPool = new(MockBehavior.Loose, mockTcpConnectionFactory.Object) { CallBase = true }; mockTorHttpPool.Setup(x => x.SendCoreAsync(It.IsAny <TorTcpConnection>(), It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>())) .Returns((TorTcpConnection tcpConnection, HttpRequestMessage request, CancellationToken cancellationToken) => { if (tcpConnection == aliceConnection) { return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); } throw new NotSupportedException(); }); using TorHttpPool pool = mockTorHttpPool.Object; using HttpRequestMessage request = new(HttpMethod.Get, "http://wasabi.backend"); // Alice circuit is NOT yet disposed. using HttpResponseMessage aliceResponse = await pool.SendAsync(request, aliceCircuit); Assert.True(aliceResponse.IsSuccessStatusCode); // Dispose Alice circuit. aliceCircuit.Dispose(); // Alice circuit is already disposed and thus it cannot be used. await Assert.ThrowsAsync <TorCircuitExpiredException>(async() => await pool.SendAsync(request, aliceCircuit).ConfigureAwait(false)); mockTcpConnectionFactory.VerifyAll(); }
public async Task UseCorrectIdentitiesAsync() { using CancellationTokenSource timeoutCts = new(TimeSpan.FromMinutes(1)); ICircuit defaultIdentity = DefaultCircuit.Instance; using PersonCircuit aliceIdentity = new(); using PersonCircuit bobIdentity = new(); using TorTcpConnection aliceConnection = new(null !, new MemoryStream(), aliceIdentity, true); using TorTcpConnection bobConnection = new(null !, new MemoryStream(), bobIdentity, true); using TorTcpConnection defaultConnection = new(null !, new MemoryStream(), defaultIdentity, true); Mock <TorTcpConnectionFactory> mockTcpConnectionFactory = new(MockBehavior.Strict, new IPEndPoint(IPAddress.Loopback, 7777)); _ = mockTcpConnectionFactory.Setup(c => c.ConnectAsync(It.IsAny <Uri>(), aliceIdentity, It.IsAny <CancellationToken>())).ReturnsAsync(aliceConnection); _ = mockTcpConnectionFactory.Setup(c => c.ConnectAsync(It.IsAny <Uri>(), bobIdentity, It.IsAny <CancellationToken>())).ReturnsAsync(bobConnection); _ = mockTcpConnectionFactory.Setup(c => c.ConnectAsync(It.IsAny <Uri>(), defaultIdentity, It.IsAny <CancellationToken>())).ReturnsAsync(defaultConnection); TorTcpConnectionFactory tcpConnectionFactory = mockTcpConnectionFactory.Object; // Use implementation of TorHttpPool and only replace SendCoreAsync behavior. Mock <TorHttpPool> mockTorHttpPool = new(MockBehavior.Loose, tcpConnectionFactory) { CallBase = true }; mockTorHttpPool.Setup(x => x.SendCoreAsync(It.IsAny <TorTcpConnection>(), It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>())) .Returns((TorTcpConnection tcpConnection, HttpRequestMessage request, CancellationToken cancellationToken) => { HttpResponseMessage httpResponse = new(HttpStatusCode.OK); if (tcpConnection == aliceConnection) { httpResponse.Content = new StringContent("Alice circuit!"); } else if (tcpConnection == bobConnection) { httpResponse.Content = new StringContent("Bob circuit!"); } else if (tcpConnection == defaultConnection) { httpResponse.Content = new StringContent("Default circuit!"); } else { throw new NotSupportedException(); } return(Task.FromResult(httpResponse)); }); using TorHttpPool pool = mockTorHttpPool.Object; using HttpRequestMessage request = new(HttpMethod.Get, "http://wasabi.backend"); using HttpResponseMessage aliceResponse = await pool.SendAsync(request, aliceIdentity); Assert.Equal("Alice circuit!", await aliceResponse.Content.ReadAsStringAsync(timeoutCts.Token)); using HttpResponseMessage bobResponse = await pool.SendAsync(request, bobIdentity); Assert.Equal("Bob circuit!", await bobResponse.Content.ReadAsStringAsync(timeoutCts.Token)); using HttpResponseMessage defaultResponse = await pool.SendAsync(request, defaultIdentity); Assert.Equal("Default circuit!", await defaultResponse.Content.ReadAsStringAsync(timeoutCts.Token)); mockTcpConnectionFactory.VerifyAll(); }