Exemple #1
0
 private void AssertAuthenticationSucceeds(
     MongoClientSettings settings,
     bool async,
     bool speculativeAuthenticatationShouldSucceedIfPossible = true)
 {
     // If we don't use a DisposableClient, the second run of AuthenticationSucceedsWithMongoDB_X509_mechanism
     // will fail because the backing Cluster's connections will be associated with a dropped user
     using (var client = DriverTestConfiguration.CreateDisposableclient(settings))
     {
         // The first command executed with the MongoClient triggers either the sync or async variation of the
         // MongoClient's IAuthenticator
         if (async)
         {
             _ = client.ListDatabaseNamesAsync().GetAwaiter().GetResult().ToList();
         }
         else
         {
             _ = client.ListDatabaseNames().ToList();
         }
         if (Feature.SpeculativeAuthentication.IsSupported(CoreTestConfiguration.ServerVersion) &&
             speculativeAuthenticatationShouldSucceedIfPossible)
         {
             var cancellationToken = CancellationToken.None;
             var serverSelector    = new ReadPreferenceServerSelector(settings.ReadPreference);
             var server            = client.Cluster.SelectServer(serverSelector, cancellationToken);
             var channel           = server.GetChannel(cancellationToken);
             var isMasterResult    = channel.ConnectionDescription.IsMasterResult;
             isMasterResult.SpeculativeAuthenticate.Should().NotBeNull();
         }
     }
 }
Exemple #2
0
        /// <summary>
        /// Connects to the server. Normally there is no need to call this method as
        /// the driver will connect to the server automatically when needed.
        /// </summary>
        /// <param name="timeout">How long to wait before timing out.</param>
        public virtual void Connect(TimeSpan timeout)
        {
            var readPreference = _settings.ReadPreference;
            var readPreferenceServerSelector = new ReadPreferenceServerSelector(readPreference);

            _cluster.SelectServerAsync(readPreferenceServerSelector, timeout, CancellationToken.None).GetAwaiter().GetResult();
        }
Exemple #3
0
        public void RunTestDefinition(JsonDrivenTestCase testCase)
        {
            var testDefinition     = testCase.Test;
            var testData           = BsonSerializer.Deserialize <TestData>(testDefinition);
            var clusterDescription = ServerSelectionTestHelper.BuildClusterDescription(testData.topology_description);

            using var cluster = CreateAndSetupCluster(clusterDescription, testData.mocked_topology_state);
            var readPreferenceSelector = new ReadPreferenceServerSelector(ReadPreference.Nearest);

            var selectionHistogram = testData.outcome.expected_frequencies.Keys
                                     .ToDictionary(s => clusterDescription.Servers.Single(d => d.EndPoint.ToString().EndsWith(s)).ServerId, s => 0);
            var selectionFrequenciesExpected = testData.outcome.expected_frequencies.
                                               ToDictionary(s => clusterDescription.Servers.Single(d => d.EndPoint.ToString().EndsWith(s.Key)).ServerId, s => s.Value);

            for (int i = 0; i < testData.iterations; i++)
            {
                var selectedServer = testData.async
                    ? cluster.SelectServerAsync(readPreferenceSelector, default).GetAwaiter().GetResult()
                    : cluster.SelectServer(readPreferenceSelector, default);

                selectionHistogram[selectedServer.ServerId]++;
            }

            foreach (var pair in selectionHistogram)
            {
                var expectedFrequency = selectionFrequenciesExpected[pair.Key];
                var actualFrequency   = pair.Value / (double)testData.iterations;

                actualFrequency.Should().BeInRange(expectedFrequency - testData.outcome.tolerance, expectedFrequency + testData.outcome.tolerance);
            }
        }
Exemple #4
0
        private IReadBindingHandle GetSingleServerReadBinding(CancellationToken cancellationToken)
        {
            var readPreference = _options.ReadPreference ?? _database.Settings.ReadPreference;
            var selector       = new ReadPreferenceServerSelector(readPreference);
            var server         = _cluster.SelectServer(selector, cancellationToken);
            var binding        = new SingleServerReadBinding(server, readPreference, NoCoreSession.NewHandle());

            return(new ReadBindingHandle(binding));
        }
        /// <summary>
        /// Connects to the server. Normally there is no need to call this method as
        /// the driver will connect to the server automatically when needed.
        /// </summary>
        /// <param name="timeout">How long to wait before timing out.</param>
        public virtual void Connect(TimeSpan timeout)
        {
            var readPreference = _settings.ReadPreference;
            var readPreferenceServerSelector = new ReadPreferenceServerSelector(readPreference);

            using (var timeoutCancellationTokenSource = new CancellationTokenSource(timeout))
            {
                _cluster.SelectServer(readPreferenceServerSelector, timeoutCancellationTokenSource.Token);
            }
        }
