public BinaryConnection_CommandEventTests()
        {
            _capturedEvents = new EventCapturer()
                .Capture<CommandStartedEvent>()
                .Capture<CommandSucceededEvent>()
                .Capture<CommandFailedEvent>();

            _mockStreamFactory = new Mock<IStreamFactory>();

            _endPoint = new DnsEndPoint("localhost", 27017);
            var serverId = new ServerId(new ClusterId(), _endPoint);

            _mockConnectionInitializer = new Mock<IConnectionInitializer>();
            _mockConnectionInitializer.Setup(i => i.InitializeConnectionAsync(It.IsAny<IConnection>(), CancellationToken.None))
                .Returns(() => Task.FromResult(new ConnectionDescription(
                    new ConnectionId(serverId),
                    new IsMasterResult(new BsonDocument()),
                    new BuildInfoResult(new BsonDocument("version", "2.6.3")))));

            _subject = new BinaryConnection(
                serverId: serverId,
                endPoint: _endPoint,
                settings: new ConnectionSettings(),
                streamFactory: _mockStreamFactory.Object,
                connectionInitializer: _mockConnectionInitializer.Object,
                eventSubscriber: _capturedEvents);

            _stream = new BlockingMemoryStream();
            _mockStreamFactory.Setup(f => f.CreateStreamAsync(_endPoint, CancellationToken.None))
                .Returns(Task.FromResult<Stream>(_stream));
            _subject.OpenAsync(CancellationToken.None).Wait();
            _capturedEvents.Clear();

            _operationIdDisposer = EventContext.BeginOperation();
        }
コード例 #2
0
        public void Setup()
        {
            _capturedEvents = new EventCapturer();
            _streamFactory = Substitute.For<IStreamFactory>();

            _endPoint = new DnsEndPoint("localhost", 27017);
            var serverId = new ServerId(new ClusterId(), _endPoint);

            _connectionInitializer = Substitute.For<IConnectionInitializer>();
            _connectionInitializer.InitializeConnection(null, CancellationToken.None)
                .ReturnsForAnyArgs(new ConnectionDescription(
                    new ConnectionId(serverId),
                    new IsMasterResult(new BsonDocument()),
                    new BuildInfoResult(new BsonDocument("version", "2.6.3"))));
            _connectionInitializer.InitializeConnectionAsync(null, CancellationToken.None)
                .ReturnsForAnyArgs(Task.FromResult(new ConnectionDescription(
                    new ConnectionId(serverId),
                    new IsMasterResult(new BsonDocument()),
                    new BuildInfoResult(new BsonDocument("version", "2.6.3")))));

            _subject = new BinaryConnection(
                serverId: serverId,
                endPoint: _endPoint,
                settings: new ConnectionSettings(),
                streamFactory: _streamFactory,
                connectionInitializer: _connectionInitializer,
                eventSubscriber: _capturedEvents);
        }
        public void Setup()
        {
            _capturedEvents = new EventCapturer()
                .Capture<CommandStartedEvent>()
                .Capture<CommandSucceededEvent>()
                .Capture<CommandFailedEvent>();

            _streamFactory = Substitute.For<IStreamFactory>();

            _endPoint = new DnsEndPoint("localhost", 27017);
            var serverId = new ServerId(new ClusterId(), _endPoint);

            _connectionInitializer = Substitute.For<IConnectionInitializer>();
            _connectionInitializer.InitializeConnectionAsync(null, CancellationToken.None)
                .ReturnsForAnyArgs(Task.FromResult(new ConnectionDescription(
                    new ConnectionId(serverId),
                    new IsMasterResult(new BsonDocument()),
                    new BuildInfoResult(new BsonDocument("version", "2.6.3")))));

            _subject = new BinaryConnection(
                serverId: serverId,
                endPoint: _endPoint,
                settings: new ConnectionSettings(),
                streamFactory: _streamFactory,
                connectionInitializer: _connectionInitializer,
                eventSubscriber: _capturedEvents);

            _stream = new BlockingMemoryStream();
            _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                .ReturnsForAnyArgs(Task.FromResult<Stream>(_stream));
            _subject.OpenAsync(CancellationToken.None).Wait();
            _capturedEvents.Clear();

            _operationIdDisposer = EventContext.BeginOperation();
        }
コード例 #4
0
        public BinaryConnectionTests()
        {
            _capturedEvents = new EventCapturer();
            _mockStreamFactory = new Mock<IStreamFactory>();

            _endPoint = new DnsEndPoint("localhost", 27017);
            var serverId = new ServerId(new ClusterId(), _endPoint);

            _mockConnectionInitializer = new Mock<IConnectionInitializer>();
            _mockConnectionInitializer.Setup(i => i.InitializeConnection(It.IsAny<IConnection>(), CancellationToken.None))
                .Returns(() => new ConnectionDescription(
                    new ConnectionId(serverId),
                    new IsMasterResult(new BsonDocument()),
                    new BuildInfoResult(new BsonDocument("version", "2.6.3"))));
            _mockConnectionInitializer.Setup(i => i.InitializeConnectionAsync(It.IsAny<IConnection>(), CancellationToken.None))
                .Returns(() => Task.FromResult(new ConnectionDescription(
                    new ConnectionId(serverId),
                    new IsMasterResult(new BsonDocument()),
                    new BuildInfoResult(new BsonDocument("version", "2.6.3")))));

            _subject = new BinaryConnection(
                serverId: serverId,
                endPoint: _endPoint,
                settings: new ConnectionSettings(),
                streamFactory: _mockStreamFactory.Object,
                connectionInitializer: _mockConnectionInitializer.Object,
                eventSubscriber: _capturedEvents);
        }
コード例 #5
0
 public void Setup()
 {
     _settings = new ClusterSettings(serverSelectionTimeout: TimeSpan.FromSeconds(2),
         postServerSelector: new LatencyLimitingServerSelector(TimeSpan.FromMinutes(2)));
     _serverFactory = Substitute.For<IClusterableServerFactory>();
     _capturedEvents = new EventCapturer();
 }
コード例 #6
0
        public ServerMonitorTests()
        {
            _endPoint = new DnsEndPoint("localhost", 27017);
            _serverId = new ServerId(new ClusterId(), _endPoint);
            _connection = new MockConnection();
            _mockConnectionFactory = new Mock<IConnectionFactory>();
            _mockConnectionFactory
                .Setup(f => f.CreateConnection(_serverId, _endPoint))
                .Returns(_connection);
            _capturedEvents = new EventCapturer();

            _subject = new ServerMonitor(_serverId, _endPoint, _mockConnectionFactory.Object, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan, _capturedEvents);
        }
コード例 #7
0
        public void Setup()
        {
            _endPoint = new DnsEndPoint("localhost", 27017);
            _connection = new MockConnection();
            _connectionFactory = Substitute.For<IConnectionFactory>();
            _connectionFactory.CreateConnection(null, null)
                .ReturnsForAnyArgs(_connection);

            _capturedEvents = new EventCapturer();

            _serverId = new ServerId(new ClusterId(), _endPoint);
            _subject = new ServerMonitor(_serverId, _endPoint, _connectionFactory, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan, _capturedEvents);
        }
コード例 #8
0
ファイル: ClusterTests.cs プロジェクト: RavenZZ/MDRelation
 public ClusterTests()
 {
     _settings = new ClusterSettings(serverSelectionTimeout: TimeSpan.FromSeconds(2),
         postServerSelector: new LatencyLimitingServerSelector(TimeSpan.FromMinutes(2)));
     _mockServerFactory = new Mock<IClusterableServerFactory>();
     _mockServerFactory.Setup(f => f.CreateServer(It.IsAny<ClusterId>(), It.IsAny<EndPoint>()))
         .Returns((ClusterId clusterId, EndPoint endPoint) =>
         {
             var mockServer = new Mock<IClusterableServer>();
             mockServer.SetupGet(s => s.EndPoint).Returns(endPoint);
             return mockServer.Object;
         });
     _capturedEvents = new EventCapturer();
 }
