コード例 #1
0
        private void ExecuteOperation(IMongoClient client, IMongoDatabase database, IMongoCollection <BsonDocument> collection, BsonDocument operation, BsonDocument outcome, bool async)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(operation, "name", "object", "collectionOptions", "arguments", "error", "result");

            if (operation.TryGetValue("object", out var @object))
            {
                if (@object.AsString == "database")
                {
                    collection = null;
                }
            }

            var  name            = (string)operation["name"];
            var  test            = CrudOperationTestFactory.CreateTest(name);
            bool isErrorExpected = operation.GetValue("error", false).AsBoolean;

            var arguments = (BsonDocument)operation.GetValue("arguments", new BsonDocument());

            test.SkipIfNotSupported(arguments);
            if (operation.TryGetValue("result", out var result))
            {
                outcome           = outcome ?? new BsonDocument();
                outcome["result"] = result;
            }

            test.Execute(client.Cluster.Description, database, collection, arguments, outcome, isErrorExpected, async);

            var threwException = test.ActualException != null;

            if (isErrorExpected && !threwException)
            {
                throw new Exception("The test was expected to throw an exception, but no exception was thrown.");
            }
        }
コード例 #2
0
        private void AssertError(Exception actualException, BsonDocument expectedResult)
        {
            if (actualException == null)
            {
                throw new Exception("Expected an exception to be thrown but none was.");
            }

            var actualMongoCommandException = actualException as MongoCommandException;

            if (actualMongoCommandException == null)
            {
                throw new Exception($"Expected a MongoCommandException to be thrown but instead a ${actualException.GetType().Name} was.");
            }

            JsonDrivenHelper.EnsureAllFieldsAreValid(expectedResult, "error");
            var expectedError = expectedResult["error"].AsBsonDocument;

            JsonDrivenHelper.EnsureAllFieldsAreValid(expectedError, "code", "errorLabels");
            var code = expectedError["code"].ToInt32();

            actualMongoCommandException.Code.Should().Be(code);

            if (expectedError.TryGetValue("errorLabels", out var expectedLabels))
            {
                foreach (var expectedLabel in expectedLabels.AsBsonArray)
                {
                    actualMongoCommandException.HasErrorLabel(expectedLabel.ToString()).Should().BeTrue();
                }
            }
        }
コード例 #3
0
        private void ParseDatabaseOptions(BsonDocument document)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(document, "readConcern", "readPreference", "writeConcern");

            var database = _collection.Database;

            if (document.Contains("readConcern"))
            {
                var readConcern = ReadConcern.FromBsonDocument(document["readConcern"].AsBsonDocument);
                database = database.WithReadConcern(readConcern);
            }

            if (document.Contains("readPreference"))
            {
                var readPreference = ReadPreference.FromBsonDocument(document["readPreference"].AsBsonDocument);
                database = database.WithReadPreference(readPreference);
            }

            if (document.Contains("writeConcern"))
            {
                var writeConcern = WriteConcern.FromBsonDocument(document["writeConcern"].AsBsonDocument);
                database = database.WithWriteConcern(writeConcern);
            }

            // update _collection to be associated with the reconfigured database
            _collection = database.GetCollection <BsonDocument>(
                _collection.CollectionNamespace.CollectionName,
                _collection.Settings);
        }
コード例 #4
0
        private void AssertValid(ConnectionString connectionString, BsonDocument definition)
        {
            if (!definition["valid"].ToBoolean())
            {
                throw new AssertionException($"The connection string '{definition["uri"]}' should be invalid.");
            }

            var hostsValue = definition["hosts"] as BsonArray;

            if (hostsValue != null)
            {
                var expectedEndPoints = hostsValue
                                        .Select(x => ConvertExpectedHostToEndPoint((BsonDocument)x))
                                        .ToList();

                var missing = expectedEndPoints.Except(connectionString.Hosts, EndPointHelper.EndPointEqualityComparer);
                missing.Any().Should().Be(false);

                var additions = connectionString.Hosts.Except(expectedEndPoints, EndPointHelper.EndPointEqualityComparer);
                additions.Any().Should().Be(false);
            }

            var authValue = definition["auth"] as BsonDocument;

            if (authValue != null)
            {
                JsonDrivenHelper.EnsureAllFieldsAreValid(authValue, "db", "username", "password");

                connectionString.DatabaseName.Should().Be(ValueToString(authValue["db"]));
                connectionString.Username.Should().Be(ValueToString(authValue["username"]));
                connectionString.Password.Should().Be(ValueToString(authValue["password"]));
            }

            AssertOptions(connectionString, definition);
        }
