예제 #1
0
        public void Command_should_update_the_session_and_cluster_cluster_times()
        {
            RequireServer.Check().VersionGreaterThanOrEqualTo("3.6").ClusterTypes(ClusterType.ReplicaSet, ClusterType.Sharded);

            var eventCapturer = new EventCapturer().Capture <CommandSucceededEvent>(e => e.CommandName == "ping");

            using (var cluster = CoreTestConfiguration.CreateCluster(b => b.Subscribe(eventCapturer)))
                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 }");
                        channel.Command <BsonDocument>(
                            session,
                            ReadPreference.Primary,
                            DatabaseNamespace.Admin,
                            command,
                            null, // payloads
                            NoOpElementNameValidator.Instance,
                            null, // additionalOptions
                            null, // postWriteAction
                            CommandResponseHandling.Return,
                            BsonDocumentSerializer.Instance,
                            new MessageEncoderSettings(),
                            cancellationToken);
                    }

                    var commandSucceededEvent = eventCapturer.Next().Should().BeOfType <CommandSucceededEvent>().Subject;
                    var actualReply           = commandSucceededEvent.Reply;
                    var actualClusterTime     = actualReply["$clusterTime"].AsBsonDocument;
                    session.ClusterTime.Should().Be(actualClusterTime);
                    server.ClusterClock.ClusterTime.Should().Be(actualClusterTime);
                }
        }
예제 #2
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");
        }
        private (IConnectionPool, FailPoint, ICluster, Func <object, bool>) SetupConnectionData(BsonDocument test, EventCapturer eventCapturer, bool isUnit)
        {
            ParseSettings(test, out var connectionPoolSettings, out var connectionSettings);

            IConnectionPool     connectionPool;
            ICluster            cluster      = null;
            FailPoint           failPoint    = null;
            Func <object, bool> eventsFilter = _ => true;

            if (isUnit)
            {
                var endPoint = new DnsEndPoint("localhost", 27017);
                var serverId = new ServerId(new ClusterId(), endPoint);

                var connectionFactory          = new Mock <IConnectionFactory>();
                var connectionExceptionHandler = new Mock <IConnectionExceptionHandler>();

                connectionFactory
                .Setup(c => c.CreateConnection(serverId, endPoint))
                .Returns(() =>
                {
                    var connection = new MockConnection(serverId, connectionSettings, eventCapturer);
                    return(connection);
                });

                connectionPool = new ExclusiveConnectionPool(
                    serverId,
                    endPoint,
                    connectionPoolSettings,
                    connectionFactory.Object,
                    eventCapturer,
                    connectionExceptionHandler.Object);

                connectionPool.Initialize();
            }
            else
            {
                var async = test.GetValue(Schema.async).ToBoolean();
                cluster = CoreTestConfiguration.CreateCluster(b => b
                                                              .ConfigureServer(s => s.With(
                                                                                   heartbeatInterval: TimeSpan.FromMinutes(10)))
                                                              .ConfigureConnectionPool(c => c.With(
                                                                                           maxConnecting: connectionPoolSettings.MaxConnecting,
                                                                                           maxConnections: connectionPoolSettings.MaxConnections,
                                                                                           minConnections: connectionPoolSettings.MinConnections,
                                                                                           maintenanceInterval: connectionPoolSettings.MaintenanceInterval,
                                                                                           waitQueueTimeout: connectionPoolSettings.WaitQueueTimeout))
                                                              .ConfigureConnection(s => s.With(applicationName: $"{connectionSettings.ApplicationName}_async_{async}"))
                                                              .Subscribe(eventCapturer));

                var server = cluster.SelectServer(WritableServerSelector.Instance, CancellationToken.None);
                connectionPool = server._connectionPool();

                if (test.TryGetValue(Schema.Intergration.failPoint, out var failPointDocument))
                {
                    if (failPointDocument.AsBsonDocument.Contains("data"))
                    {
                        var data = failPointDocument["data"].AsBsonDocument;
                        if (data.TryGetValue("appName", out var appNameValue))
                        {
                            data["appName"] = $"{appNameValue}_async_{async}";
                        }
                    }

                    var resetPool = connectionPoolSettings.MinConnections > 0;

                    if (resetPool)
                    {
                        eventCapturer.WaitForOrThrowIfTimeout(events => events.Any(e => e is ConnectionCreatedEvent), TimeSpan.FromMilliseconds(500));

                        var connectionIdsToIgnore = new HashSet <int>(eventCapturer.Events
                                                                      .OfType <ConnectionCreatedEvent>()
                                                                      .Select(c => c.ConnectionId.LocalValue)
                                                                      .ToList());

                        eventsFilter = o =>
                        {
                            if (o is ConnectionOpenedEvent
                                or ConnectionClosedEvent
                                or ConnectionCreatedEvent
                                or ConnectionFailedEvent)
                            {
                                var connectionId = o.ConnectionId();
                                return(!connectionIdsToIgnore.Contains(connectionId.LocalValue) &&
                                       EndPointHelper.Equals(connectionId.ServerId.EndPoint, server.EndPoint));
                            }

                            if (o is ConnectionPoolReadyEvent
                                or ConnectionPoolClearedEvent)
                            {
                                var serverId = o.ServerId();
                                return(EndPointHelper.Equals(serverId.EndPoint, server.EndPoint));
                            }

                            return(true);
                        };

                        connectionPool.Clear(closeInUseConnections: false);
                        eventCapturer.WaitForOrThrowIfTimeout(events => events.Any(e => e is ConnectionPoolClearedEvent), TimeSpan.FromMilliseconds(500));
                    }

                    var failPointServer = CoreTestConfiguration.Cluster.SelectServer(new EndPointServerSelector(server.EndPoint), default);
                    failPoint = FailPoint.Configure(failPointServer, NoCoreSession.NewHandle(), failPointDocument.AsBsonDocument);

                    if (resetPool)
                    {
                        eventCapturer.Clear();
                        connectionPool.SetReady();
                    }
                }
            }

            return(connectionPool, failPoint, cluster, eventsFilter);
        }