コード例 #9
0
        public void Setup()
        {
            _connectionFactory = Substitute.For<IConnectionFactory>();
            _endPoint = new DnsEndPoint("localhost", 27017);
            _capturedEvents = new EventCapturer();
            _serverId = new ServerId(new ClusterId(), _endPoint);
            _settings = new ConnectionPoolSettings(
                maintenanceInterval: Timeout.InfiniteTimeSpan,
                maxConnections: 4,
                minConnections: 2,
                waitQueueSize: 1,
                waitQueueTimeout: TimeSpan.FromSeconds(2));

            _subject = new ExclusiveConnectionPool(
                _serverId,
                _endPoint,
                _settings,
                _connectionFactory,
                _capturedEvents);
        }
コード例 #10
0
        public void Setup()
        {
            _clusterId = new ClusterId();
            _clusterConnectionMode = ClusterConnectionMode.Standalone;
            _connectionPool = Substitute.For<IConnectionPool>();
            _connectionPoolFactory = Substitute.For<IConnectionPoolFactory>();
            _connectionPoolFactory.CreateConnectionPool(null, null)
                .ReturnsForAnyArgs(_connectionPool);

            _endPoint = new DnsEndPoint("localhost", 27017);
            _heartbeatConnection = new MockConnection();
            _heartbeatConnectionFactory = Substitute.For<IConnectionFactory>();
            _heartbeatConnectionFactory.CreateConnection(null, null)
                .ReturnsForAnyArgs(_heartbeatConnection);

            _capturedEvents = new EventCapturer();
            _settings = new ServerSettings(heartbeatInterval: Timeout.InfiniteTimeSpan);

            _subject = new ClusterableServer(_clusterId, _clusterConnectionMode, _settings, _endPoint, _connectionPoolFactory, _heartbeatConnectionFactory, _capturedEvents);
        }
コード例 #11
0
        public ExclusiveConnectionPoolTests()
        {
            _mockConnectionFactory = new Mock<IConnectionFactory> { DefaultValue = DefaultValue.Mock };
            _endPoint = new DnsEndPoint("localhost", 27017);
            _capturedEvents = new EventCapturer();
            _serverId = new ServerId(new ClusterId(), _endPoint);
            _settings = new ConnectionPoolSettings(
                maintenanceInterval: Timeout.InfiniteTimeSpan,
                maxConnections: 4,
                minConnections: 2,
                waitQueueSize: 1,
                waitQueueTimeout: TimeSpan.FromSeconds(2));

            _subject = new ExclusiveConnectionPool(
                _serverId,
                _endPoint,
                _settings,
                _mockConnectionFactory.Object,
                _capturedEvents);
        }
コード例 #12
0
        public void TestFixtureSetUp()
        {
            __capturedEvents = new EventCapturer()
                .Capture<CommandStartedEvent>()
                .Capture<CommandSucceededEvent>()
                .Capture<CommandFailedEvent>();

            var settings = new MongoClientSettings
            {
                ClusterConfigurator = cb =>
                {
                    cb.Subscribe(__capturedEvents);

                    // never heartbeat...
                    cb.ConfigureServer(ss => ss.With(heartbeatInterval: Timeout.InfiniteTimeSpan));
                }
            };

            __client = new MongoClient(settings);
        }
コード例 #13
0
        public void OneTimeSetUp()
        {
            __capturedEvents = new EventCapturer()
                .Capture<CommandStartedEvent>(e => __commandsToCapture.Contains(e.CommandName))
                .Capture<CommandSucceededEvent>(e => __commandsToCapture.Contains(e.CommandName))
                .Capture<CommandFailedEvent>(e => __commandsToCapture.Contains(e.CommandName));

            var settings = new MongoClientSettings
            {
                ClusterConfigurator = cb =>
                {
                    cb = CoreTestConfiguration.ConfigureCluster(cb);
                    cb.Subscribe(__capturedEvents);

                    // never heartbeat...
                    cb.ConfigureServer(ss => ss.With(heartbeatInterval: Timeout.InfiniteTimeSpan));
                }
            };

            __client = new MongoClient(settings);
        }
コード例 #14
0
ファイル: ServerTests.cs プロジェクト: RavenZZ/MDRelation
        public ServerTests()
        {
            _clusterId = new ClusterId();
            _endPoint = new DnsEndPoint("localhost", 27017);

            _clusterConnectionMode = ClusterConnectionMode.Standalone;
            _mockConnectionPool = new Mock<IConnectionPool>();
            _mockConnectionPool.Setup(p => p.AcquireConnection(It.IsAny<CancellationToken>())).Returns(new Mock<IConnectionHandle>().Object);
            _mockConnectionPool.Setup(p => p.AcquireConnectionAsync(It.IsAny<CancellationToken>())).Returns(Task.FromResult(new Mock<IConnectionHandle>().Object));
            _mockConnectionPoolFactory = new Mock<IConnectionPoolFactory>();
            _mockConnectionPoolFactory
                .Setup(f => f.CreateConnectionPool(It.IsAny<ServerId>(), _endPoint))
                .Returns(_mockConnectionPool.Object);

            _mockServerMonitor = new Mock<IServerMonitor>();
            _mockServerMonitorFactory = new Mock<IServerMonitorFactory>();
            _mockServerMonitorFactory.Setup(f => f.Create(It.IsAny<ServerId>(), _endPoint)).Returns(_mockServerMonitor.Object);

            _capturedEvents = new EventCapturer();
            _settings = new ServerSettings(heartbeatInterval: Timeout.InfiniteTimeSpan);

            _subject = new Server(_clusterId, _clusterConnectionMode, _settings, _endPoint, _mockConnectionPoolFactory.Object, _mockServerMonitorFactory.Object, _capturedEvents);
        }
コード例 #15
0
        // private methods
        private void Run(BsonDocument shared, BsonDocument test)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(
                shared,
                "_path",
                "runOn",
                "data",
                "tests",
                "database_name",
                "collection_name",
                "bucket_name");
            JsonDrivenHelper.EnsureAllFieldsAreValid(
                test,
                "description",
                "clientOptions",
                "retryableReads",
                "failPoint",
                "operations",
                "result",
                "expectations",
                "async");

            if (shared.TryGetValue("runOn", out var runOn))
            {
                RequireServer.Check().RunOn(runOn.AsBsonArray);
            }
            if (test.TryGetValue("skipReason", out var skipReason))
            {
                throw new SkipException(skipReason.AsString);
            }

            DropCollection();
            CreateCollection();
            InsertData(shared);

            using (ConfigureFailPoint(test))
            {
                var eventCapturer = new EventCapturer()
                                    .Capture <CommandStartedEvent>(e => !__commandsToNotCapture.Contains(e.CommandName));

                Dictionary <string, BsonValue> sessionIdMap;

                using (var client = CreateDisposableClient(test, eventCapturer))
                    using (var session0 = StartSession(client, test, "session0"))
                        using (var session1 = StartSession(client, test, "session1"))
                        {
                            var objectMap = new Dictionary <string, object>
                            {
                                { "session0", session0 },
                                { "session1", session1 }
                            };
                            sessionIdMap = new Dictionary <string, BsonValue>
                            {
                                { "session0", session0.ServerSession.Id },
                                { "session1", session1.ServerSession.Id }
                            };

                            ExecuteOperations(client, objectMap, test);
                        }

                AssertEvents(eventCapturer, test, sessionIdMap);
                AssertOutcome(test);
            }
        }
