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); }
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}."); } }
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."); } }
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(); } } }
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); }
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 } }
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 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}."); } }
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); } }
// 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 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 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); }
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); } }
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); } }
// 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); } }
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); } }
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)); }
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 } } }
private InsertOneModel <BsonDocument> ParseInsertOneModel(BsonDocument model) { JsonDrivenHelper.EnsureAllFieldsAreValid(model, "document"); var document = model["document"].AsBsonDocument; return(new InsertOneModel <BsonDocument>(document)); }
private DeleteOneModel <BsonDocument> ParseDeleteOneModel(BsonDocument model) { JsonDrivenHelper.EnsureAllFieldsAreValid(model, "filter"); var filter = new BsonDocumentFilterDefinition <BsonDocument>(model["filter"].AsBsonDocument); return(new DeleteOneModel <BsonDocument>(filter)); }
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); }
// 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); } }
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)); }
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); } }
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)); }
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); }
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 }
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)); }
private ServerDescription BuildServerDescription(BsonDocument serverDescription, TimeSpan heartbeatInterval) { JsonDrivenHelper.EnsureAllFieldsAreValid(serverDescription, "address", "avg_rtt_ms", "tags", "type", "lastUpdateTime", "lastWrite", "maxWireVersion"); var endPoint = EndPointHelper.Parse(serverDescription["address"].ToString()); var averageRoundTripTime = TimeSpan.FromMilliseconds(serverDescription.GetValue("avg_rtt_ms", 0.0).ToDouble()); var type = GetServerType(serverDescription["type"].ToString()); TagSet tagSet = null; if (serverDescription.Contains("tags")) { tagSet = BuildTagSet((BsonDocument)serverDescription["tags"]); } DateTime lastWriteTimestamp; if (serverDescription.Contains("lastWrite")) { lastWriteTimestamp = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(serverDescription["lastWrite"]["lastWriteDate"].ToInt64()); } else { lastWriteTimestamp = _utcNow; } var maxWireVersion = serverDescription.GetValue("maxWireVersion", 5).ToInt32(); var wireVersionRange = new Range <int>(0, maxWireVersion); var serverVersion = maxWireVersion == 5 ? new SemanticVersion(3, 4, 0) : new SemanticVersion(3, 2, 0); DateTime lastUpdateTimestamp; if (serverDescription.Contains("lastUpdateTime")) { lastUpdateTimestamp = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(serverDescription.GetValue("lastUpdateTime", 0).ToInt64()); } else { lastUpdateTimestamp = _utcNow; } var serverId = new ServerId(_clusterId, endPoint); return(new ServerDescription( serverId, endPoint, averageRoundTripTime: averageRoundTripTime, type: type, lastUpdateTimestamp: lastUpdateTimestamp, lastWriteTimestamp: lastWriteTimestamp, heartbeatInterval: heartbeatInterval, wireVersionRange: wireVersionRange, version: serverVersion, tags: tagSet, state: ServerState.Connected)); }