public async Task IdleChannelClosureAsyncTest() { using (FaultyServer server = new FaultyServer()) { try { await server.StartAsync(); TimeSpan runTime = TimeSpan.FromSeconds(45.0); Stopwatch sw = Stopwatch.StartNew(); Guid activityId = Guid.NewGuid(); Trace.CorrelationManager.ActivityId = activityId; ChannelProperties channelProperties = new ChannelProperties( new UserAgentContainer(), certificateHostNameOverride: "localhost", requestTimerPool: new TimerPool(1), requestTimeout: TimeSpan.FromSeconds(3.0), openTimeout: TimeSpan.FromSeconds(3.0), maxChannels: ushort.MaxValue, partitionCount: 1, maxRequestsPerChannel: 100, receiveHangDetectionTime: TimeSpan.FromSeconds(11.0), sendHangDetectionTime: TimeSpan.FromSeconds(3.0), idleTimeout: TimeSpan.FromSeconds(5), idleTimerPool: new TimerPool(1)); using (Channel channel = new Channel( server.Uri, channelProperties)) { AutoResetEvent initializationEvent = new AutoResetEvent(initialState: false); ManualResetEventSlim connectionClosedEvent = new ManualResetEventSlim(initialState: false); channel.OnInitializationComplete += () => { Trace.WriteLine("channel initialization event is fired"); initializationEvent.Set(); }; channel.SubscribeToConnectionClosure(() => { Trace.WriteLine("channel connection closure event is fired"); connectionClosedEvent.Set(); }); channel.Initialize(activityId); Assert.IsTrue(initializationEvent.WaitOne()); Trace.WriteLine("channel initialization completes"); Assert.IsTrue(channel.Healthy); Assert.IsFalse(connectionClosedEvent.IsSet); Trace.WriteLine($"Start waiting for idle: {DateTime.UtcNow}"); bool isChannelIdleAndClosed = false; while (sw.Elapsed < runTime) { if (!channel.Healthy) { Assert.IsTrue(channel.IsIdle); Trace.WriteLine($"Idle: {DateTime.UtcNow}"); if (connectionClosedEvent.Wait(TimeSpan.FromSeconds(2))) { Trace.WriteLine($"Connection closed: {DateTime.UtcNow}"); sw.Stop(); isChannelIdleAndClosed = true; break; } } await Task.Delay(TimeSpan.FromSeconds(2)); } Assert.IsTrue(isChannelIdleAndClosed); Assert.IsTrue(sw.Elapsed < runTime); } } finally { await server.StopAsync(); } } }
public async Task ServerCloseOnSslNegotiationCompleteAsyncTest() { using (FaultyServer server = new FaultyServer()) { server.OnConnectionEvent += (sender, args) => { if (args.EventType == FaultyServer.ConnectionEventType.SslNegotiationComplete) { RntbdTests.RandomSleep(); args.Close = true; } }; try { await server.StartAsync(); Dictionary <OperationType, ResourceOperation> operationMap = new Dictionary <OperationType, ResourceOperation> { [OperationType.Read] = ResourceOperation.ReadDocument, [OperationType.Upsert] = ResourceOperation.UpsertDocument, }; foreach (OperationType operationType in new OperationType[] { OperationType.Read, OperationType.Upsert }) { TimeSpan runTime = TimeSpan.FromSeconds(10.0); Stopwatch sw = Stopwatch.StartNew(); while (sw.Elapsed < runTime) { Guid activityId = Guid.NewGuid(); Trace.CorrelationManager.ActivityId = activityId; using (Rntbd.Channel channel = new Rntbd.Channel( server.Uri, new Rntbd.ChannelProperties( new UserAgentContainer(), certificateHostNameOverride: "localhost", timerPool: new TimerPool(1), requestTimeout: TimeSpan.FromSeconds(1.0), openTimeout: TimeSpan.FromSeconds(1.0), maxChannels: ushort.MaxValue, maxRequestsPerChannel: 100, receiveHangDetectionTime: TimeSpan.FromSeconds(2.0), sendHangDetectionTime: TimeSpan.FromSeconds(0.5)))) { channel.Initialize(activityId); try { ResourceType resourceType = ResourceType.Document; ResourceOperation resourceOperation = operationMap[operationType]; StoreResponse response = await channel.RequestAsync( DocumentServiceRequest.Create( operationType, resourceType, AuthorizationTokenType.SecondaryReadonlyMasterKey), new Uri(server.Uri, "foo/bar/baz"), resourceOperation, activityId); } catch (DocumentClientException e) { Assert.AreEqual(activityId.ToString(), e.ActivityId); if (!string.Equals("ServiceUnavailable", e.Error.Code) && !string.Equals("Gone", e.Error.Code)) { Assert.Fail("Unexpected error code: {0}", e.Error.Code); } Exception rootCause = e; Exception nextRootCause = e.InnerException; while (nextRootCause != null) { rootCause = nextRootCause; nextRootCause = nextRootCause.InnerException; } SocketException socketException = rootCause as SocketException; if (socketException != null) { if (socketException.SocketErrorCode != SocketError.ConnectionReset && socketException.SocketErrorCode != SocketError.ConnectionAborted) { Assert.Fail( "Expected connection reset or " + "connection aborted. Actual: {0}", socketException.SocketErrorCode.ToString()); } } else { GoneException goneException = rootCause as GoneException; IOException ioException = rootCause as IOException; Assert.IsTrue(goneException != null || ioException != null, "Expected GoneException or IOException. Actual: {0} ({1})", rootCause.Message, rootCause.GetType()); } } } } } } finally { await server.StopAsync(); } } }
public async Task ServerCloseOnSslNegotiationCompleteAsyncTest() { using (FaultyServer server = new FaultyServer()) { server.OnConnectionEvent += (sender, args) => { if (args.EventType == FaultyServer.ConnectionEventType.SslNegotiationComplete) { RntbdTests.RandomSleep(); args.Close = true; } }; try { await server.StartAsync(); Dictionary <OperationType, ResourceOperation> operationMap = new Dictionary <OperationType, ResourceOperation> { [OperationType.Read] = ResourceOperation.ReadDocument, [OperationType.Upsert] = ResourceOperation.UpsertDocument, }; foreach (OperationType operationType in new OperationType[] { OperationType.Read, OperationType.Upsert }) { TimeSpan runTime = TimeSpan.FromSeconds(10.0); Stopwatch sw = Stopwatch.StartNew(); while (sw.Elapsed < runTime) { Guid activityId = Guid.NewGuid(); Trace.CorrelationManager.ActivityId = activityId; using (Rntbd.Channel channel = new Rntbd.Channel( server.Uri, RntbdTests.GetChannelProperties())) { channel.Initialize(activityId); try { ResourceType resourceType = ResourceType.Document; ResourceOperation resourceOperation = operationMap[operationType]; StoreResponse response = await channel.RequestAsync( DocumentServiceRequest.Create( operationType, resourceType, AuthorizationTokenType.SecondaryReadonlyMasterKey), new Uri(server.Uri, "foo/bar/baz"), resourceOperation, activityId); } catch (TransportException e) { Assert.AreEqual(activityId, e.ActivityId); Assert.IsTrue( (e.ErrorCode == TransportErrorCode.ReceiveFailed) || (e.ErrorCode == TransportErrorCode.SslNegotiationFailed) || (e.ErrorCode == TransportErrorCode.ReceiveStreamClosed), "Expected ReceiveFailed or ReceiveStreamClosed. Actual: {0}", e.ErrorCode); Exception rootCause = e.GetBaseException(); if (e.Equals(rootCause)) { return; } SocketException socketException = rootCause as SocketException; if (socketException != null) { if (socketException.SocketErrorCode != SocketError.ConnectionReset && socketException.SocketErrorCode != SocketError.ConnectionAborted) { Assert.Fail( "Expected connection reset or " + "connection aborted. Actual: {0}", socketException.SocketErrorCode.ToString()); } } else { IOException ioException = rootCause as IOException; Assert.IsTrue(ioException != null, "Expected IOException. Actual: {0} ({1})", rootCause.Message, rootCause.GetType()); } } } } } } finally { await server.StopAsync(); } } }