コード例 #16
0
 public LoadBalancedClusterTests()
 {
     _settings          = new ClusterSettings().With(loadBalanced: true);
     _mockServerFactory = new MockClusterableServerFactory();
     _capturedEvents    = new EventCapturer();
 }
コード例 #17
0
        public async Task PoolClearedError_read_retryablity_test([Values(true, false)] bool async)
        {
            RequireServer.Check().Supports(Feature.FailPointsBlockConnection);

            var heartbeatInterval = TimeSpan.FromMilliseconds(50);
            var eventsWaitTimeout = TimeSpan.FromMilliseconds(5000);

            var failPointCommand = BsonDocument.Parse(
                $@"{{
                    configureFailPoint : 'failCommand',
                    mode : {{ 'times' : 1 }},
                    data :
                    {{
                        failCommands : [ 'find' ],
                        errorCode : 91,
                        blockConnection: true,
                        blockTimeMS: 1000
                    }}
                }}");

            IServerSelector failPointSelector = new ReadPreferenceServerSelector(ReadPreference.Primary);
            var             settings          = DriverTestConfiguration.GetClientSettings();

            if (CoreTestConfiguration.Cluster.Description.Type == Core.Clusters.ClusterType.Sharded)
            {
                var serverAddress = settings.Servers.First();
                settings.Servers = new[] { serverAddress };

                // set settings.DirectConnection = true after removing obsolete ConnectionMode
#pragma warning disable CS0618 // Type or member is obsolete
                settings.ConnectionMode = ConnectionMode.Direct;
#pragma warning restore CS0618 // Type or member is obsolete

                failPointSelector = new EndPointServerSelector(new DnsEndPoint(serverAddress.Host, serverAddress.Port));
            }

            settings.MaxConnectionPoolSize = 1;
            settings.RetryReads            = true;

            var eventCapturer = new EventCapturer()
                                .Capture <ConnectionPoolClearedEvent>()
                                .Capture <ConnectionPoolCheckedOutConnectionEvent>()
                                .Capture <ConnectionPoolCheckingOutConnectionFailedEvent>()
                                .CaptureCommandEvents("find");

            var failpointServer = DriverTestConfiguration.Client.Cluster.SelectServer(failPointSelector, default);
            using var failPoint = FailPoint.Configure(failpointServer, NoCoreSession.NewHandle(), failPointCommand);

            using var client = CreateClient(settings, eventCapturer, heartbeatInterval);
            var database   = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
            var collection = database.GetCollection <BsonDocument>(DriverTestConfiguration.CollectionNamespace.CollectionName);

            eventCapturer.Clear();

            if (async)
            {
                await ThreadingUtilities.ExecuteTasksOnNewThreads(2, async __ =>
                {
                    var cursor = await collection.FindAsync(FilterDefinition <BsonDocument> .Empty);
                    _          = await cursor.ToListAsync();
                });
            }
            else
            {
                ThreadingUtilities.ExecuteOnNewThreads(2, __ =>
                {
                    _ = collection.Find(FilterDefinition <BsonDocument> .Empty).ToList();
                });
            }

            // wait for 2 CommandSucceededEvent events, meaning that all other events should be received
            eventCapturer.WaitForOrThrowIfTimeout(
                events => events.OfType <CommandSucceededEvent>().Count() == 2,
                eventsWaitTimeout);

            eventCapturer.Events.OfType <CommandStartedEvent>().Count().Should().Be(3);
            eventCapturer.Events.OfType <CommandFailedEvent>().Count().Should().Be(1);
            eventCapturer.Events.OfType <CommandSucceededEvent>().Count().Should().Be(2);
            eventCapturer.Events.OfType <ConnectionPoolClearedEvent>().Count().Should().Be(1);
            eventCapturer.Events.OfType <ConnectionPoolCheckedOutConnectionEvent>().Count().Should().Be(3);
            eventCapturer.Events.OfType <ConnectionPoolCheckingOutConnectionFailedEvent>().Count().Should().Be(1);
        }
コード例 #18
0
        public void WriteError_details_should_expose_writeErrors_errInfo()
        {
            RequireServer.Check().VersionGreaterThanOrEqualTo(new SemanticVersion(5, 0, 0, ""));

            var eventCapturer       = new EventCapturer().Capture <CommandSucceededEvent>(e => e.CommandName == "insert");
            var collectionName      = "WriteError_details_should_expose_writeErrors_errInfo";
            var collectionValidator = BsonDocument.Parse("{ x : { $type : 'string' } }");
            var collectionOptions   = new CreateCollectionOptions <BsonDocument> {
                Validator = collectionValidator
            };

            Exception exception;

            using (var client = CreateDisposableClient(eventCapturer))
            {
                var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
                database.CreateCollection(collectionName, collectionOptions);
                var collection = database.GetCollection <BsonDocument>(collectionName);

                exception = Record.Exception(() => collection.InsertOne(new BsonDocument("x", 1)));
            }

            // Assert MongoWriteException WriteError
            exception.Should().NotBeNull();
            var mongoWriteExcepion        = exception.Should().BeOfType <MongoWriteException>().Subject;
            var writeError                = mongoWriteExcepion.WriteError;
            var objectId                  = writeError.Details["failingDocumentId"].AsObjectId;
            var expectedWriteErrorDetails = GetExpectedWriteErrorDetails(objectId);

            writeError.Code.Should().Be(121);
            writeError.Message.Should().Be("Document failed validation");
            writeError.Details.Should().BeEquivalentTo(expectedWriteErrorDetails);

            // Assert MongoBulkWriteException WriteError
            exception.InnerException.Should().NotBeNull();
            var bulkWriteException = exception.InnerException.Should().BeOfType <MongoBulkWriteException <BsonDocument> >().Subject;

            bulkWriteException.WriteErrors.Should().HaveCount(1);
            var bulkWriteWriteError = bulkWriteException.WriteErrors.Single();

            bulkWriteWriteError.Code.Should().Be(121);
            bulkWriteWriteError.Message.Should().Be("Document failed validation");
            bulkWriteWriteError.Details.Should().BeEquivalentTo(expectedWriteErrorDetails);

            // Assert exception messages
            var expectedWriteErrorMessage = GetExpectedWriteErrorMessage(expectedWriteErrorDetails.ToJson());

            mongoWriteExcepion.Message.Should().Be($"A write operation resulted in an error. WriteError: {expectedWriteErrorMessage}.");
            bulkWriteException.Message.Should().Be($"A bulk write operation resulted in one or more errors. WriteErrors: [ {expectedWriteErrorMessage} ].");

            // Assert writeErrors[0].errInfo
            eventCapturer.Events.Should().HaveCount(1);
            var commandSucceededEvent = (CommandSucceededEvent)eventCapturer.Events.Single();
            var writeErrors           = commandSucceededEvent.Reply["writeErrors"].AsBsonArray;

            writeErrors.Values.Should().HaveCount(1);
            var errorInfo = writeErrors.Values.Single()["errInfo"].AsBsonDocument;

            errorInfo.Should().BeEquivalentTo(expectedWriteErrorDetails);

            string GetExpectedWriteErrorMessage(string expectedWriteErrorDetails)
            {
                return($"{{ Category : \"Uncategorized\", Code : 121, Message : \"Document failed validation\", Details : \"{expectedWriteErrorDetails}\" }}");
            }

            BsonDocument GetExpectedWriteErrorDetails(ObjectId objectId)
            {
                return(BsonDocument.Parse($"{{ failingDocumentId : {objectId.ToJson()}, details : {{ operatorName : \"$type\", specifiedAs : {{ x : {{ $type : \"string\" }} }}, reason : \"type did not match\", consideredValue : 1, consideredType : \"int\" }} }}"));
            }
        }
