public void Stop_should_trigger_immidiate_maintenace_call( [Values(false, true)] bool checkOutConnection, [Values(false, true)] bool closeInUseConnection) { var eventCapturer = new EventCapturer() .Capture <ConnectionPoolAddedConnectionEvent>() .Capture <ConnectionPoolRemovedConnectionEvent>(); int connectionId = 0; using (var pool = CreatePool( eventCapturer, minPoolSize: 1, connectionFactoryConfigurator: (factory) => { factory .Setup(f => f.CreateConnection(__serverId, __endPoint)) .Returns(() => new MockConnection(new ConnectionId(__serverId, ++connectionId), new ConnectionSettings(), eventCapturer)); })) // use to ensure that Maintenance attempt has been called { var subject = pool._maintenanceHelper(); var maitenanceInPlayTimeout = TimeSpan.FromMilliseconds(50); eventCapturer.WaitForEventOrThrowIfTimeout <ConnectionPoolAddedConnectionEvent>(maitenanceInPlayTimeout); eventCapturer.Next().Should().BeOfType <ConnectionPoolAddedConnectionEvent>().Which.ConnectionId.LocalValue.Should().Be(1); // minPoolSize has been enrolled eventCapturer.Any().Should().BeFalse(); SpinWait.SpinUntil(() => pool.ConnectionHolder._connections().Count > 0, TimeSpan.FromSeconds(1)).Should().BeTrue(); // wait until connection 1 has been returned to the pool after minPoolSize logic IConnection acquiredConnection = null; if (checkOutConnection) { acquiredConnection = pool.AcquireConnection(CancellationToken.None); acquiredConnection.ConnectionId.LocalValue.Should().Be(1); } IncrementGeneration(pool); subject.Stop(maxGenerationToReap: closeInUseConnection ? pool.Generation : null); var requestInPlayTimeout = TimeSpan.FromMilliseconds(100); if (!closeInUseConnection && checkOutConnection) { // connection in progress should be not touched Thread.Sleep(requestInPlayTimeout); } else { eventCapturer.WaitForOrThrowIfTimeout((events) => events.OfType <ConnectionPoolRemovedConnectionEvent>().Count() >= 1, requestInPlayTimeout); eventCapturer.Next().Should().BeOfType <ConnectionPoolRemovedConnectionEvent>(); } eventCapturer.Any().Should().BeFalse(); pool.AvailableCount.Should().Be(checkOutConnection ? pool.Settings.MaxConnections - 1 : pool.Settings.MaxConnections); pool.CreatedCount.Should().Be(checkOutConnection ? 1 : 0); pool.DormantCount.Should().Be(0); pool.PendingCount.Should().Be(0); pool.UsedCount.Should().Be(checkOutConnection ? 1 : 0); } }
public void Dispose_should_raise_the_correct_events() { _subject.Dispose(); _capturedEvents.Next().Should().BeOfType <ConnectionClosingEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionClosedEvent>(); _capturedEvents.Any().Should().BeFalse(); }
public void Dispose_should_dispose_the_server() { _subject.Initialize(); _capturedEvents.Clear(); _subject.Dispose(); _connectionPool.Received().Dispose(); _serverMonitor.Received().Dispose(); _capturedEvents.Next().Should().BeOfType <ServerClosingEvent>(); _capturedEvents.Next().Should().BeOfType <ServerClosedEvent>(); _capturedEvents.Any().Should().BeFalse(); }
public void Initialize_should_create_and_initialize_the_server() { var subject = CreateSubject(); subject.Initialize(); _serverFactory.GetServer(_endPoint).Received().Initialize(); _capturedEvents.Next().Should().BeOfType <ClusterOpeningEvent>(); _capturedEvents.Next().Should().BeOfType <ClusterAddingServerEvent>(); _capturedEvents.Next().Should().BeOfType <ClusterAddedServerEvent>(); _capturedEvents.Next().Should().BeOfType <ClusterOpenedEvent>(); _capturedEvents.Next().Should().BeOfType <ClusterDescriptionChangedEvent>(); _capturedEvents.Any().Should().BeFalse(); }
public void Description_should_contain_expected_server_description() { var subject = CreateSubject(); subject.Description.Servers.Should().BeEmpty(); subject.Initialize(); _capturedEvents.Clear(); PublishDescription(_endPoint); var description = subject.Description; description.Servers.Should().ContainSingle(s => EndPointHelper.Equals(s.EndPoint, _endPoint) && s.State == ServerState.Connected); _capturedEvents.Next().Should().BeOfType <ClusterDescriptionChangedEvent>(); _capturedEvents.Any().Should().BeFalse(); }
public void DescriptionChanged_should_be_raised_when_moving_from_disconnected_to_connected() { var changes = new List <ServerDescriptionChangedEventArgs>(); _subject.DescriptionChanged += (o, e) => changes.Add(e); SetupHeartbeatConnection(); _subject.Initialize(); SpinWait.SpinUntil(() => _subject.Description.State == ServerState.Connected, TimeSpan.FromSeconds(5)).Should().BeTrue(); changes.Count.Should().Be(1); changes[0].OldServerDescription.State.Should().Be(ServerState.Disconnected); changes[0].NewServerDescription.State.Should().Be(ServerState.Connected); _capturedEvents.Next().Should().BeOfType <ServerHeartbeatStartedEvent>(); _capturedEvents.Next().Should().BeOfType <ServerHeartbeatSucceededEvent>(); _capturedEvents.Any().Should().BeFalse(); }
public void BulkWrite_should_pin_connection_as_expected( [Values(1, 3)] int attempts, [Values(false, true)] bool async) { SkipIfNotLoadBalancingMode(); KillOpenTransactions(); SetupData(); ServiceIdHelper.IsServiceIdEmulationEnabled = true; // TODO: temporary solution to enable emulating serviceId in a server response var eventCapturer = new EventCapturer() .Capture <ConnectionPoolCheckedOutConnectionEvent>() .Capture <ConnectionPoolCheckingOutConnectionEvent>() .Capture <ConnectionPoolCheckedInConnectionEvent>() .Capture <ConnectionPoolCheckingInConnectionEvent>() .Capture <CommandSucceededEvent>(); using (var cluster = CreateLoadBalancedCluster(eventCapturer)) { eventCapturer.Clear(); for (int i = 1; i <= attempts; i++) { ICoreSessionHandle session; DisposableBindingBundle <IReadWriteBindingHandle, RetryableWriteContext> writeBindingsBundle; using (session = CreateSession(cluster, isImplicit: false, withTransaction: true)) { eventCapturer.Any().Should().BeFalse(); using (writeBindingsBundle = CreateReadWriteBindingsAndRetryableWriteContext(cluster, session.Fork(), async)) { AssertCheckOutOnlyEvents(eventCapturer, i); _ = CreateAndRunBulkOperation(writeBindingsBundle.RetryableContext, async); AssertCommand(eventCapturer, "insert", noMoreEvents: true); } } AssertCommand(eventCapturer, "abortTransaction", noMoreEvents: false); AssertCheckInOnlyEvents(eventCapturer); AssertSessionReferenceCount(session, 0); AssertChannelReferenceCount(writeBindingsBundle.RetryableContext.Channel, 0); } } }
public void Description_should_return_default_when_disposed() { _subject.Dispose(); var description = _subject.Description; description.EndPoint.Should().Be(_endPoint); description.Type.Should().Be(ServerType.Unknown); description.State.Should().Be(ServerState.Disconnected); _capturedEvents.Next().Should().BeOfType <ServerClosingEvent>(); _capturedEvents.Next().Should().BeOfType <ServerClosedEvent>(); _capturedEvents.Any().Should().BeFalse(); }
public void AcquireConnectionAsync_should_return_a_connection() { InitializeAndWait(); _capturedEvents.Clear(); var connection = _subject.AcquireConnectionAsync(CancellationToken.None).Result; connection.Should().NotBeNull(); _subject.AvailableCount.Should().Be(_settings.MaxConnections - 1); _subject.CreatedCount.Should().Be(_settings.MinConnections); _subject.DormantCount.Should().Be(_settings.MinConnections - 1); _subject.UsedCount.Should().Be(1); _capturedEvents.Next().Should().BeOfType <ConnectionPoolCheckingOutConnectionEvent>(); _capturedEvents.Next().Should().BeOfType <ConnectionPoolCheckedOutConnectionEvent>(); _capturedEvents.Any().Should().BeFalse(); }