コード例 #5
0
        private void ApplyPhase(BsonDocument phase)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(phase, "applicationErrors", "description", "outcome", "responses");

            if (phase.Contains("responses"))
            {
                var responses = phase["responses"].AsBsonArray;
                foreach (BsonArray response in responses)
                {
                    ApplyResponse(response);
                }
            }

            if (phase.TryGetValue("applicationErrors", out var applicationErrors))
            {
                foreach (BsonDocument applicationError in applicationErrors.AsBsonArray)
                {
                    ApplyApplicationError(applicationError);
                }
            }

            var outcome     = (BsonDocument)phase["outcome"];
            var description = (string)phase.GetValue("description", defaultValue: null);

            VerifyOutcome(outcome, description);
        }
コード例 #6
0
        private void ApplyResponse(BsonArray response)
        {
            if (response.Count != 2)
            {
                throw new FormatException($"Invalid response count: {response.Count}.");
            }

            var address          = response[0].AsString;
            var isMasterDocument = response[1].AsBsonDocument;

            JsonDrivenHelper.EnsureAllFieldsAreValid(isMasterDocument, "hosts", "ismaster", "maxWireVersion", "minWireVersion", "ok", "primary", "secondary", "setName", "setVersion");

            var endPoint                 = EndPointHelper.Parse(address);
            var isMasterResult           = new IsMasterResult(isMasterDocument);
            var currentServerDescription = _serverFactory.GetServerDescription(endPoint);
            var newServerDescription     = currentServerDescription.With(
                canonicalEndPoint: isMasterResult.Me,
                electionId: isMasterResult.ElectionId,
                replicaSetConfig: isMasterResult.GetReplicaSetConfig(),
                state: isMasterResult.Wrapped.GetValue("ok", false).ToBoolean() ? ServerState.Connected : ServerState.Disconnected,
                type: isMasterResult.ServerType,
                wireVersionRange: new Range <int>(isMasterResult.MinWireVersion, isMasterResult.MaxWireVersion));

            var currentClusterDescription = _cluster.Description;

            _serverFactory.PublishDescription(newServerDescription);
            SpinWait.SpinUntil(() => !object.ReferenceEquals(_cluster.Description, currentClusterDescription), 100); // sometimes returns false and that's OK
        }
        private void AssertEvents(BsonDocument test, EventCapturer eventCapturer, Func <object, bool> eventsFilter)
        {
            var actualEvents   = GetFilteredEvents(eventCapturer, test, eventsFilter);
            var expectedEvents = GetExpectedEvents(test);

            try
            {
                var minCount = Math.Min(actualEvents.Count, expectedEvents.Count);
                for (var i = 0; i < minCount; i++)
                {
                    var expectedEvent = expectedEvents[i];
                    JsonDrivenHelper.EnsureAllFieldsAreValid(expectedEvent, "type", "address", "connectionId", "options", "reason");
                    AssertEvent(actualEvents[i], expectedEvent);
                }

                if (actualEvents.Count < expectedEvents.Count)
                {
                    throw new Exception($"Missing event: {expectedEvents[actualEvents.Count]}.");
                }

                if (actualEvents.Count > expectedEvents.Count)
                {
                    throw new Exception($"Unexpected event of type: {actualEvents[expectedEvents.Count].GetType().Name}.");
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"Events asserting failed: {ex.Message}. Triggered events: {eventCapturer}.", ex);
            }
        }