コード例 #19
0
 public MultiServerClusterTests()
 {
     _settings = new ClusterSettings();
     _serverFactory = new MockClusterableServerFactory();
     _capturedEvents = new EventCapturer();
 }
コード例 #20
0
        private void Run(BsonDocument shared, BsonDocument test)
        {
            if (test.Contains("skipReason"))
            {
                throw new SkipException($"Test skipped because {test["skipReason"]}.");
            }

            if (shared.TryGetValue("topology", out var topology))
            {
                CheckClusterTopology(topology.AsBsonArray);
            }

            JsonDrivenHelper.EnsureAllFieldsAreValid(shared,
                                                     "_path",
                                                     "database_name",
                                                     "collection_name",
                                                     "data",
                                                     "tests",
                                                     "topology");
            JsonDrivenHelper.EnsureAllFieldsAreValid(test,
                                                     "description",
                                                     "clientOptions",
                                                     "failPoint",
                                                     "sessionOptions",
                                                     "operations",
                                                     "expectations",
                                                     "outcome",
                                                     "async",
                                                     "useMultipleMongoses");

            _databaseName   = shared["database_name"].AsString;
            _collectionName = shared["collection_name"].AsString;

            KillAllSessions();
            DropCollection();
            CreateCollection();
            InsertData(shared);

            if (CoreTestConfiguration.Cluster.Description.Type == ClusterType.Sharded)
            {
                PrimeShardRoutersWithDistinctCommand();
            }

            var eventCapturer = new EventCapturer()
                                .Capture <CommandStartedEvent>(e => !__commandsToNotCapture.Contains(e.CommandName));

            var useMultipleShardRouters = test.GetValue("useMultipleMongoses", false).ToBoolean();

            using (var client = CreateDisposableClient(test, eventCapturer, useMultipleShardRouters))
                using (ConfigureFailPointOnPrimaryOrShardRoutersIfNeeded(client, test))
                {
                    Dictionary <string, BsonValue> sessionIdMap;

                    using (var session0 = StartSession(client, test, "session0"))
                        using (var session1 = StartSession(client, test, "session1"))
                        {
                            var objectMap = new Dictionary <string, object>
                            {
                                { "session0", session0 },
                                { "session1", session1 }
                            };
                            sessionIdMap = new Dictionary <string, BsonValue>
                            {
                                { "session0", session0.ServerSession.Id },
                                { "session1", session1.ServerSession.Id }
                            };

                            ExecuteOperations(client, objectMap, test);
                        }

                    AssertEvents(eventCapturer, test, sessionIdMap);
                    AssertOutcome(test);
                }
        }
コード例 #21
0
 public JsonDrivenTestFactory(IMongoClient client, string databaseName, string collectionName, string bucketName, Dictionary <string, object> objectMap, EventCapturer eventCapturer)
     : this(client, databaseName, collectionName, bucketName, objectMap)
 {
     _eventCapturer = eventCapturer;
 }
コード例 #22
0
        public void Ensure_command_network_error_before_hadnshake_is_correctly_handled([Values(false, true)] bool async, [Values(false, true)] bool streamable)
        {
            var eventCapturer = new EventCapturer().Capture <ServerDescriptionChangedEvent>();

            // ensure that isMaster check response is finished only after network error
            var hasNetworkErrorBeenTriggered = new TaskCompletionSource <bool>();
            // ensure that there are no unexpected events between test ending and cluster disposing
            var hasClusterBeenDisposed = new TaskCompletionSource <bool>();

            EndPoint initialSelectedEndpoint = null;

            using (var cluster = CreateAndSetupCluster(hasNetworkErrorBeenTriggered, hasClusterBeenDisposed, eventCapturer, streamable))
            {
                ForceClusterId(cluster, __clusterId);

                // 0. Initial heartbeat via `connection.Open`
                // The next isMaster response will be delayed because the Task.WaitAny in the mock.Returns
                cluster.Initialize();

                var selectedServer = cluster.SelectServer(CreateWritableServerAndEndPointSelector(__endPoint1), CancellationToken.None);
                initialSelectedEndpoint = selectedServer.EndPoint;
                initialSelectedEndpoint.Should().Be(__endPoint1);

                // make sure the next isMaster check has been called
                Thread.Sleep(__heartbeatInterval + TimeSpan.FromMilliseconds(50));

                // 1. Trigger the command network error BEFORE handshake. At this time isMaster response is alreaady delayed until `hasNetworkErrorBeenTriggered.SetResult`
                Exception exception;
                if (async)
                {
                    exception = Record.Exception(() => selectedServer.GetChannelAsync(CancellationToken.None).GetAwaiter().GetResult());
                }
                else
                {
                    exception = Record.Exception(() => selectedServer.GetChannel(CancellationToken.None));
                }

                var e = exception.Should().BeOfType <MongoConnectionException>().Subject;
                e.Message.Should().Be("DnsException");

                // 2. Waiting for the isMaster check
                hasNetworkErrorBeenTriggered.SetResult(true); // unlock the in-progress isMaster response

                Thread.Sleep(100);                            // make sure the delayed isMaster check had time to change description if there is a bug
                var knownServers = cluster.Description.Servers.Where(s => s.Type != ServerType.Unknown);
                if (knownServers.Select(s => s.EndPoint).Contains(initialSelectedEndpoint))
                {
                    throw new Exception($"The type of failed server {initialSelectedEndpoint} has not been changed to Unknown.");
                }

                // ensure that a new server can be selected
                selectedServer = cluster.SelectServer(WritableServerSelector.Instance, CancellationToken.None);

                // ensure that the selected server is not the same as the initial
                selectedServer.EndPoint.Should().Be(__endPoint2);

                // the 4th event is MongoConnectionException which will trigger the next isMaster check immediately
                eventCapturer.WaitForOrThrowIfTimeout(events => events.Count() >= 4, TimeSpan.FromSeconds(5));
            }
            hasClusterBeenDisposed.SetCanceled(); // Cut off not related events. Stop waiting in the latest mock.Returns for OpenAsync

            // Events asserting
            var initialHeartbeatEvents = new[]
            {
                // endpoints can be in random order
                eventCapturer.Next().Should().BeOfType <ServerDescriptionChangedEvent>().Subject,
                eventCapturer.Next().Should().BeOfType <ServerDescriptionChangedEvent>().Subject
            }
            .OrderBy(c => GetPort(c.NewDescription.EndPoint))
            .ToList();

            AssertEvent(initialHeartbeatEvents[0], __endPoint1, ServerType.ShardRouter, "Heartbeat");
            AssertEvent(initialHeartbeatEvents[1], __endPoint2, ServerType.ShardRouter, "Heartbeat"); // the next 27018 events will be suppressed

            AssertNextEvent(eventCapturer, initialSelectedEndpoint, ServerType.Unknown, "InvalidatedBecause:ChannelException during handshake: MongoDB.Driver.MongoConnectionException: DnsException");
            AssertNextEvent(eventCapturer, initialSelectedEndpoint, ServerType.Unknown, "Heartbeat", typeof(MongoConnectionException));
            eventCapturer.Any().Should().BeFalse();

            int GetPort(EndPoint endpoint) => ((DnsEndPoint)endpoint).Port;
        }
