コード例 #1
0
        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());
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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();
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
            }
        }
コード例 #8
0
        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());
        }