コード例 #8
0
        private void VerifyClusterDescription(ClusterDescription actualDescription, BsonDocument expectedDescription)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(expectedDescription, "servers", "setName", "topologyType");

            var expectedTopologyType = expectedDescription["topologyType"].AsString;

            VerifyTopology(actualDescription, expectedTopologyType);

            var actualEndPoints = actualDescription.Servers.Select(x => x.EndPoint);
            var expectedEndPointDescriptionPairs = expectedDescription["servers"].AsBsonArray.Select(x => new
            {
                EndPoint    = EndPointHelper.Parse(x["address"].AsString),
                Description = x.AsBsonDocument
            });

            actualEndPoints.WithComparer(EndPointHelper.EndPointEqualityComparer).Should().BeEquivalentTo(expectedEndPointDescriptionPairs.Select(x => x.EndPoint).WithComparer(EndPointHelper.EndPointEqualityComparer));

            foreach (var actualServerDescription in actualDescription.Servers)
            {
                var expectedServerDescription = expectedEndPointDescriptionPairs.Single(x => EndPointHelper.EndPointEqualityComparer.Equals(x.EndPoint, actualServerDescription.EndPoint)).Description;
                VerifyServerDescription(actualServerDescription, expectedServerDescription);
            }

            if (expectedDescription.Contains("setName"))
            {
                // TODO: assert something against setName
            }
        }
コード例 #9
0
 private void VerifyEvent(ClusterDescriptionChangedEvent actualEvent, BsonDocument expectedEvent)
 {
     JsonDrivenHelper.EnsureAllFieldsAreValid(expectedEvent, "newDescription", "previousDescription", "topologyId");
     actualEvent.ClusterId.Should().Be(_cluster.ClusterId);
     VerifyClusterDescription(actualEvent.OldDescription, expectedEvent["previousDescription"].AsBsonDocument);
     VerifyClusterDescription(actualEvent.NewDescription, expectedEvent["newDescription"].AsBsonDocument);
 }
        private void ExecuteOperation(
            BsonDocument operation,
            EventCapturer eventCapturer,
            ConcurrentDictionary <string, IConnection> connectionMap,
            ConcurrentDictionary <string, Task> tasks,
            IConnectionPool connectionPool,
            bool async,
            out Exception exception)
        {
            exception = null;
            var name = operation.GetValue("name").ToString();

            switch (name)
            {
            case "ready":
                connectionPool.SetReady();
                break;

            case "checkIn":
                ExecuteCheckIn(operation, connectionMap, out exception);
                break;

            case "checkOut":
                ExecuteCheckOut(connectionPool, operation, connectionMap, tasks, async, out exception);
                break;

            case "clear":
                JsonDrivenHelper.EnsureAllFieldsAreValid(operation, "name", "closeInUseConnections");
                var closeInUseConnections = operation.GetValue("closeInUseConnections", defaultValue: false).ToBoolean();
                connectionPool.Clear(closeInUseConnections: closeInUseConnections);
                break;

            case "close":
                connectionPool.Dispose();
                break;

            case "start":
                JsonDrivenHelper.EnsureAllFieldsAreValid(operation, "name", "target");
                Start(operation, tasks);
                break;

            case "wait":
                var ms = operation.GetValue("ms").ToInt32();
                Thread.Sleep(TimeSpan.FromMilliseconds(ms));
                break;

            case "waitForEvent":
                JsonDrivenHelper.EnsureAllFieldsAreValid(operation, "name", "event", "count", "timeout");
                WaitForEvent(eventCapturer, operation);
                break;

            case "waitForThread":
                JsonDrivenHelper.EnsureAllFieldsAreValid(operation, "name", "target");
                WaitForThread(operation, tasks, out exception);
                break;

            default:
                throw new ArgumentException($"Unknown operation {name}.");
            }
        }
コード例 #11
0
        public void RunTestDefinition(JsonDrivenTestCase testCase)
        {
            var definition = testCase.Test;

            JsonDrivenHelper.EnsureAllFieldsAreValid(definition, "valid", "options", "hosts", "auth", "description", "uri", "warning");

            ConnectionString connectionString = null;
            Exception        parseException   = null;

            try
            {
                connectionString = new ConnectionString((string)definition["uri"]);
            }
            catch (Exception ex)
            {
                parseException = ex;
            }

            if (parseException == null)
            {
                AssertValid(connectionString, definition);
            }
            else
            {
                AssertInvalid(parseException, definition);
            }
        }