コード例 #23
0
        public void Cursor_should_unpin_connection_for_operations_under_the_same_transaction_after_abortTransaction_and_cursor_dispose(
            [Values(1, 3)] int attempts,
            [Values(false, true)] bool forceCursorClose,
            [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>();

            List <IAsyncCursor <BsonDocument> > cursors = new();

            using (var cluster = CreateLoadBalancedCluster(eventCapturer))
            {
                eventCapturer.Clear();

                ICoreSessionHandle session;
                DisposableBindingBundle <IReadBindingHandle, RetryableReadContext> readBindingsBundle = null;

                using (session = CreateSession(cluster, isImplicit: false, withTransaction: true))
                {
                    for (int i = 1; i <= attempts; i++)
                    {
                        AssertSessionReferenceCount(session, i); // dynamic value because we don't close cursors in the loop

                        IAsyncCursor <BsonDocument> asyncCursor;
                        eventCapturer.Any().Should().BeFalse();
                        using (readBindingsBundle = CreateReadBindingsAndRetryableReadContext(cluster, session.Fork(), async))
                        {
                            AssertCheckOutOnlyEvents(eventCapturer, i, shouldNextAttemptTriggerCheckout: false);

                            asyncCursor = CreateAndRunFindOperation(readBindingsBundle.RetryableContext, async);

                            AssertCommand(eventCapturer, "find", noMoreEvents: true);
                        }
                        MoveNext(asyncCursor, async).Should().BeTrue(); // no op
                        MoveNext(asyncCursor, async).Should().BeTrue();

                        AssertCommand(eventCapturer, "getMore", noMoreEvents: true);

                        cursors.Add(asyncCursor);
                    }

                    AbortTransaction(session, async);
                    AssertCommand(eventCapturer, "abortTransaction", noMoreEvents: true);
                }

                for (int i = 0; i < cursors.Count; i++)
                {
                    IAsyncCursor <BsonDocument> cursor = cursors[i];
                    if (forceCursorClose)
                    {
                        cursor.Dispose();
                    }
                    else
                    {
                        var exception = Record.Exception(() => cursor.MoveNext());
                        exception
                        .Should()
                        .BeOfType <MongoCommandException>()
                        .Subject
                        .Message
                        .Should()
                        .StartWith("Command getMore failed: Cannot run getMore on cursor")
                        .And
                        .EndWith("without a txnNumber.");
                        cursor.Dispose();
                    }

                    AssertCommand(eventCapturer, "killCursors", noMoreEvents: i < cursors.Count - 1);
                }
                AssertCheckInOnlyEvents(eventCapturer);
                AssertSessionReferenceCount(session, 0);
                AssertChannelReferenceCount(readBindingsBundle.RetryableContext.Channel, 0);
            }
        }
コード例 #24
0
 public void Setup()
 {
     _settings       = new ClusterSettings();
     _serverFactory  = new MockClusterableServerFactory();
     _capturedEvents = new EventCapturer();
 }
コード例 #25
0
        private void AssertNextEvent(EventCapturer eventCapturer, EndPoint expectedEndPoint, ServerType expectedServerType, string expectedReasonStart, Type exceptionType = null)
        {
            var @event = eventCapturer.Next().Should().BeOfType <ServerDescriptionChangedEvent>().Subject;

            AssertEvent(@event, expectedEndPoint, expectedServerType, expectedReasonStart, exceptionType);
        }
 protected virtual EventCapturer InitializeEventCapturer(EventCapturer eventCapturer)
 {
     return(eventCapturer.Capture <CommandStartedEvent>(e => !DefaultCommandsToNotCapture.Contains(e.CommandName)));
 }
        protected virtual void ExecuteOperations(IMongoClient client, Dictionary <string, object> objectMap, BsonDocument test, EventCapturer eventCapturer = null)
        {
            _objectMap = objectMap;

            var factory = CreateJsonDrivenTestFactory(client, DatabaseName, CollectionName, objectMap, eventCapturer);

            foreach (var operation in test[OperationsKey].AsBsonArray.Cast <BsonDocument>())
            {
                ModifyOperationIfNeeded(operation);
                var receiver       = operation["object"].AsString;
                var name           = operation["name"].AsString;
                var jsonDrivenTest = factory.CreateTest(receiver, name);
                jsonDrivenTest.Arrange(operation);
                if (test["async"].AsBoolean)
                {
                    jsonDrivenTest.ActAsync(CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    jsonDrivenTest.Act(CancellationToken.None);
                }
                AssertOperation(jsonDrivenTest);
            }
        }
 protected virtual JsonDrivenTestFactory CreateJsonDrivenTestFactory(IMongoClient mongoClient, string databaseName, string collectionName, Dictionary <string, object> objectMap, EventCapturer eventCapturer)
 {
     return(new JsonDrivenTestFactory(mongoClient, databaseName, collectionName, bucketName: null, objectMap, eventCapturer));
 }
コード例 #29
0
        // private methods
        private ServerMonitor CreateSubject(out MockConnection connection, out Mock <IConnectionFactory> mockConnectionFactory, out Mock <IRoundTripTimeMonitor> mockRoundTripTimeMonitor, EventCapturer eventCapturer = null, bool captureConnectionEvents = false)
        {
            mockRoundTripTimeMonitor = new Mock <IRoundTripTimeMonitor>();
            mockRoundTripTimeMonitor.Setup(m => m.RunAsync()).Returns(Task.FromResult(true));

            if (captureConnectionEvents)
            {
                connection = new MockConnection(__serverId, new ConnectionSettings(), eventCapturer);
            }
            else
            {
                connection = new MockConnection();
            }
            mockConnectionFactory = new Mock <IConnectionFactory>();
            mockConnectionFactory
            .Setup(f => f.CreateConnection(__serverId, __endPoint))
            .Returns(connection);

            return(new ServerMonitor(
                       __serverId,
                       __endPoint,
                       mockConnectionFactory.Object,
                       __serverMonitorSettings,
                       eventCapturer ?? new EventCapturer(),
                       mockRoundTripTimeMonitor.Object));
        }
コード例 #30
0
        public void Cursor_should_pin_connection_in_transaction_with_new_sessions_as_expected(
            [Values(1, 3)] int attempts,
            [Values(false, true)] bool forceCursorClose,
            [Values(false)] 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 <IReadBindingHandle, RetryableReadContext> readBindingsBundle;
                    IAsyncCursor <BsonDocument> asyncCursor;

                    using (session = CreateSession(cluster, isImplicit: false, withTransaction: true))
                    {
                        AssertSessionReferenceCount(session, 1);

                        eventCapturer.Any().Should().BeFalse();
                        using (readBindingsBundle = CreateReadBindingsAndRetryableReadContext(cluster, session.Fork(), async))
                        {
                            AssertCheckOutOnlyEvents(eventCapturer, i);

                            asyncCursor = CreateAndRunFindOperation(readBindingsBundle.RetryableContext, async);

                            AssertCommand(eventCapturer, "find", noMoreEvents: true);
                        }

                        MoveNext(asyncCursor, async).Should().BeTrue(); // no op
                        MoveNext(asyncCursor, async).Should().BeTrue();

                        AssertSessionReferenceCount(session, 2);
                        AssertChannelReferenceCount(readBindingsBundle.RetryableContext.Channel, 2);
                        AssertChannelReferenceCount(asyncCursor, 2);
                        AssertCommand(eventCapturer, "getMore", noMoreEvents: true);

                        if (forceCursorClose)
                        {
                            asyncCursor.Dispose();

                            AssertCommand(eventCapturer, "killCursors", noMoreEvents: true);
                        }
                        else
                        {
                            MoveNext(asyncCursor, async).Should().BeTrue(); // cursorId = 0
                            MoveNext(asyncCursor, async).Should().BeFalse();

                            AssertCommand(eventCapturer, "getMore", noMoreEvents: true);
                        }
                    }
                    AssertCommand(eventCapturer, "abortTransaction", noMoreEvents: false);
                    AssertCheckInOnlyEvents(eventCapturer);
                    AssertSessionReferenceCount(session, 0);
                    AssertChannelReferenceCount(readBindingsBundle.RetryableContext.Channel, 0);
                }
            }
        }
 public UnifiedAssertSameLsidOnLastTwoCommandsOperation(EventCapturer eventCapturer)
 {
     _eventCapturer = eventCapturer;
 }
