private void AssertCommandAspect(BsonDocument actualCommand, string name, BsonValue expectedValue) { var commandName = actualCommand.ElementCount == 0 ? "<unknown>" : actualCommand.GetElement(0).Name; if (expectedValue.IsBsonNull) { switch (name) { case "allowDiskUse": case "autocommit": case "readConcern": case "recoveryToken": case "startTransaction": case "txnNumber": case "writeConcern": case "maxTimeMS": if (actualCommand.Contains(name)) { throw new AssertionFailedException($"Did not expect field '{name}' in command: {actualCommand.ToJson()}."); } return; } } if (!actualCommand.Contains(name)) { // some missing fields are only missing because the C# driver omits default values switch (name) { case "new": if (commandName == "findAndModify" && expectedValue == false) { return; } break; case "cursor" when commandName == "listCollections": return; } throw new AssertionFailedException($"Expected field '{name}' in command: {actualCommand.ToJson()}."); } var actualValue = actualCommand[name]; if (name == "updates") { AdaptExpectedUpdateModels(actualValue.AsBsonArray.Cast <BsonDocument>().ToList(), expectedValue.AsBsonArray.Cast <BsonDocument>().ToList()); } var namesToUseOrderInsensitiveComparisonWith = new[] { "writeConcern", "maxTimeMS", "updates", "indexes", "getMore" }; var useOrderInsensitiveComparison = namesToUseOrderInsensitiveComparisonWith.Contains(name); if (!(useOrderInsensitiveComparison ? BsonValueEquivalencyComparer.Compare(actualValue, expectedValue) : actualValue.Equals(expectedValue))) { switch (name) { case "out": if (commandName == "mapReduce") { if (expectedValue is BsonString && actualValue.IsBsonDocument && actualValue.AsBsonDocument.Contains("replace") && actualValue["replace"] == expectedValue.AsString) { // allow short form for "out" to be equivalent to the long form // Assumes that the driver is correctly generating the following // fields: db, sharded, nonAtomic return; } } break; } throw new AssertionFailedException($"Expected field '{name}' in command '{commandName}' to be {expectedValue.ToJson()} but found {actualValue.ToJson()}."); } }