コード例 #12
0
        // private methods
        private TransactionOptions ParseTransactionOptions(BsonDocument document)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(document, "readConcern", "readPreference", "writeConcern", "maxCommitTimeMS");

            var options = new TransactionOptions();

            if (document.Contains("readConcern"))
            {
                options = options.With(readConcern: ReadConcern.FromBsonDocument(document["readConcern"].AsBsonDocument));
            }

            if (document.Contains("readPreference"))
            {
                options = options.With(readPreference: ReadPreference.FromBsonDocument(document["readPreference"].AsBsonDocument));
            }

            if (document.Contains("writeConcern"))
            {
                options = options.With(writeConcern: WriteConcern.FromBsonDocument(document["writeConcern"].AsBsonDocument));
            }

            if (document.Contains("maxCommitTimeMS"))
            {
                options = options.With(maxCommitTime: TimeSpan.FromMilliseconds(document["maxCommitTimeMS"].ToInt32()));
            }

            return(options);
        }
        // private methods
        private void AssertError(BsonDocument test, Exception ex)
        {
            var containsErrorNode = test.Contains("error");

            if (!containsErrorNode && ex != null)
            {
                throw new Exception("Unexpected exception has been thrown.", ex);
            }
            else if (containsErrorNode && ex == null)
            {
                throw new Exception($"The test was expected to throw an exception {test["error"]}, but no exception was thrown.");
            }
            else if (containsErrorNode)
            {
                var error = test["error"].AsBsonDocument;
                JsonDrivenHelper.EnsureAllFieldsAreValid(error, "type", "message");
                var exType = MapErrorTypeToExpected(ex, out var exMessage);

                var expectedExceptionType = error["type"].ToString();
                var expectedErrorMessage  = error["message"].ToString();

                exType.Should().Be(expectedExceptionType);
                exMessage.Should().Be(expectedErrorMessage);
            }
        }
コード例 #14
0
        public void RunTestDefinition(JsonDrivenTestCase testCase)
        {
            var shared = testCase.Shared;
            var test   = testCase.Test;

            JsonDrivenHelper.EnsureAllFieldsAreValid(
                shared,
                "_path",
                "description",
                "bson_type",  // ignored
                "test_key",   // ignored
                "deprecated", // ignored
                "valid",
                "decodeErrors",
                "parseErrors");

            var testType = test["type"].AsString;

            switch (testType)
            {
            case "valid": RunValidTest(test); break;

            case "decodeErrors": RunDecodeErrorsTest(test); break;

            case "parseErrors": RunParseErrorsTest(test); break;

            default: throw new Exception($"Invalid test type: {testType}.");
            }
        }
コード例 #15
0
        public void RunTestDefinition(BsonDocument definition, BsonDocument test)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(definition, "_path", "database_name", "collection_name", "runOn", "minServerVersion", "maxServerVersion", "data", "tests");
            JsonDrivenHelper.EnsureAllFieldsAreValid(test, "description", "skipReason", "operation", "operations", "expectations", "outcome", "async");
            SkipTestIfNeeded(definition, test);

            var databaseName   = GetDatabaseName(definition);
            var collectionName = GetCollectionName(definition);

            DropCollection(databaseName, collectionName);
            PrepareData(databaseName, collectionName, definition);

            using (var client = CreateDisposableClient(_capturedEvents))
            {
                var database   = client.GetDatabase(databaseName);
                var operations = test.Contains("operation")
                    ? new[] { test["operation"].AsBsonDocument }
                    : test["operations"].AsBsonArray.Cast <BsonDocument>();
                var outcome = (BsonDocument)test.GetValue("outcome", null);
                var async   = test["async"].AsBoolean;

                foreach (var operation in operations)
                {
                    var collection = collectionName == null ? null : GetCollection(database, collectionName, operation);
                    ExecuteOperation(client, database, collection, operation, outcome, async);
                }

                AssertEventsIfNeeded(_capturedEvents, test);
            }
        }
コード例 #16
0
        private ReadPreference BuildReadPreference(BsonDocument readPreferenceDescription)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(readPreferenceDescription, "mode", "tag_sets", "maxStalenessSeconds");

            var mode = (ReadPreferenceMode)Enum.Parse(typeof(ReadPreferenceMode), readPreferenceDescription["mode"].AsString);

            IEnumerable <TagSet> tagSets = null;

            if (readPreferenceDescription.Contains("tag_sets"))
            {
                tagSets = ((BsonArray)readPreferenceDescription["tag_sets"]).Select(x => BuildTagSet((BsonDocument)x));
            }

            TimeSpan?maxStaleness = null;

            if (readPreferenceDescription.Contains("maxStalenessSeconds"))
            {
                maxStaleness = TimeSpan.FromSeconds(readPreferenceDescription["maxStalenessSeconds"].ToDouble());
            }

            // work around minor issue in test files
            if (mode == ReadPreferenceMode.Primary && tagSets != null)
            {
                if (tagSets.Count() == 1 && tagSets.First().Tags.Count == 0)
                {
                    tagSets = null;
                }
            }

            return(new ReadPreference(mode, tagSets, maxStaleness));
        }