コード例 #32
0
        public void Command_should_use_serverApi([Values(false, true)] bool async)
        {
            RequireServer.Check().Supports(Feature.CommandMessage);

            var serverApi     = new ServerApi(ServerApiVersion.V1);
            var eventCapturer = new EventCapturer().Capture <CommandStartedEvent>(e => e.CommandName == "ping");
            var builder       = CoreTestConfiguration
                                .ConfigureCluster(new ClusterBuilder())
                                .Subscribe(eventCapturer)
                                .ConfigureCluster(x => x.With(serverApi: serverApi));

            using (var cluster = CoreTestConfiguration.CreateCluster(builder))
                using (var session = cluster.StartSession())
                {
                    var cancellationToken = CancellationToken.None;
                    var server            = (Server)cluster.SelectServer(WritableServerSelector.Instance, cancellationToken);
                    using (var channel = server.GetChannel(cancellationToken))
                    {
                        var command = BsonDocument.Parse("{ ping : 1 }");
                        if (async)
                        {
                            channel
                            .CommandAsync(
                                session,
                                ReadPreference.Primary,
                                DatabaseNamespace.Admin,
                                command,
                                null, // payloads
                                NoOpElementNameValidator.Instance,
                                null, // additionalOptions
                                null, // postWriteAction
                                CommandResponseHandling.Return,
                                BsonDocumentSerializer.Instance,
                                new MessageEncoderSettings(),
                                cancellationToken)
                            .GetAwaiter()
                            .GetResult();
                        }
                        else
                        {
                            channel.Command(
                                session,
                                ReadPreference.Primary,
                                DatabaseNamespace.Admin,
                                command,
                                null, // payloads
                                NoOpElementNameValidator.Instance,
                                null, // additionalOptions
                                null, // postWriteAction
                                CommandResponseHandling.Return,
                                BsonDocumentSerializer.Instance,
                                new MessageEncoderSettings(),
                                cancellationToken);
                        }
                    }
                }

            var commandStartedEvent = eventCapturer.Next().Should().BeOfType <CommandStartedEvent>().Subject;

            commandStartedEvent.Command["apiVersion"].AsString.Should().Be("1");
        }
コード例 #33
0
 public MultiServerClusterTests()
 {
     _settings       = new ClusterSettings();
     _serverFactory  = new MockClusterableServerFactory();
     _capturedEvents = new EventCapturer();
 }
 public UnifiedAssertNumberConnectionsCheckedOutOperation(EventCapturer eventCapturer, int?requiredConnectionNumber)
 {
     _eventCapturer            = Ensure.IsNotNull(eventCapturer, nameof(eventCapturer));
     _requiredConnectionNumber = Ensure.HasValue(requiredConnectionNumber, nameof(requiredConnectionNumber)).Value;
 }
コード例 #35
0
        public void Heartbeat_should_make_immediate_next_attempt_for_streaming_protocol(string exceptionType, bool?moreToCome)
        {
            var capturedEvents = new EventCapturer()
                                 .Capture <ServerHeartbeatSucceededEvent>()
                                 .Capture <ServerHeartbeatFailedEvent>()
                                 .Capture <ServerDescriptionChangedEvent>();
            var subject = CreateSubject(out var mockConnection, out _, out var mockRoundTimeTripMonitor, capturedEvents);

            subject.DescriptionChanged +=
                (o, e) =>
            {
                capturedEvents.TryGetEventHandler <ServerDescriptionChangedEvent>(out var eventHandler);
                eventHandler(new ServerDescriptionChangedEvent(e.OldServerDescription, e.NewServerDescription));
            };

            SetupHeartbeatConnection(mockConnection, isStreamable: true, autoFillStreamingResponses: false);

            Exception exception = null;

            switch (exceptionType)
            {
            case null:
                mockConnection.EnqueueCommandResponseMessage(CreateStreamableCommandResponseMessage(moreToCome.Value), null);
                break;

            case "MongoConnectionException":
                // previousDescription type is "Known" for this case
                mockConnection.EnqueueCommandResponseMessage(
                    exception = CoreExceptionHelper.CreateException(exceptionType));
                break;
            }

            // 10 seconds delay. Not expected to be processed
            mockConnection.EnqueueCommandResponseMessage(CreateStreamableCommandResponseMessage(), TimeSpan.FromSeconds(10));

            subject.Initialize();

            var expectedServerDescriptionChangedEventCount = exception != null
                ? 3 // +1 event because a connection initialized event doesn't have waiting
                : 2;

            capturedEvents.WaitForOrThrowIfTimeout(
                events =>
                events.Count(e => e is ServerDescriptionChangedEvent) >= expectedServerDescriptionChangedEventCount,      // the connection has been initialized and the first heatbeat event has been fired
                TimeSpan.FromSeconds(10));

            capturedEvents.Next().Should().BeOfType <ServerDescriptionChangedEvent>(); // connection initialized
            AssertHeartbeatAttempt();
            capturedEvents.Any().Should().BeFalse();                                   // the next attempt will be in 10 seconds because the second stremable respone has 10 seconds delay

            void AssertHeartbeatAttempt()
            {
                if (exception != null)
                {
                    mockRoundTimeTripMonitor.Verify(c => c.Reset(), Times.Once);

                    var serverHeartbeatFailedEvent = capturedEvents.Next().Should().BeOfType <ServerHeartbeatFailedEvent>().Subject; // updating the server based on the heartbeat
                    serverHeartbeatFailedEvent.Exception.Should().Be(exception);

                    var serverDescriptionChangedEvent = capturedEvents.Next().Should().BeOfType <ServerDescriptionChangedEvent>().Subject;
                    serverDescriptionChangedEvent.NewDescription.HeartbeatException.Should().Be(exception);

                    serverDescriptionChangedEvent = capturedEvents.Next().Should().BeOfType <ServerDescriptionChangedEvent>().Subject;  // when we catch exceptions, we close the current connection, so opening connection will trigger one more ServerDescriptionChangedEvent
                    serverDescriptionChangedEvent.OldDescription.HeartbeatException.Should().Be(exception);
                    serverDescriptionChangedEvent.NewDescription.HeartbeatException.Should().BeNull();
                }
                else
                {
                    mockRoundTimeTripMonitor.Verify(c => c.Reset(), Times.Never);
                    capturedEvents.Next().Should().BeOfType <ServerHeartbeatSucceededEvent>();
                    var serverDescriptionChangedEvent = capturedEvents.Next().Should().BeOfType <ServerDescriptionChangedEvent>().Subject; // updating the server based on the heartbeat
                    serverDescriptionChangedEvent.NewDescription.HeartbeatException.Should().BeNull();
                }
            }
        }