Exemple #6
0
        private async Task <IReadBindingHandle> GetSingleServerReadBindingAsync(CancellationToken cancellationToken)
        {
            var readPreference = _options.ReadPreference ?? _database.Settings.ReadPreference;
            var selector       = new ReadPreferenceServerSelector(readPreference);
            var server         = await _cluster.SelectServerAsync(selector, cancellationToken).ConfigureAwait(false);

            var binding = new SingleServerReadBinding(server, readPreference, NoCoreSession.NewHandle());

            return(new ReadBindingHandle(binding));
        }
        private static bool IsReplicaSet(string uri)
        {
            var clusterBuilder = new ClusterBuilder();

            clusterBuilder.ConfigureWithConnectionString(uri);

            using (var cluster = clusterBuilder.BuildCluster())
            {
                cluster.Initialize();

                var serverSelector = new ReadPreferenceServerSelector(ReadPreference.PrimaryPreferred);
                var server         = cluster.SelectServer(serverSelector, CancellationToken.None);
                return(server.Description.Type.IsReplicaSetMember());
            }
        }
        public void RunTestDefinition(JsonDrivenTestCase testCase)
        {
            var definition = testCase.Test;

            JsonDrivenHelper.EnsureAllFieldsAreValid(definition, "_path", "in_latency_window", "operation", "read_preference", "suitable_servers", "topology_description", "heartbeatFrequencyMS", "error");

            var error              = definition.GetValue("error", false).ToBoolean();
            var heartbeatInterval  = TimeSpan.FromMilliseconds(definition.GetValue("heartbeatFrequencyMS", 10000).ToInt64());
            var clusterDescription = ServerSelectionTestHelper.BuildClusterDescription((BsonDocument)definition["topology_description"], heartbeatInterval);

            IServerSelector selector;

            if (definition.GetValue("operation", "read").AsString == "write")
            {
                selector = WritableServerSelector.Instance;
            }
            else
            {
                ReadPreference readPreference;
                try
                {
                    readPreference = BuildReadPreference(definition["read_preference"].AsBsonDocument);
                }
                catch
                {
                    if (error)
                    {
                        return;
                    }
                    throw;
                }

                selector = new ReadPreferenceServerSelector(readPreference);
            }

            if (error)
            {
                RunErrorTest(clusterDescription, selector);
            }
            else
            {
                RunNonErrorTest(definition, clusterDescription, selector, heartbeatInterval);
            }
        }
        public void RunTestDefinition(BsonDocument definition)
        {
            var             error              = definition.GetValue("error", false).ToBoolean();
            var             heartbeatInterval  = TimeSpan.FromMilliseconds(definition.GetValue("heartbeatFrequencyMS", 10000).ToInt64());
            var             clusterDescription = BuildClusterDescription((BsonDocument)definition["topology_description"], heartbeatInterval);
            IServerSelector selector;

            if (definition.GetValue("operation", "read").AsString == "write")
            {
                selector = WritableServerSelector.Instance;
            }
            else
            {
                ReadPreference readPreference;
                try
                {
                    readPreference = BuildReadPreference(definition["read_preference"].AsBsonDocument);
                }
                catch
                {
                    if (error)
                    {
                        return;
                    }
                    throw;
                }

                selector = new ReadPreferenceServerSelector(readPreference);
            }

            if (error)
            {
                RunErrorTest(clusterDescription, selector);
            }
            else
            {
                RunNonErrorTest(definition, clusterDescription, selector, heartbeatInterval);
            }
        }
        /// <summary>
        /// Lets the server know that this thread is about to begin a series of related operations that must all occur
        /// on the same connection. The return value of this method implements IDisposable and can be placed in a
        /// using statement (in which case RequestDone will be called automatically when leaving the using statement).
        /// </summary>
        /// <param name="readPreference">The read preference.</param>
        /// <returns>A helper object that implements IDisposable and calls <see cref="RequestDone"/> from the Dispose method.</returns>
        internal virtual IDisposable RequestStart(ReadPreference readPreference)
        {
            var serverSelector = new ReadPreferenceServerSelector(readPreference);

            return(RequestStart(serverSelector, readPreference));
        }
Exemple #11
0
        /// <summary>
        /// Lets the server know that this thread is about to begin a series of related operations that must all occur
        /// on the same connection. The return value of this method implements IDisposable and can be placed in a
        /// using statement (in which case RequestDone will be called automatically when leaving the using statement).
        /// </summary>
        /// <param name="initialDatabase">One of the databases involved in the related operations.</param>
        /// <param name="readPreference">The read preference.</param>
        /// <returns>A helper object that implements IDisposable and calls <see cref="RequestDone"/> from the Dispose method.</returns>
        public virtual IDisposable RequestStart(MongoDatabase initialDatabase, ReadPreference readPreference)
        {
            var serverSelector = new ReadPreferenceServerSelector(readPreference);

            return(RequestStart(serverSelector, readPreference));
        }
Exemple #12
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);
        }