Example #1
0
        public void Dispose_should_dispose_the_server()
        {
            _subject.Initialize();
            _capturedEvents.Clear();

            _subject.Dispose();
            _mockConnectionPool.Verify(p => p.Dispose(), Times.Once);
            _mockServerMonitor.Verify(m => m.Dispose(), Times.Once);

            _capturedEvents.Next().Should().BeOfType <ServerClosingEvent>();
            _capturedEvents.Next().Should().BeOfType <ServerClosedEvent>();
            _capturedEvents.Any().Should().BeFalse();
        }
Example #2
0
        public void GetChannel_should_update_topology_and_clear_connection_pool_on_network_error_or_timeout(
            [Values("TimedOutSocketException", "NetworkUnreachableSocketException")] string errorType,
            [Values(false, true)] bool async)
        {
            var serverId           = new ServerId(_clusterId, _endPoint);
            var connectionId       = new ConnectionId(serverId);
            var innerMostException = CoreExceptionHelper.CreateException(errorType);

            var openConnectionException = new MongoConnectionException(connectionId, "Oops", new IOException("Cry", innerMostException));
            var mockConnection          = new Mock <IConnectionHandle>();

            mockConnection.Setup(c => c.Open(It.IsAny <CancellationToken>())).Throws(openConnectionException);
            mockConnection.Setup(c => c.OpenAsync(It.IsAny <CancellationToken>())).ThrowsAsync(openConnectionException);

            var connectionFactory = new Mock <IConnectionFactory>();

            connectionFactory.Setup(cf => cf.CreateConnection(serverId, _endPoint)).Returns(mockConnection.Object);

            var mockExceptionHandler   = new Mock <IConnectionExceptionHandler>();
            var connectionPoolSettings = new ConnectionPoolSettings();
            var connectionPool         = new ExclusiveConnectionPool(serverId, _endPoint, connectionPoolSettings, connectionFactory.Object, new EventAggregator(), mockExceptionHandler.Object);

            var mockConnectionPoolFactory = new Mock <IConnectionPoolFactory>();

            mockConnectionPoolFactory
            .Setup(f => f.CreateConnectionPool(It.IsAny <ServerId>(), _endPoint, It.IsAny <IConnectionExceptionHandler>()))
            .Returns(connectionPool);
            var mockMonitorServerDescription = new ServerDescription(serverId, _endPoint);
            var mockServerMonitor            = new Mock <IServerMonitor>();

            mockServerMonitor.SetupGet(m => m.Description).Returns(mockMonitorServerDescription);
            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);

            connectionPool._connectionExceptionHandler(subject);
            subject.Initialize();
            connectionPool.SetReady();

            IChannelHandle channel = null;
            Exception      exception;

            if (async)
            {
                exception = Record.Exception(() => channel = subject.GetChannelAsync(CancellationToken.None).GetAwaiter().GetResult());
            }
            else
            {
                exception = Record.Exception(() => channel = subject.GetChannel(CancellationToken.None));
            }

            channel.Should().BeNull();
            exception.Should().Be(openConnectionException);
            subject.Description.Type.Should().Be(ServerType.Unknown);
            subject.Description.ReasonChanged.Should().Contain("ChannelException during handshake");
        }