コード例 #17
0
        public void RunTestDefinition(JsonDrivenTestCase testCase)
        {
            var definition = testCase.Test;

            JsonDrivenHelper.EnsureAllFieldsAreValid(definition, "description", "uri", "valid", "credential");

            MongoCredential mongoCredential = null;
            Exception       parseException  = null;

            try
            {
                var connectionString = (string)definition["uri"];
                mongoCredential = MongoClientSettings.FromConnectionString(connectionString).Credential;
            }
            catch (Exception ex)
            {
                parseException = ex;
            }

            if (parseException == null)
            {
                AssertValid(mongoCredential, definition);
            }
            else
            {
                AssertInvalid(parseException, definition);
            }
        }
コード例 #18
0
        private void AssertValid(MongoCredential mongoCredential, BsonDocument definition)
        {
            if (!definition["valid"].ToBoolean())
            {
                throw new AssertionException($"The connection string '{definition["uri"]}' should be invalid.");
            }

            var expectedCredential = definition["credential"] as BsonDocument;

            if (expectedCredential != null)
            {
                JsonDrivenHelper.EnsureAllFieldsAreValid(expectedCredential, "username", "password", "source", "mechanism", "mechanism_properties");
                mongoCredential.Username.Should().Be(ValueToString(expectedCredential["username"]));
#pragma warning disable 618
                mongoCredential.Password.Should().Be(ValueToString(expectedCredential["password"]));
#pragma warning restore 618
                mongoCredential.Source.Should().Be(ValueToString(expectedCredential["source"]));
                mongoCredential.Mechanism.Should().Be(ValueToString(expectedCredential["mechanism"]));

                var authenticator = mongoCredential.ToAuthenticator();
                if (authenticator is GssapiAuthenticator gssapiAuthenticator)
                {
                    expectedCredential.TryGetValue("mechanism_properties", out var expectedMechanismProperties);
                    if (expectedMechanismProperties.IsBsonNull)
                    {
                        var serviceName = gssapiAuthenticator._mechanism_serviceName();
                        serviceName.Should().Be("mongodb");      // The default is "mongodb".
                        var canonicalizeHostName = gssapiAuthenticator._mechanism_canonicalizeHostName();
                        canonicalizeHostName.Should().BeFalse(); // The default is "false".
                    }
                    else
                    {
                        foreach (var expectedMechanismProperty in expectedMechanismProperties.AsBsonDocument)
                        {
                            var mechanismName = expectedMechanismProperty.Name;
                            switch (mechanismName)
                            {
                            case "SERVICE_NAME":
                                var serviceName = gssapiAuthenticator._mechanism_serviceName();
                                serviceName.Should().Be(ValueToString(expectedMechanismProperty.Value));
                                break;

                            case "CANONICALIZE_HOST_NAME":
                                var canonicalizeHostName = gssapiAuthenticator._mechanism_canonicalizeHostName();
                                canonicalizeHostName.Should().Be(expectedMechanismProperty.Value.ToBoolean());
                                break;

                            default:
                                throw new Exception($"Invalid mechanism property '{mechanismName}'.");
                            }
                        }
                    }
                }
                else
                {
                    // Other authenticators do not contain mechanism properties
                }
            }
        }
コード例 #19
0
        private InsertOneModel <BsonDocument> ParseInsertOneModel(BsonDocument model)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(model, "document");

            var document = model["document"].AsBsonDocument;

            return(new InsertOneModel <BsonDocument>(document));
        }
コード例 #20
0
        private DeleteOneModel <BsonDocument> ParseDeleteOneModel(BsonDocument model)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(model, "filter");

            var filter = new BsonDocumentFilterDefinition <BsonDocument>(model["filter"].AsBsonDocument);

            return(new DeleteOneModel <BsonDocument>(filter));
        }