コード例 #36
0
        public void Connection_pool_should_not_be_cleared_when_replSetStepDown_and_GetMore([Values(false, true)] bool async)
        {
            RequireServer.Check().Supports(Feature.KeepConnectionPoolWhenReplSetStepDown).ClusterType(ClusterType.ReplicaSet);

            var eventCapturer = new EventCapturer().Capture <ConnectionPoolClearedEvent>();

            using (var client = CreateDisposableClient(eventCapturer))
            {
                var database = client.GetDatabase(_databaseName, new MongoDatabaseSettings {
                    WriteConcern = WriteConcern.WMajority
                });
                database.DropCollection(_databaseName);
                var collection = database.GetCollection <BsonDocument>(_collectionName, new MongoCollectionSettings {
                    WriteConcern = WriteConcern.WMajority
                });
                var adminDatabase = client.GetDatabase("admin").WithWriteConcern(WriteConcern.W1);

                collection.InsertMany(
                    new[]
                {
                    new BsonDocument("x", 1),
                    new BsonDocument("x", 2),
                    new BsonDocument("x", 3),
                    new BsonDocument("x", 4),
                    new BsonDocument("x", 5),
                });
                eventCapturer.Clear();

                var cursor = collection.FindSync(FilterDefinition <BsonDocument> .Empty, new FindOptions <BsonDocument> {
                    BatchSize = 2
                });
                cursor.MoveNext();

                foreach (var secondary in client.Cluster.Description.Servers.Where(c => c.Type == ServerType.ReplicaSetSecondary))
                {
                    RunOnSecondary(client, secondary.EndPoint, BsonDocument.Parse("{ replSetFreeze : 0 }"));
                }

                var          replSetStepDownCommand = BsonDocument.Parse("{ replSetStepDown : 30, force : true }");
                BsonDocument replSetStepDownResult;
                if (async)
                {
                    replSetStepDownResult = adminDatabase.RunCommandAsync <BsonDocument>(replSetStepDownCommand).GetAwaiter().GetResult();
                }
                else
                {
                    replSetStepDownResult = adminDatabase.RunCommand <BsonDocument>(replSetStepDownCommand);
                }

                replSetStepDownResult.Should().NotBeNull();
                replSetStepDownResult.GetValue("ok", false).ToBoolean().Should().BeTrue();

                cursor.MoveNext();

                eventCapturer.Events.Should().BeEmpty(); // it also means that no new PoolClearedEvent
            }

            void RunOnSecondary(IMongoClient primaryClient, EndPoint secondaryEndpoint, BsonDocument command)
            {
                var secondarySettings = primaryClient.Settings.Clone();

                secondarySettings.ClusterConfigurator = null;
#pragma warning disable CS0618 // Type or member is obsolete
                secondarySettings.ConnectionMode = ConnectionMode.Direct;
#pragma warning restore CS0618 // Type or member is obsolete
                var secondaryDnsEndpoint = (DnsEndPoint)secondaryEndpoint;
                secondarySettings.Server = new MongoServerAddress(secondaryDnsEndpoint.Host, secondaryDnsEndpoint.Port);
                using (var secondaryClient = DriverTestConfiguration.CreateDisposableClient(secondarySettings))
                {
                    var adminDatabase = secondaryClient.GetDatabase(DatabaseNamespace.Admin.DatabaseName);
                    adminDatabase.RunCommand <BsonDocument>(command);
                }
            }
        }
コード例 #37
0
        private EventCapturer CreateEventCapturer(IEnumerable <string> eventTypesToCapture, IEnumerable <string> commandNamesToSkip, IEventFormatter eventFormatter)
        {
            var eventCapturer = new EventCapturer(eventFormatter);

            foreach (var eventTypeToCapture in eventTypesToCapture)
            {
                switch (eventTypeToCapture.ToLowerInvariant())
                {
                case "commandstartedevent":
                    eventCapturer = eventCapturer.Capture <CommandStartedEvent>(x => !commandNamesToSkip.Contains(x.CommandName));
                    break;

                case "commandsucceededevent":
                    eventCapturer = eventCapturer.Capture <CommandSucceededEvent>(x => !commandNamesToSkip.Contains(x.CommandName));
                    break;

                case "commandfailedevent":
                    eventCapturer = eventCapturer.Capture <CommandFailedEvent>(x => !commandNamesToSkip.Contains(x.CommandName));
                    break;

                case "poolcreatedevent":
                    eventCapturer = eventCapturer.Capture <ConnectionPoolOpenedEvent>();
                    break;

                case "poolclearedevent":
                    eventCapturer = eventCapturer.Capture <ConnectionPoolClearedEvent>();
                    break;

                case "poolclosedevent":
                    eventCapturer = eventCapturer.Capture <ConnectionPoolClosedEvent>();
                    break;

                case "connectioncreatedevent":
                    eventCapturer = eventCapturer.Capture <ConnectionCreatedEvent>();
                    break;

                case "connectionclosedevent":
                    eventCapturer = eventCapturer.Capture <ConnectionClosedEvent>();
                    break;

                case "connectionreadyevent":
                    eventCapturer = eventCapturer.Capture <ConnectionOpenedEvent>();
                    break;

                case "connectioncheckoutstartedevent":
                    eventCapturer = eventCapturer.Capture <ConnectionPoolCheckingOutConnectionEvent>();
                    break;

                case "connectioncheckoutfailedevent":
                    eventCapturer = eventCapturer.Capture <ConnectionPoolCheckingOutConnectionFailedEvent>();
                    break;

                case "connectioncheckedoutevent":
                    eventCapturer = eventCapturer.Capture <ConnectionPoolCheckedOutConnectionEvent>();
                    break;

                case "connectioncheckedinevent":
                    eventCapturer = eventCapturer.Capture <ConnectionPoolCheckedInConnectionEvent>();
                    break;

                case "poolreadyevent":
                    // should be handled in the scope of CSHARP-3509
                    break;

                default:
                    throw new FormatException($"Invalid event name: {eventTypeToCapture}.");
                }
            }

            return(eventCapturer);
        }
コード例 #38
0
        public void BulkWrite_and_cursor_should_share_pinned_connection_under_the_same_transaction_2(
            [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();

                ICoreSessionHandle session;
                DisposableBindingBundle <IReadWriteBindingHandle, RetryableWriteContext> writeBindingsBundle;
                DisposableBindingBundle <IReadBindingHandle, RetryableReadContext>       readBindingsBundle;
                IAsyncCursor <BsonDocument> asyncCursor;

                using (session = CreateSession(cluster, isImplicit: false, withTransaction: true))
                {
                    AssertSessionReferenceCount(session, 1);

                    eventCapturer.Any().Should().BeFalse();

                    // bulk operation
                    using (writeBindingsBundle = CreateReadWriteBindingsAndRetryableWriteContext(cluster, session.Fork(), async))
                    {
                        AssertCheckOutOnlyEvents(eventCapturer, 1);

                        _ = CreateAndRunBulkOperation(writeBindingsBundle.RetryableContext, async);

                        AssertCommand(eventCapturer, "insert", noMoreEvents: true);
                    }
                    AssertSessionReferenceCount(session, 1);

                    // find operation
                    using (readBindingsBundle = CreateReadBindingsAndRetryableReadContext(cluster, session.Fork(), async))
                    {
                        eventCapturer.Any().Should().BeFalse();

                        asyncCursor = CreateAndRunFindOperation(readBindingsBundle.RetryableContext, async);

                        AssertCommand(eventCapturer, "find", noMoreEvents: true);
                    }
                }

                MoveNext(asyncCursor, async).Should().BeTrue(); // no op
                MoveNext(asyncCursor, async).Should().BeTrue(); // getMore
                AssertCommand(eventCapturer, "getMore", noMoreEvents: true);
                MoveNext(asyncCursor, async).Should().BeTrue(); // getMore
                AssertCommand(eventCapturer, "getMore", noMoreEvents: true);
                MoveNext(asyncCursor, async).Should().BeTrue(); // cursorId = 0
                AssertCommand(eventCapturer, "getMore", noMoreEvents: false);
                AssertCommand(eventCapturer, "abortTransaction", noMoreEvents: false);
                AssertCheckInOnlyEvents(eventCapturer);
                MoveNext(asyncCursor, async).Should().BeFalse();

                AssertChannelReferenceCount(readBindingsBundle.RetryableContext.Channel, 0);
                AssertChannelReferenceCount(writeBindingsBundle.RetryableContext.Channel, 0);
                AssertSessionReferenceCount(session, 0);
            }
        }
