public void WithHeartbeat_should_return_new_instance_when_a_field_is_not_equal(string notEqualField) { var averageRoundTripTime = TimeSpan.FromSeconds(1); var replicaSetConfig = new ReplicaSetConfig( new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) }, "name", new DnsEndPoint("localhost", 27017), 1); var state = ServerState.Connected; var tags = new TagSet(new[] { new Tag("x", "a") }); var type = ServerType.ReplicaSetPrimary; var version = new SemanticVersion(2, 6, 3); var wireVersionRange = new Range <int>(2, 3); var subject = new ServerDescription( __serverId, __endPoint, state: state, type: type, averageRoundTripTime: averageRoundTripTime, replicaSetConfig: replicaSetConfig, tags: tags, version: version, wireVersionRange: wireVersionRange); switch (notEqualField) { case "AverageRoundTripTime": averageRoundTripTime = averageRoundTripTime.Add(TimeSpan.FromSeconds(1)); break; case "ReplicaSetConfig": replicaSetConfig = new ReplicaSetConfig(replicaSetConfig.Members, "newname", replicaSetConfig.Primary, replicaSetConfig.Version); break; case "Tags": tags = new TagSet(new[] { new Tag("x", "b") }); break; case "Type": type = ServerType.ReplicaSetSecondary; break; case "Version": version = new SemanticVersion(version.Major, version.Minor, version.Patch + 1); break; case "WireVersionRange": wireVersionRange = new Range <int>(0, 0); break; } var serverDescription2 = subject.With( averageRoundTripTime: averageRoundTripTime, replicaSetConfig: replicaSetConfig, state: ServerState.Connected, tags: tags, type: type, version: version, wireVersionRange: wireVersionRange); subject.Equals(serverDescription2).Should().BeFalse(); subject.Equals((object)serverDescription2).Should().BeFalse(); subject.GetHashCode().Should().NotBe(serverDescription2.GetHashCode()); }
protected override void InitializeSubClass() { // generate initial server description var newDescription = _baseDescription .With( type: ServerType.LoadBalanced, reasonChanged: "Initialized", state: ServerState.Connected); var oldDescription = Interlocked.CompareExchange(ref _currentDescription, value: newDescription, comparand: _currentDescription); var eventArgs = new ServerDescriptionChangedEventArgs(oldDescription, newDescription); // propagate event to upper levels, this will be called only once TriggerServerDescriptionChanged(this, eventArgs); }
protected override void Invalidate(string reasonInvalidated, bool clearConnectionPool, TopologyVersion topologyVersion) { var newDescription = _baseDescription.With( $"InvalidatedBecause:{reasonInvalidated}", lastUpdateTimestamp: DateTime.UtcNow, topologyVersion: topologyVersion); SetDescription(newDescription, clearConnectionPool); // TODO: make the heartbeat request conditional so we adhere to this part of the spec // > Network error when reading or writing: ... Clients MUST NOT request an immediate check of the server; // > since application sockets are used frequently, a network error likely means the server has just become // > unavailable, so an immediate refresh is likely to get a network error, too. RequestHeartbeat(); }
protected override void InitializeSubClass() { // generate initial server description var newDescription = _baseDescription .With( type: ServerType.LoadBalanced, reasonChanged: "Initialized", state: ServerState.Connected); var oldDescription = Interlocked.CompareExchange(ref _currentDescription, value: newDescription, comparand: _currentDescription); var eventArgs = new ServerDescriptionChangedEventArgs(oldDescription, newDescription); // mark pool as ready, start the connection creation thread. // note that the pool can not be paused after it was marked as ready in LB mode. ConnectionPool.SetReady(); // propagate event to upper levels, this will be called only once TriggerServerDescriptionChanged(this, eventArgs); }
public void With_should_return_same_instance_when_all_fields_are_equal() { var averageRoundTripTime = TimeSpan.FromSeconds(1); var helloOk = true; var lastUpdateTimestamp = DateTime.UtcNow; var replicaSetConfig = new ReplicaSetConfig( new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) }, "name", new DnsEndPoint("localhost", 27017), 1); var state = ServerState.Connected; var tags = new TagSet(new[] { new Tag("x", "a") }); var type = ServerType.ReplicaSetPrimary; var version = new SemanticVersion(3, 6, 0); var wireVersionRange = new Range <int>(6, 14); var subject = new ServerDescription( __serverId, __endPoint, averageRoundTripTime: averageRoundTripTime, helloOk: helloOk, lastUpdateTimestamp: lastUpdateTimestamp, replicaSetConfig: replicaSetConfig, state: state, tags: tags, type: type, version: version, wireVersionRange: wireVersionRange); var result = subject.With( averageRoundTripTime: averageRoundTripTime, helloOk: helloOk, lastUpdateTimestamp: lastUpdateTimestamp, replicaSetConfig: replicaSetConfig, state: ServerState.Connected, tags: tags, type: type, version: version, wireVersionRange: wireVersionRange); result.ShouldBeEquivalentTo(subject); }
public void WithHeartbeat_should_return_same_instance_when_all_fields_are_equal() { var averageRoundTripTime = TimeSpan.FromSeconds(1); var replicaSetConfig = new ReplicaSetConfig( new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) }, "name", new DnsEndPoint("localhost", 27017), 1); var state = ServerState.Connected; var tags = new TagSet(new[] { new Tag("x", "a") }); var type = ServerType.ReplicaSetPrimary; var version = new SemanticVersion(2, 6, 3); var wireVersionRange = new Range <int>(0, 2); var subject = new ServerDescription( __serverId, __endPoint, state: state, type: type, averageRoundTripTime: averageRoundTripTime, replicaSetConfig: replicaSetConfig, tags: tags, version: version, wireVersionRange: wireVersionRange); var serverDescription2 = subject.With( averageRoundTripTime: averageRoundTripTime, replicaSetConfig: replicaSetConfig, state: ServerState.Connected, tags: tags, type: type, version: version, wireVersionRange: wireVersionRange); serverDescription2.Should().BeSameAs(subject); }
public void HandleChannelException_should_update_topology_as_expected_on_network_error_or_timeout( string errorType, bool shouldUpdateTopology) { var serverId = new ServerId(_clusterId, _endPoint); var connectionId = new ConnectionId(serverId); Exception innerMostException; switch (errorType) { case "MongoConnectionExceptionWithSocketTimeout": innerMostException = new SocketException((int)SocketError.TimedOut); break; case nameof(MongoConnectionException): innerMostException = new SocketException((int)SocketError.NetworkUnreachable); break; default: throw new ArgumentException("Unknown error type."); } var operationUsingChannelException = new MongoConnectionException(connectionId, "Oops", new IOException("Cry", innerMostException)); var mockConnection = new Mock <IConnectionHandle>(); var isMasterResult = new IsMasterResult(new BsonDocument { { "compressors", new BsonArray() } }); // the server version doesn't matter when we're not testing MongoNotPrimaryExceptions, but is needed when // Server calls ShouldClearConnectionPoolForException var buildInfoResult = new BuildInfoResult(new BsonDocument { { "version", "4.4.0" } }); mockConnection.SetupGet(c => c.Description) .Returns(new ConnectionDescription(new ConnectionId(serverId, 0), isMasterResult, buildInfoResult)); var mockConnectionPool = new Mock <IConnectionPool>(); mockConnectionPool.Setup(p => p.AcquireConnection(It.IsAny <CancellationToken>())).Returns(mockConnection.Object); mockConnectionPool.Setup(p => p.AcquireConnectionAsync(It.IsAny <CancellationToken>())).ReturnsAsync(mockConnection.Object); var mockConnectionPoolFactory = new Mock <IConnectionPoolFactory>(); mockConnectionPoolFactory .Setup(f => f.CreateConnectionPool(It.IsAny <ServerId>(), _endPoint)) .Returns(mockConnectionPool.Object); var mockMonitorServerInitialDescription = new ServerDescription(serverId, _endPoint).With(reasonChanged: "Initial D", type: ServerType.Unknown); var mockServerMonitor = new Mock <IServerMonitor>(); mockServerMonitor.SetupGet(m => m.Description).Returns(mockMonitorServerInitialDescription); mockServerMonitor.SetupGet(m => m.Lock).Returns(new object()); var mockServerMonitorFactory = new Mock <IServerMonitorFactory>(); mockServerMonitorFactory.Setup(f => f.Create(It.IsAny <ServerId>(), _endPoint)).Returns(mockServerMonitor.Object); var subject = new DefaultServer(_clusterId, _clusterClock, _clusterConnectionMode, _connectionModeSwitch, _directConnection, _settings, _endPoint, mockConnectionPoolFactory.Object, mockServerMonitorFactory.Object, _capturedEvents, _serverApi); subject.Initialize(); var heartbeatDescription = mockMonitorServerInitialDescription.With(reasonChanged: "Heartbeat", type: ServerType.Standalone); mockServerMonitor.Setup(m => m.Description).Returns(heartbeatDescription); mockServerMonitor.Raise( m => m.DescriptionChanged += null, new ServerDescriptionChangedEventArgs(mockMonitorServerInitialDescription, heartbeatDescription)); subject.Description.Should().Be(heartbeatDescription); subject.HandleChannelException(mockConnection.Object, operationUsingChannelException); if (shouldUpdateTopology) { subject.Description.Type.Should().Be(ServerType.Unknown); subject.Description.ReasonChanged.Should().Contain("ChannelException"); } else { subject.Description.Should().Be(heartbeatDescription); } }
public void With_should_return_new_instance_when_a_field_is_not_equal(string notEqualField) { var averageRoundTripTime = TimeSpan.FromSeconds(1); var canonicalEndPoint = new DnsEndPoint("localhost", 27017); var electionId = new ElectionId(ObjectId.GenerateNewId()); var heartbeatException = new Exception(); var heartbeatInterval = TimeSpan.FromSeconds(10); var lastUpdateTimestamp = DateTime.UtcNow; var lastWriteTimestamp = DateTime.UtcNow; var logicalSessionTimeout = TimeSpan.FromMinutes(1); var maxBatchCount = 1000; var maxDocumentSize = 16000000; var maxMessageSize = 48000000; var maxWireDocumentSize = 16000000; var replicaSetConfig = new ReplicaSetConfig( new[] { new DnsEndPoint("localhost", 27017), new DnsEndPoint("localhost", 27018) }, "name", new DnsEndPoint("localhost", 27017), 1); var state = ServerState.Connected; var tags = new TagSet(new[] { new Tag("x", "a") }); var type = ServerType.ReplicaSetPrimary; var version = new SemanticVersion(2, 6, 3); var wireVersionRange = new Range <int>(2, 3); var subject = new ServerDescription( __serverId, __endPoint, averageRoundTripTime: averageRoundTripTime, canonicalEndPoint: canonicalEndPoint, electionId: electionId, heartbeatException: heartbeatException, heartbeatInterval: heartbeatInterval, lastUpdateTimestamp: lastUpdateTimestamp, lastWriteTimestamp: lastWriteTimestamp, logicalSessionTimeout: logicalSessionTimeout, maxBatchCount: maxBatchCount, maxDocumentSize: maxDocumentSize, maxMessageSize: maxMessageSize, maxWireDocumentSize: maxWireDocumentSize, replicaSetConfig: replicaSetConfig, state: state, tags: tags, type: type, version: version, wireVersionRange: wireVersionRange); switch (notEqualField) { case "AverageRoundTripTime": averageRoundTripTime = averageRoundTripTime.Add(TimeSpan.FromSeconds(1)); break; case "CanonicalEndPoint": canonicalEndPoint = new DnsEndPoint("localhost", 27018); break; case "ElectionId": electionId = new ElectionId(ObjectId.Empty); break; case "HeartbeatException": heartbeatException = new Exception(); break; case "HeartbeatInterval": heartbeatInterval = TimeSpan.FromSeconds(11); break; case "LastUpdateTimestamp": lastUpdateTimestamp = lastUpdateTimestamp.Add(TimeSpan.FromSeconds(1)); break; case "LastWriteTimestamp": lastWriteTimestamp = lastWriteTimestamp.Add(TimeSpan.FromSeconds(1)); break; case "LogicalSessionTimeout": logicalSessionTimeout = TimeSpan.FromMinutes(2); break; case "MaxBatchCount": maxBatchCount += 1; break; case "MaxDocumentSize": maxDocumentSize += 1; break; case "MaxMessageSize": maxMessageSize += 1; break; case "MaxWireDocumentSize": maxWireDocumentSize += 1; break; case "ReplicaSetConfig": replicaSetConfig = new ReplicaSetConfig(replicaSetConfig.Members, "newname", replicaSetConfig.Primary, replicaSetConfig.Version); break; case "State": state = ServerState.Disconnected; break; case "Tags": tags = new TagSet(new[] { new Tag("x", "b") }); break; case "Type": type = ServerType.ReplicaSetSecondary; break; case "Version": version = new SemanticVersion(version.Major, version.Minor, version.Patch + 1); break; case "WireVersionRange": wireVersionRange = new Range <int>(0, 0); break; } var result = subject.With( averageRoundTripTime: averageRoundTripTime, canonicalEndPoint: canonicalEndPoint, electionId: electionId, heartbeatException: heartbeatException, heartbeatInterval: heartbeatInterval, lastUpdateTimestamp: lastUpdateTimestamp, lastWriteTimestamp: lastWriteTimestamp, logicalSessionTimeout: logicalSessionTimeout, maxBatchCount: maxBatchCount, maxDocumentSize: maxDocumentSize, maxMessageSize: maxMessageSize, maxWireDocumentSize: maxWireDocumentSize, replicaSetConfig: replicaSetConfig, state: state, tags: tags, type: type, version: version, wireVersionRange: wireVersionRange); result.Should().NotBeSameAs(subject); result.Equals(subject).Should().BeFalse(); result.Equals((object)subject).Should().BeFalse(); result.GetHashCode().Should().NotBe(subject.GetHashCode()); }