コード例 #21
0
        private void VerifyEvent(ServerClosedEvent actualEvent, BsonDocument expectedEvent)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(expectedEvent, "address", "topologyId");
            var expectedEndPoint = EndPointHelper.Parse(expectedEvent["address"].AsString);

            actualEvent.ClusterId.Should().Be(_cluster.ClusterId);
            actualEvent.ServerId.EndPoint.WithComparer(EndPointHelper.EndPointEqualityComparer).Should().Be(expectedEndPoint);
        }
コード例 #22
0
        // private methods
        private void Run(BsonDocument shared, BsonDocument test)
        {
            if (test.Contains("skipReason"))
            {
                throw new SkipException(test["skipReason"].AsString);
            }
            //if (test["description"].AsString != "rerun commit after empty transaction")
            //{
            //    return;
            //}

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

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

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

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

                Dictionary <string, BsonValue> sessionIdMap;

                var useMultipleShardRouters = shared["_path"].AsString.EndsWith("pin-mongos.json") &&
                                              CoreTestConfiguration.Cluster.Description.Type == ClusterType.Sharded;
                if (useMultipleShardRouters)
                {
                    PrimeShardRoutersWithDistinctCommand();
                }

                using (var client = CreateDisposableClient(test, eventCapturer, useMultipleShardRouters))
                    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);
            }
        }
コード例 #23
0
        private ClusterDescription BuildClusterDescription(BsonDocument topologyDescription, TimeSpan heartbeatInterval)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(topologyDescription, "servers", "type");

            var clusterType = GetClusterType(topologyDescription["type"].ToString());
            var servers     = BuildServerDescriptions((BsonArray)topologyDescription["servers"], heartbeatInterval);

            return(new ClusterDescription(_clusterId, ClusterConnectionMode.Automatic, clusterType, servers));
        }
コード例 #24
0
        private void VerifyOutcome(BsonDocument outcome)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(outcome, "compatible", "logicalSessionTimeoutMinutes", "servers", "setName", "topologyType");

            var expectedTopologyType = (string)outcome["topologyType"];

            VerifyTopology(_cluster, expectedTopologyType);

            var actualDescription = _cluster.Description;

            var actualServers   = actualDescription.Servers.Select(x => x.EndPoint);
            var expectedServers = outcome["servers"].AsBsonDocument.Elements.Select(x => new
            {
                EndPoint    = EndPointHelper.Parse(x.Name),
                Description = (BsonDocument)x.Value
            });

            actualServers.WithComparer(EndPointHelper.EndPointEqualityComparer).Should().BeEquivalentTo(expectedServers.Select(x => x.EndPoint).WithComparer(EndPointHelper.EndPointEqualityComparer));

            foreach (var actualServer in actualDescription.Servers)
            {
                var expectedServer = expectedServers.Single(x => EndPointHelper.EndPointEqualityComparer.Equals(x.EndPoint, actualServer.EndPoint));
                VerifyServerDescription(actualServer, expectedServer.Description);
            }

            if (outcome.Contains("setName"))
            {
                // TODO: assert something against setName
            }

            if (outcome.Contains("logicalSessionTimeoutMinutes"))
            {
                TimeSpan?expectedLogicalSessionTimeout;
                switch (outcome["logicalSessionTimeoutMinutes"].BsonType)
                {
                case BsonType.Null:
                    expectedLogicalSessionTimeout = null;
                    break;

                case BsonType.Int32:
                case BsonType.Int64:
                    expectedLogicalSessionTimeout = TimeSpan.FromMinutes(outcome["logicalSessionTimeoutMinutes"].ToDouble());
                    break;

                default:
                    throw new FormatException($"Invalid logicalSessionTimeoutMinutes BSON type: {outcome["setName"].BsonType}.");
                }
                actualDescription.LogicalSessionTimeout.Should().Be(expectedLogicalSessionTimeout);
            }

            if (outcome.Contains("compatible"))
            {
                var expectedIsCompatibleWithDriver = outcome["compatible"].ToBoolean();
                actualDescription.IsCompatibleWithDriver.Should().Be(expectedIsCompatibleWithDriver);
            }
        }
コード例 #25
0
        private void RunParseErrorsTest(BsonDocument test)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(test, "type", "description", "string");

            var json = test["string"].AsString;

            var exception = Record.Exception(() => BsonDocument.Parse(json));

            AssertException(exception);
        }