Example #3
0
        public void GetChannel_should_clear_connection_pool_when_opening_connection_throws_MongoAuthenticationException(
            [Values(false, true)] bool async)
        {
            var connectionId         = new ConnectionId(new ServerId(_clusterId, _endPoint));
            var mockConnectionHandle = new Mock <IConnectionHandle>();

            var mockConnectionPool = new Mock <IConnectionPool>();

            var mockConnectionPoolFactory = new Mock <IConnectionPoolFactory>();

            mockConnectionPoolFactory
            .Setup(f => f.CreateConnectionPool(It.IsAny <ServerId>(), _endPoint, It.IsAny <IConnectionExceptionHandler>()))
            .Returns(mockConnectionPool.Object);

            var server = new DefaultServer(
                _clusterId,
                _clusterClock,
                _clusterConnectionMode,
                _connectionModeSwitch,
                _directConnection,
                _settings,
                _endPoint,
                mockConnectionPoolFactory.Object,
                _mockServerMonitorFactory.Object,
                _capturedEvents,
                _serverApi);

            var exceptionToThrow = new MongoAuthenticationException(connectionId, "Invalid login.");

            mockConnectionPool
            .Setup(p => p.AcquireConnection(It.IsAny <CancellationToken>()))
            .Callback(() => server.HandleExceptionOnOpen(exceptionToThrow))
            .Throws(exceptionToThrow);
            mockConnectionPool
            .Setup(p => p.AcquireConnectionAsync(It.IsAny <CancellationToken>()))
            .Callback(() => server.HandleExceptionOnOpen(exceptionToThrow))
            .Throws(exceptionToThrow);
            mockConnectionPool.Setup(p => p.Clear(It.IsAny <bool>()));

            server.Initialize();

            var exception = Record.Exception(() =>
            {
                if (async)
                {
                    server.GetChannelAsync(CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    server.GetChannel(CancellationToken.None);
                }
            });

            exception.Should().BeOfType <MongoAuthenticationException>();
            mockConnectionPool.Verify(p => p.Clear(It.IsAny <bool>()), Times.Once());
        }
Example #4
0
        // private methods
        private Server SetupServer(bool exceptionOnConnectionOpen, bool exceptionOnConnectionAcquire)
        {
            var connectionId         = new ConnectionId(new ServerId(_clusterId, _endPoint));
            var mockConnectionHandle = new Mock <IConnectionHandle>();

            mockConnectionHandle
            .Setup(c => c.Fork())
            .Returns(mockConnectionHandle.Object);

            var mockConnectionPool = new Mock <IConnectionPool>();

            if (exceptionOnConnectionAcquire)
            {
                mockConnectionPool
                .Setup(p => p.AcquireConnection(It.IsAny <CancellationToken>()))
                .Throws(new TimeoutException("Timeout"));
                mockConnectionPool
                .Setup(p => p.AcquireConnectionAsync(It.IsAny <CancellationToken>()))
                .Throws(new TimeoutException("Timeout"));
                mockConnectionPool.Setup(p => p.Clear());
            }
            else if (exceptionOnConnectionOpen)
            {
                mockConnectionPool
                .Setup(p => p.AcquireConnection(It.IsAny <CancellationToken>()))
                .Throws(new MongoAuthenticationException(connectionId, "Invalid login."));
                mockConnectionPool
                .Setup(p => p.AcquireConnectionAsync(It.IsAny <CancellationToken>()))
                .Throws(new MongoAuthenticationException(connectionId, "Invalid login."));
                mockConnectionPool.Setup(p => p.Clear());
            }
            else
            {
                mockConnectionPool
                .Setup(p => p.AcquireConnection(It.IsAny <CancellationToken>()))
                .Returns(mockConnectionHandle.Object);
                mockConnectionPool
                .Setup(p => p.AcquireConnectionAsync(It.IsAny <CancellationToken>()))
                .Returns(Task.FromResult(mockConnectionHandle.Object));
                mockConnectionPool.Setup(p => p.Clear());
            }

            var mockConnectionPoolFactory = new Mock <IConnectionPoolFactory>();

            mockConnectionPoolFactory
            .Setup(f => f.CreateConnectionPool(It.IsAny <ServerId>(), _endPoint))
            .Returns(mockConnectionPool.Object);

            var server = new DefaultServer(
                _clusterId,
                _clusterClock,
                _clusterConnectionMode,
                _connectionModeSwitch,
                _directConnection,
                _settings,
                _endPoint,
                mockConnectionPoolFactory.Object,
                _mockServerMonitorFactory.Object,
                _capturedEvents,
                _serverApi);

            server.Initialize();

            return(server);
        }
Example #5
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);
            }
        }