コード例 #39
0
 private void AssertCheckOutOnlyEvents(EventCapturer eventCapturer, int attempt, bool shouldNextAttemptTriggerCheckout = true)
 {
     AssertCheckOutOnlyEvents(eventCapturer, attempt, shouldHelloBeCalled: attempt == 1, shouldNextAttemptTriggerCheckout);
 }
コード例 #40
0
        public void BsonSizeLimitAndBatchSizeSplittingTest(
            [Values(false, true)] bool async)
        {
            RequireServer.Check().Supports(Feature.ClientSideEncryption);

            var eventCapturer = new EventCapturer().Capture <CommandStartedEvent>(e => e.CommandName == "insert");

            using (var client = ConfigureClient())
                using (var clientEncrypted = ConfigureClientEncrypted(kmsProviderFilter: "local", eventCapturer: eventCapturer))
                {
                    var collLimitSchema = JsonFileReader.Instance.Documents["limits.limits-schema.json"];
                    CreateCollection(client, __collCollectionNamespace, new BsonDocument("$jsonSchema", collLimitSchema));
                    var datakeysLimitsKey  = JsonFileReader.Instance.Documents["limits.limits-key.json"];
                    var keyVaultCollection = GetCollection(client, __keyVaultCollectionNamespace);
                    Insert(keyVaultCollection, async, datakeysLimitsKey);

                    var coll = GetCollection(clientEncrypted, __collCollectionNamespace);

                    var exception = Record.Exception(
                        () => Insert(
                            coll,
                            async,
                            new BsonDocument
                    {
                        { "_id", "over_2mib_under_16mib" },
                        { "unencrypted", new string('a', 2097152) }
                    }));
                    exception.Should().BeNull();
                    eventCapturer.Clear();

                    var limitsDoc = JsonFileReader.Instance.Documents["limits.limits-doc.json"];
                    limitsDoc.AddRange(
                        new BsonDocument
                    {
                        { "_id", "encryption_exceeds_2mib" },
                        { "unencrypted", new string('a', 2097152 - 2000) }
                    });
                    exception = Record.Exception(
                        () => Insert(
                            coll,
                            async,
                            limitsDoc));
                    exception.Should().BeNull();
                    eventCapturer.Clear();

                    exception = Record.Exception(
                        () => Insert(
                            coll,
                            async,
                            new BsonDocument
                    {
                        { "_id", "over_2mib_1" },
                        { "unencrypted", new string('a', 2097152) }
                    },
                            new BsonDocument
                    {
                        { "_id", "over_2mib_2" },
                        { "unencrypted", new string('a', 2097152) }
                    }));
                    exception.Should().BeNull();
                    eventCapturer.Count.Should().Be(2);
                    eventCapturer.Clear();

                    var limitsDoc1 = JsonFileReader.Instance.Documents["limits.limits-doc.json"];
                    limitsDoc1.AddRange(
                        new BsonDocument
                    {
                        { "_id", "encryption_exceeds_2mib_1" },
                        { "unencrypted", new string('a', 2097152 - 2000) }
                    });
                    var limitsDoc2 = JsonFileReader.Instance.Documents["limits.limits-doc.json"];
                    limitsDoc2.AddRange(
                        new BsonDocument
                    {
                        { "_id", "encryption_exceeds_2mib_2" },
                        { "unencrypted", new string('a', 2097152 - 2000) }
                    });

                    exception = Record.Exception(
                        () => Insert(
                            coll,
                            async,
                            limitsDoc1,
                            limitsDoc2));
                    exception.Should().BeNull();
                    eventCapturer.Count.Should().Be(2);
                    eventCapturer.Clear();

                    exception = Record.Exception(
                        () => Insert(
                            coll,
                            async,
                            new BsonDocument
                    {
                        { "_id", "under_16mib" },
                        { "unencrypted", new string('a', 16777216 - 2000) }
                    }));
                    exception.Should().BeNull();
                    eventCapturer.Clear();

                    limitsDoc = JsonFileReader.Instance.Documents["limits.limits-doc.json"];
                    limitsDoc.AddRange(
                        new BsonDocument
                    {
                        { "_id", "encryption_exceeds_16mib" },
                        { "unencrypted", new string('a', 16777216 - 2000) }
                    });
                    exception = Record.Exception(
                        () => Insert(
                            coll,
                            async,
                            limitsDoc));
                    exception.Should().NotBeNull();
                    eventCapturer.Clear();

                    // additional not spec tests
                    exception = Record.Exception(
                        () => Insert(
                            coll,
                            async,
                            new BsonDocument
                    {
                        { "_id", "advanced_over_2mib_1" },
                        { "unencrypted", new string('a', 2097152) }
                    },
                            new BsonDocument
                    {
                        { "_id", "advanced_over_2mib_2" },
                        { "unencrypted", new string('a', 2097152) }
                    },
                            new BsonDocument
                    {
                        { "_id", "advanced_over_2mib_3" },
                        { "unencrypted", new string('a', 2097152) }
                    }));
                    exception.Should().BeNull();
                    eventCapturer.Count.Should().Be(3);
                    eventCapturer.Clear();

                    exception = Record.Exception(
                        () => Insert(
                            coll,
                            async,
                            new BsonDocument
                    {
                        { "_id", "small_1" },
                        { "unencrypted", "a" }
                    },
                            new BsonDocument
                    {
                        { "_id", "small_2" },
                        { "unencrypted", "a" }
                    },
                            new BsonDocument
                    {
                        { "_id", "small_3" },
                        { "unencrypted", "a" }
                    }));
                    exception.Should().BeNull();
                    eventCapturer.Count.Should().Be(1);
                    eventCapturer.Clear();
                }
        }
コード例 #41
0
 private DisposableMongoClient GetClient(EventCapturer capturer)
 {
     return(DriverTestConfiguration.CreateDisposableClient(capturer));
 }
コード例 #42
0
 private void AssertCommand(EventCapturer eventCapturer, string commandName, bool noMoreEvents)
 {
     eventCapturer.Next().Should().BeOfType <CommandSucceededEvent>().Subject.CommandName.Should().Be(commandName);
     eventCapturer.Any().Should().Be(!noMoreEvents);
 }
コード例 #43
0
        // private methods
        private DisposableMongoClient CreateClient(MongoClientSettings mongoClientSettings, EventCapturer eventCapturer, TimeSpan heartbeatInterval, string applicationName = null)
        {
            var clonedClientSettings = mongoClientSettings ?? DriverTestConfiguration.Client.Settings.Clone();

            clonedClientSettings.ApplicationName     = applicationName;
            clonedClientSettings.HeartbeatInterval   = heartbeatInterval;
            clonedClientSettings.ClusterConfigurator = builder => builder.Subscribe(eventCapturer);

            return(DriverTestConfiguration.CreateDisposableClient(clonedClientSettings));
        }
コード例 #44
0
 private void AssertCheckInOnlyEvents(EventCapturer eventCapturer)
 {
     eventCapturer.Next().Should().BeOfType <ConnectionPoolCheckingInConnectionEvent>();
     eventCapturer.Next().Should().BeOfType <ConnectionPoolCheckedInConnectionEvent>();
     eventCapturer.Any().Should().BeFalse();
 }
コード例 #45
0
 public void Setup()
 {
     _settings = new ClusterSettings();
     _serverFactory = new MockClusterableServerFactory();
     _capturedEvents = new EventCapturer();
 }
コード例 #46
0
 private DisposableMongoClient GetClient(EventCapturer capturer)
 {
     return(GetClient(cb => cb.Subscribe(capturer)));
 }