コード例 #26
0
        private DeleteManyModel <BsonDocument> ParseDeleteManyModel(BsonDocument model)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(model, "name", "arguments");
            var arguments = model["arguments"].AsBsonDocument;

            JsonDrivenHelper.EnsureAllFieldsAreValid(arguments, "filter");
            var filter = new BsonDocumentFilterDefinition <BsonDocument>(arguments["filter"].AsBsonDocument);

            return(new DeleteManyModel <BsonDocument>(filter));
        }
コード例 #27
0
        private void VerifyEvent(ServerDescriptionChangedEvent actualEvent, BsonDocument expectedEvent)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(expectedEvent, "address", "newDescription", "previousDescription", "topologyId");
            var expectedEndPoint = EndPointHelper.Parse(expectedEvent["address"].AsString);

            actualEvent.ClusterId.Should().Be(_cluster.ClusterId);
            actualEvent.ServerId.EndPoint.WithComparer(EndPointHelper.EndPointEqualityComparer).Should().Be(expectedEndPoint);
            VerifyServerDescription(actualEvent.OldDescription, expectedEvent["previousDescription"].AsBsonDocument);
            VerifyServerDescription(actualEvent.NewDescription, expectedEvent["newDescription"].AsBsonDocument);
        }
        private void ApplyResponse(BsonArray response)
        {
            if (response.Count != 2)
            {
                throw new FormatException($"Invalid response count: {response.Count}.");
            }

            var address       = response[0].AsString;
            var helloDocument = response[1].AsBsonDocument;
            var expectedNames = new[]
            {
                "arbiterOnly",
                "arbiters",
                "electionId",
                "hidden",
                "hosts",
                "helloOk",
                "isWritablePrimary",
                OppressiveLanguageConstants.LegacyHelloResponseIsWritablePrimaryFieldName,
                "isreplicaset",
                "logicalSessionTimeoutMinutes",
                "maxWireVersion",
                "me",
                "minWireVersion",
                "msg",
                "ok",
                "passive",
                "passives",
                "primary",
                "secondary",
                "setName",
                "setVersion",
                "topologyVersion"
            };

            JsonDrivenHelper.EnsureAllFieldsAreValid(helloDocument, expectedNames);

            var endPoint    = EndPointHelper.Parse(address);
            var helloResult = new HelloResult(helloDocument);
            var currentServerDescription = _serverFactory.GetServerDescription(endPoint);
            var newServerDescription     = currentServerDescription.With(
                canonicalEndPoint: helloResult.Me,
                electionId: helloResult.ElectionId,
                logicalSessionTimeout: helloResult.LogicalSessionTimeout,
                replicaSetConfig: helloResult.GetReplicaSetConfig(),
                state: helloResult.Wrapped.GetValue("ok", false).ToBoolean() ? ServerState.Connected : ServerState.Disconnected,
                topologyVersion: helloResult.TopologyVersion,
                type: helloResult.ServerType,
                wireVersionRange: new Range <int>(helloResult.MinWireVersion, helloResult.MaxWireVersion));

            var currentClusterDescription = _cluster.Description;

            _serverFactory.PublishDescription(newServerDescription);
            SpinWait.SpinUntil(() => !object.ReferenceEquals(_cluster.Description, currentClusterDescription), 100); // sometimes returns false and that's OK
        }
コード例 #29
0
        // public methods
        public override void Arrange(BsonDocument document)
        {
            JsonDrivenHelper.EnsureFieldEquals(document, "object", "collection");

            if (document.Contains("collectionOptions"))
            {
                ParseCollectionOptions(document["collectionOptions"].AsBsonDocument);
            }

            base.Arrange(document);
        }
コード例 #30
0
        private ReplaceOneModel <BsonDocument> ParseReplaceOneModel(BsonDocument model)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(model, "name", "arguments");
            var arguments = model["arguments"].AsBsonDocument;

            JsonDrivenHelper.EnsureAllFieldsAreValid(arguments, "filter", "replacement");
            var filter      = new BsonDocumentFilterDefinition <BsonDocument>(arguments["filter"].AsBsonDocument);
            var replacement = arguments["replacement"].AsBsonDocument;

            return(new ReplaceOneModel <BsonDocument>(filter, replacement));
        }