/tests/MongoDB.Driver.Tests/MongoCollectionImplTests.cs
http://github.com/mongodb/mongo-csharp-driver · C# · 3657 lines · 3344 code · 282 blank · 31 comment · 171 complexity · 9dbd03b8576f485536d7520f954ab9a7 MD5 · raw file
Large files are truncated click here to view the full file
- /* Copyright 2010-present MongoDB Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Linq.Expressions;
- using System.Net;
- using System.Threading;
- using FluentAssertions;
- using MongoDB.Bson;
- using MongoDB.Bson.Serialization;
- using MongoDB.Bson.Serialization.Attributes;
- using MongoDB.Bson.Serialization.Serializers;
- using MongoDB.Bson.TestHelpers.XunitExtensions;
- using MongoDB.Driver.Core.Bindings;
- using MongoDB.Driver.Core.Clusters;
- using MongoDB.Driver.Core.Connections;
- using MongoDB.Driver.Core.Misc;
- using MongoDB.Driver.Core.Operations;
- using MongoDB.Driver.Core.Servers;
- using MongoDB.Driver.Core.TestHelpers.XunitExtensions;
- using MongoDB.Driver.Tests;
- using Moq;
- using Xunit;
- namespace MongoDB.Driver
- {
- public class MongoCollectionImplTests
- {
- private readonly ConnectionId _connectionId = new ConnectionId(new ServerId(new ClusterId(0), new DnsEndPoint("localhost", 27017)), 0);
- private readonly ReadConcern _readConcern = ReadConcern.Majority;
- private MockOperationExecutor _operationExecutor;
- public MongoCollectionImplTests()
- {
- var mockClient = new Mock<IMongoClient>();
- var mockCluster = new Mock<ICluster>();
- mockClient.SetupGet(m => m.Cluster).Returns(mockCluster.Object);
- _operationExecutor = new MockOperationExecutor();
- _operationExecutor.Client = mockClient.Object;
- }
- [Fact]
- public void CollectionName_should_be_set()
- {
- var subject = CreateSubject<BsonDocument>();
- subject.CollectionNamespace.CollectionName.Should().Be("bar");
- }
- public void Database_should_be_set()
- {
- var subject = CreateSubject<BsonDateTime>();
- subject.Database.Should().NotBeNull();
- }
- [Fact]
- public void Settings_should_be_set()
- {
- var subject = CreateSubject<BsonDocument>();
- subject.Settings.Should().NotBeNull();
- }
- [Theory]
- [ParameterAttributeData]
- public void Aggregate_should_execute_an_AggregateOperation_when_out_is_not_specified(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var pipeline = new EmptyPipelineDefinition<BsonDocument>().Match("{ x : 2 }");
- var options = new AggregateOptions()
- {
- AllowDiskUse = true,
- BatchSize = 10,
- Collation = new Collation("en_US"),
- Comment = "test",
- Hint = new BsonDocument("x", 1),
- MaxAwaitTime = TimeSpan.FromSeconds(4),
- MaxTime = TimeSpan.FromSeconds(3),
- #pragma warning disable 618
- UseCursor = false
- #pragma warning restore 618
- };
- var cancellationToken = new CancellationTokenSource().Token;
- var renderedPipeline = RenderPipeline(subject, pipeline);
- if (usingSession)
- {
- if (async)
- {
- subject.AggregateAsync(session, pipeline, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.Aggregate(session, pipeline, options, cancellationToken);
- }
- }
- else
- {
- if (async)
- {
- subject.AggregateAsync(pipeline, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.Aggregate(pipeline, options, cancellationToken);
- }
- }
- var call = _operationExecutor.GetReadCall<IAsyncCursor<BsonDocument>>();
- VerifySessionAndCancellationToken(call, session, cancellationToken);
- var operation = call.Operation.Should().BeOfType<AggregateOperation<BsonDocument>>().Subject;
- operation.AllowDiskUse.Should().Be(options.AllowDiskUse);
- operation.BatchSize.Should().Be(options.BatchSize);
- operation.Collation.Should().BeSameAs(options.Collation);
- operation.CollectionNamespace.Should().Be(subject.CollectionNamespace);
- operation.Comment.Should().Be(options.Comment);
- operation.Hint.Should().Be(options.Hint);
- operation.MaxAwaitTime.Should().Be(options.MaxAwaitTime);
- operation.MaxTime.Should().Be(options.MaxTime);
- operation.Pipeline.Should().Equal(renderedPipeline.Documents);
- operation.ReadConcern.Should().Be(_readConcern);
- operation.RetryRequested.Should().BeTrue();
- operation.ResultSerializer.Should().BeSameAs(renderedPipeline.OutputSerializer);
- #pragma warning disable 618
- operation.UseCursor.Should().Be(options.UseCursor);
- #pragma warning restore 618
- }
- [Theory]
- [ParameterAttributeData]
- public void Aggregate_should_execute_an_AggregateToCollectionOperation_and_a_FindOperation_when_out_is_specified(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool usingDifferentOutputDatabase,
- [Values(false, true)] bool async)
- {
- var writeConcern = new WriteConcern(1);
- var readConcern = new ReadConcern(ReadConcernLevel.Majority);
- var inputDatabase = CreateDatabase(databaseName: "inputDatabaseName");
- var subject = CreateSubject<BsonDocument>(database: inputDatabase).WithWriteConcern(writeConcern);
- var session = CreateSession(usingSession);
- var outputDatabase = usingDifferentOutputDatabase ? subject.Database.Client.GetDatabase("outputDatabaseName") : inputDatabase;
- var outputCollection = outputDatabase.GetCollection<BsonDocument>("outputCollectionName");
- var pipeline = new EmptyPipelineDefinition<BsonDocument>()
- .Match("{ x : 2 }")
- .Out(outputCollection);
- var options = new AggregateOptions()
- {
- AllowDiskUse = true,
- BatchSize = 10,
- BypassDocumentValidation = true,
- Collation = new Collation("en_US"),
- Comment = "test",
- Hint = new BsonDocument("x", 1),
- MaxTime = TimeSpan.FromSeconds(3),
- #pragma warning disable 618
- UseCursor = false
- #pragma warning restore 618
- };
- var cancellationToken1 = new CancellationTokenSource().Token;
- var cancellationToken2 = new CancellationTokenSource().Token;
- var expectedPipeline = new List<BsonDocument>(RenderPipeline(subject, pipeline).Documents);
- if (!usingDifferentOutputDatabase)
- {
- expectedPipeline[1] = new BsonDocument("$out", outputCollection.CollectionNamespace.CollectionName);
- }
- IAsyncCursor<BsonDocument> result;
- if (usingSession)
- {
- if (async)
- {
- result = subject.AggregateAsync(session, pipeline, options, cancellationToken1).GetAwaiter().GetResult();
- }
- else
- {
- result = subject.Aggregate(session, pipeline, options, cancellationToken1);
- }
- }
- else
- {
- if (async)
- {
- result = subject.AggregateAsync(pipeline, options, cancellationToken1).GetAwaiter().GetResult();
- }
- else
- {
- result = subject.Aggregate(pipeline, options, cancellationToken1);
- }
- }
- var aggregateCall = _operationExecutor.GetWriteCall<BsonDocument>();
- VerifySessionAndCancellationToken(aggregateCall, session, cancellationToken1);
- var aggregateOperation = aggregateCall.Operation.Should().BeOfType<AggregateToCollectionOperation>().Subject;
- aggregateOperation.AllowDiskUse.Should().Be(options.AllowDiskUse);
- aggregateOperation.BypassDocumentValidation.Should().Be(options.BypassDocumentValidation);
- aggregateOperation.Collation.Should().BeSameAs(options.Collation);
- aggregateOperation.CollectionNamespace.Should().Be(subject.CollectionNamespace);
- aggregateOperation.Comment.Should().Be(options.Comment);
- aggregateOperation.Hint.Should().Be(options.Hint);
- aggregateOperation.MaxTime.Should().Be(options.MaxTime);
- aggregateOperation.Pipeline.Should().Equal(expectedPipeline);
- aggregateOperation.ReadConcern.Should().Be(readConcern);
- aggregateOperation.WriteConcern.Should().BeSameAs(writeConcern);
- var mockCursor = new Mock<IAsyncCursor<BsonDocument>>();
- _operationExecutor.EnqueueResult(mockCursor.Object);
- if (async)
- {
- result.MoveNextAsync(cancellationToken2).GetAwaiter().GetResult();
- }
- else
- {
- result.MoveNext(cancellationToken2);
- }
- var findCall = _operationExecutor.GetReadCall<IAsyncCursor<BsonDocument>>();
- VerifySessionAndCancellationToken(findCall, session, cancellationToken2);
- var findOperation = findCall.Operation.Should().BeOfType<FindOperation<BsonDocument>>().Subject;
- findOperation.AllowDiskUse.Should().NotHaveValue();
- findOperation.AllowPartialResults.Should().NotHaveValue();
- findOperation.BatchSize.Should().Be(options.BatchSize);
- findOperation.Collation.Should().BeSameAs(options.Collation);
- findOperation.CollectionNamespace.FullName.Should().Be(outputCollection.CollectionNamespace.FullName);
- findOperation.Comment.Should().BeNull();
- findOperation.CursorType.Should().Be(Core.Operations.CursorType.NonTailable);
- findOperation.Filter.Should().BeNull();
- findOperation.Limit.Should().Be(null);
- findOperation.MaxTime.Should().Be(options.MaxTime);
- #pragma warning disable 618
- findOperation.Modifiers.Should().BeNull();
- #pragma warning restore 618
- findOperation.NoCursorTimeout.Should().NotHaveValue();
- #pragma warning disable 618
- findOperation.OplogReplay.Should().NotHaveValue();
- #pragma warning restore 618
- findOperation.Projection.Should().BeNull();
- findOperation.RetryRequested.Should().BeTrue();
- findOperation.Skip.Should().Be(null);
- findOperation.Sort.Should().BeNull();
- }
- [Theory]
- [ParameterAttributeData]
- public void AggregateToCollection_should_execute_an_AggregateToCollectionOperation(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool usingDifferentOutputDatabase,
- [Values(false, true)] bool async)
- {
- var writeConcern = new WriteConcern(1);
- var readConcern = new ReadConcern(ReadConcernLevel.Majority);
- var inputDatabase = CreateDatabase(databaseName: "inputDatabaseName");
- var subject = CreateSubject<BsonDocument>(database: inputDatabase).WithWriteConcern(writeConcern);
- var session = CreateSession(usingSession);
- var outputDatabase = usingDifferentOutputDatabase ? subject.Database.Client.GetDatabase("outputDatabaseName") : inputDatabase;
- var outputCollection = outputDatabase.GetCollection<BsonDocument>("outputCollectionName");
- var pipeline = new EmptyPipelineDefinition<BsonDocument>()
- .Match("{ x : 2 }")
- .Out(outputCollection);
- var options = new AggregateOptions()
- {
- AllowDiskUse = true,
- BatchSize = 10,
- BypassDocumentValidation = true,
- Collation = new Collation("en_US"),
- Comment = "test",
- Hint = new BsonDocument("x", 1),
- MaxTime = TimeSpan.FromSeconds(3),
- #pragma warning disable 618
- UseCursor = false
- #pragma warning restore 618
- };
- var cancellationToken = new CancellationTokenSource().Token;
- var expectedPipeline = new List<BsonDocument>(RenderPipeline(subject, pipeline).Documents);
- if (!usingDifferentOutputDatabase)
- {
- expectedPipeline[1] = new BsonDocument("$out", outputCollection.CollectionNamespace.CollectionName);
- }
- if (async)
- {
- if (usingSession)
- {
- subject.AggregateToCollectionAsync(session, pipeline, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.AggregateToCollectionAsync(pipeline, options, cancellationToken).GetAwaiter().GetResult();
- }
- }
- else
- {
- if (usingSession)
- {
- subject.AggregateToCollection(session, pipeline, options, cancellationToken);
- }
- else
- {
- subject.AggregateToCollection(pipeline, options, cancellationToken);
- }
- }
- var aggregateCall = _operationExecutor.GetWriteCall<BsonDocument>();
- VerifySessionAndCancellationToken(aggregateCall, session, cancellationToken);
- var aggregateOperation = aggregateCall.Operation.Should().BeOfType<AggregateToCollectionOperation>().Subject;
- aggregateOperation.AllowDiskUse.Should().Be(options.AllowDiskUse);
- aggregateOperation.BypassDocumentValidation.Should().Be(options.BypassDocumentValidation);
- aggregateOperation.Collation.Should().BeSameAs(options.Collation);
- aggregateOperation.CollectionNamespace.Should().Be(subject.CollectionNamespace);
- aggregateOperation.Comment.Should().Be(options.Comment);
- aggregateOperation.Hint.Should().Be(options.Hint);
- aggregateOperation.MaxTime.Should().Be(options.MaxTime);
- aggregateOperation.Pipeline.Should().Equal(expectedPipeline);
- aggregateOperation.ReadConcern.Should().Be(readConcern);
- aggregateOperation.WriteConcern.Should().BeSameAs(writeConcern);
- }
- [Theory]
- [ParameterAttributeData]
- public void AggregateToCollection_should_throw_when_last_stage_is_not_an_output_stage(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var pipeline = new EmptyPipelineDefinition<BsonDocument>()
- .Match("{ x : 2 }");
- var options = new AggregateOptions();
- var cancellationToken = new CancellationTokenSource().Token;
- Exception exception;
- if (async)
- {
- if (usingSession)
- {
- exception = Record.Exception(() => subject.AggregateToCollectionAsync(session, pipeline, options, cancellationToken).GetAwaiter().GetResult());
- }
- else
- {
- exception = Record.Exception(() => subject.AggregateToCollectionAsync(pipeline, options, cancellationToken).GetAwaiter().GetResult());
- }
- }
- else
- {
- if (usingSession)
- {
- exception = Record.Exception(() => subject.AggregateToCollection(session, pipeline, options, cancellationToken));
- }
- else
- {
- exception = Record.Exception(() => subject.AggregateToCollection(pipeline, options, cancellationToken));
- }
- }
- exception.Should().BeOfType<InvalidOperationException>();
- }
- [Theory]
- [ParameterAttributeData]
- public void BulkWrite_should_execute_a_BulkMixedWriteOperation(
- [Values(false, true)] bool usingSession,
- [Values(null, false, true)] bool? bypassDocumentValidation,
- [Values(false, true)] bool isOrdered,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var collation = new Collation("en_US");
- var hint = new BsonDocument("x", 1);
- var requests = new WriteModel<BsonDocument>[]
- {
- new InsertOneModel<BsonDocument>(new BsonDocument("_id", 1).Add("a",1)),
- new DeleteManyModel<BsonDocument>(new BsonDocument("b", 1)) { Collation = collation },
- new DeleteManyModel<BsonDocument>(new BsonDocument("c", 1)) { Collation = collation, Hint = hint },
- new DeleteOneModel<BsonDocument>(new BsonDocument("d", 1)) { Collation = collation },
- new DeleteOneModel<BsonDocument>(new BsonDocument("e", 1)) { Collation = collation, Hint = hint },
- new ReplaceOneModel<BsonDocument>(new BsonDocument("f", 1), new BsonDocument("g", 1)) { Collation = collation },
- new ReplaceOneModel<BsonDocument>(new BsonDocument("h", 1), new BsonDocument("i", 1)) { Collation = collation, Hint = hint },
- new ReplaceOneModel<BsonDocument>(new BsonDocument("j", 1), new BsonDocument("k", 1)) { Collation = collation, IsUpsert = true },
- new UpdateManyModel<BsonDocument>(new BsonDocument("l", 1), new BsonDocument("$set", new BsonDocument("m", 1))) { Collation = collation },
- new UpdateManyModel<BsonDocument>(new BsonDocument("n", 1), new BsonDocument("$set", new BsonDocument("o", 1))) { Collation = collation, Hint = hint },
- new UpdateManyModel<BsonDocument>(new BsonDocument("p", 1), new BsonDocument("$set", new BsonDocument("q", 1))) { Collation = collation, IsUpsert = true },
- new UpdateOneModel<BsonDocument>(new BsonDocument("r", 1), new BsonDocument("$set", new BsonDocument("s", 1))) { Collation = collation },
- new UpdateOneModel<BsonDocument>(new BsonDocument("t", 1), new BsonDocument("$set", new BsonDocument("u", 1))) { Collation = collation, Hint = hint },
- new UpdateOneModel<BsonDocument>(new BsonDocument("v", 1), new BsonDocument("$set", new BsonDocument("w", 1))) { Collation = collation, IsUpsert = true },
- };
- var options = new BulkWriteOptions
- {
- BypassDocumentValidation = bypassDocumentValidation,
- IsOrdered = isOrdered
- };
- var cancellationToken = new CancellationTokenSource().Token;
- var operationResult = new BulkWriteOperationResult.Unacknowledged(14, new[] { new InsertRequest(new BsonDocument("b", 1)) });
- _operationExecutor.EnqueueResult<BulkWriteOperationResult>(operationResult);
- BulkWriteResult<BsonDocument> result;
- if (usingSession)
- {
- if (async)
- {
- result = subject.BulkWriteAsync(session, requests, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- result = subject.BulkWrite(session, requests, options, cancellationToken);
- }
- }
- else
- {
- if (async)
- {
- result = subject.BulkWriteAsync(requests, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- result = subject.BulkWrite(requests, options, cancellationToken);
- }
- }
- var call = _operationExecutor.GetWriteCall<BulkWriteOperationResult>();
- VerifySessionAndCancellationToken(call, session, cancellationToken);
- // I know, this is a lot of stuff in one test :(
- var operation = call.Operation.Should().BeOfType<BulkMixedWriteOperation>().Subject;
- operation.BypassDocumentValidation.Should().Be(bypassDocumentValidation);
- operation.CollectionNamespace.Should().Be(subject.CollectionNamespace);
- operation.IsOrdered.Should().Be(isOrdered);
- operation.Requests.Count().Should().Be(14);
- var convertedRequests = operation.Requests.ToList();
- // InsertOneModel
- convertedRequests[0].Should().BeOfType<InsertRequest>();
- convertedRequests[0].CorrelationId.Should().Be(0);
- var convertedRequest0 = (InsertRequest)convertedRequests[0];
- convertedRequest0.Document.Should().Be("{_id:1, a:1}");
- // RemoveManyModel
- convertedRequests[1].Should().BeOfType<DeleteRequest>();
- convertedRequests[1].CorrelationId.Should().Be(1);
- var convertedRequest1 = (DeleteRequest)convertedRequests[1];
- convertedRequest1.Collation.Should().BeSameAs(collation);
- convertedRequest1.Filter.Should().Be("{b:1}");
- convertedRequest1.Hint.Should().BeNull();
- convertedRequest1.Limit.Should().Be(0);
- // RemoveManyModel with hint
- convertedRequests[2].Should().BeOfType<DeleteRequest>();
- convertedRequests[2].CorrelationId.Should().Be(2);
- var convertedRequest2 = (DeleteRequest)convertedRequests[2];
- convertedRequest2.Collation.Should().BeSameAs(collation);
- convertedRequest2.Filter.Should().Be("{c:1}");
- convertedRequest2.Hint.Should().Be(hint);
- convertedRequest2.Limit.Should().Be(0);
- // RemoveOneModel
- convertedRequests[3].Should().BeOfType<DeleteRequest>();
- convertedRequests[3].CorrelationId.Should().Be(3);
- var convertedRequest3 = (DeleteRequest)convertedRequests[3];
- convertedRequest3.Collation.Should().BeSameAs(collation);
- convertedRequest3.Filter.Should().Be("{d:1}");
- convertedRequest3.Hint.Should().BeNull();
- convertedRequest3.Limit.Should().Be(1);
- // RemoveOneModel with hint
- convertedRequests[4].Should().BeOfType<DeleteRequest>();
- convertedRequests[4].CorrelationId.Should().Be(4);
- var convertedRequest4 = (DeleteRequest)convertedRequests[4];
- convertedRequest4.Collation.Should().BeSameAs(collation);
- convertedRequest4.Filter.Should().Be("{e:1}");
- convertedRequest4.Hint.Should().Be(hint);
- convertedRequest4.Limit.Should().Be(1);
- // ReplaceOneModel
- convertedRequests[5].Should().BeOfType<UpdateRequest>();
- convertedRequests[5].CorrelationId.Should().Be(5);
- var convertedRequest5 = (UpdateRequest)convertedRequests[5];
- convertedRequest5.Collation.Should().BeSameAs(collation);
- convertedRequest5.Filter.Should().Be("{f:1}");
- convertedRequest5.Hint.Should().BeNull();
- convertedRequest5.Update.Should().Be("{g:1}");
- convertedRequest5.UpdateType.Should().Be(UpdateType.Replacement);
- convertedRequest5.IsMulti.Should().BeFalse();
- convertedRequest5.IsUpsert.Should().BeFalse();
- // ReplaceOneModel with hint
- convertedRequests[6].Should().BeOfType<UpdateRequest>();
- convertedRequests[6].CorrelationId.Should().Be(6);
- var convertedRequest6 = (UpdateRequest)convertedRequests[6];
- convertedRequest6.Collation.Should().BeSameAs(collation);
- convertedRequest6.Filter.Should().Be("{h:1}");
- convertedRequest6.Hint.Should().Be(hint);
- convertedRequest6.Update.Should().Be("{i:1}");
- convertedRequest6.UpdateType.Should().Be(UpdateType.Replacement);
- convertedRequest6.IsMulti.Should().BeFalse();
- convertedRequest6.IsUpsert.Should().BeFalse();
- // ReplaceOneModel with upsert
- convertedRequests[7].Should().BeOfType<UpdateRequest>();
- convertedRequests[7].CorrelationId.Should().Be(7);
- var convertedRequest7 = (UpdateRequest)convertedRequests[7];
- convertedRequest7.Collation.Should().BeSameAs(collation);
- convertedRequest7.Filter.Should().Be("{j:1}");
- convertedRequest7.Hint.Should().BeNull();
- convertedRequest7.Update.Should().Be("{k:1}");
- convertedRequest7.UpdateType.Should().Be(UpdateType.Replacement);
- convertedRequest7.IsMulti.Should().BeFalse();
- convertedRequest7.IsUpsert.Should().BeTrue();
- // UpdateManyModel
- convertedRequests[8].Should().BeOfType<UpdateRequest>();
- convertedRequests[8].CorrelationId.Should().Be(8);
- var convertedRequest8 = (UpdateRequest)convertedRequests[8];
- convertedRequest8.Collation.Should().BeSameAs(collation);
- convertedRequest8.Filter.Should().Be("{l:1}");
- convertedRequest8.Hint.Should().BeNull();
- convertedRequest8.Update.Should().Be("{$set:{m:1}}");
- convertedRequest8.UpdateType.Should().Be(UpdateType.Update);
- convertedRequest8.IsMulti.Should().BeTrue();
- convertedRequest8.IsUpsert.Should().BeFalse();
- // UpdateManyModel with hint
- convertedRequests[9].Should().BeOfType<UpdateRequest>();
- convertedRequests[9].CorrelationId.Should().Be(9);
- var convertedRequest9 = (UpdateRequest)convertedRequests[9];
- convertedRequest9.Collation.Should().BeSameAs(collation);
- convertedRequest9.Filter.Should().Be("{n:1}");
- convertedRequest9.Hint.Should().Be(hint);
- convertedRequest9.Update.Should().Be("{$set:{o:1}}");
- convertedRequest9.UpdateType.Should().Be(UpdateType.Update);
- convertedRequest9.IsMulti.Should().BeTrue();
- convertedRequest9.IsUpsert.Should().BeFalse();
- // UpdateManyModel with upsert
- convertedRequests[10].Should().BeOfType<UpdateRequest>();
- convertedRequests[10].CorrelationId.Should().Be(10);
- var convertedRequest10 = (UpdateRequest)convertedRequests[10];
- convertedRequest10.Collation.Should().BeSameAs(collation);
- convertedRequest10.Filter.Should().Be("{p:1}");
- convertedRequest10.Hint.Should().BeNull();
- convertedRequest10.Update.Should().Be("{$set:{q:1}}");
- convertedRequest10.UpdateType.Should().Be(UpdateType.Update);
- convertedRequest10.IsMulti.Should().BeTrue();
- convertedRequest10.IsUpsert.Should().BeTrue();
- // UpdateOneModel
- convertedRequests[11].Should().BeOfType<UpdateRequest>();
- convertedRequests[11].CorrelationId.Should().Be(11);
- var convertedRequest11 = (UpdateRequest)convertedRequests[11];
- convertedRequest11.Collation.Should().BeSameAs(collation);
- convertedRequest11.Filter.Should().Be("{r:1}");
- convertedRequest11.Hint.Should().BeNull();
- convertedRequest11.Update.Should().Be("{$set:{s:1}}");
- convertedRequest11.UpdateType.Should().Be(UpdateType.Update);
- convertedRequest11.IsMulti.Should().BeFalse();
- convertedRequest11.IsUpsert.Should().BeFalse();
- // UpdateOneModel with hint
- convertedRequests[12].Should().BeOfType<UpdateRequest>();
- convertedRequests[12].CorrelationId.Should().Be(12);
- var convertedRequest12 = (UpdateRequest)convertedRequests[12];
- convertedRequest12.Collation.Should().BeSameAs(collation);
- convertedRequest12.Filter.Should().Be("{t:1}");
- convertedRequest12.Hint.Should().Be(hint);
- convertedRequest12.Update.Should().Be("{$set:{u:1}}");
- convertedRequest12.UpdateType.Should().Be(UpdateType.Update);
- convertedRequest12.IsMulti.Should().BeFalse();
- convertedRequest12.IsUpsert.Should().BeFalse();
- // UpdateOneModel with upsert
- convertedRequests[13].Should().BeOfType<UpdateRequest>();
- convertedRequests[13].CorrelationId.Should().Be(13);
- var convertedRequest13 = (UpdateRequest)convertedRequests[13];
- convertedRequest13.Collation.Should().BeSameAs(collation);
- convertedRequest13.Filter.Should().Be("{v:1}");
- convertedRequest13.Hint.Should().BeNull();
- convertedRequest13.Update.Should().Be("{$set:{w:1}}");
- convertedRequest13.UpdateType.Should().Be(UpdateType.Update);
- convertedRequest13.IsMulti.Should().BeFalse();
- convertedRequest13.IsUpsert.Should().BeTrue();
- // Result
- result.Should().NotBeNull();
- result.IsAcknowledged.Should().BeFalse();
- result.RequestCount.Should().Be(14);
- result.ProcessedRequests.Should().BeEquivalentTo(requests);
- for (int i = 0; i < requests.Length; i++)
- {
- result.ProcessedRequests[i].Should().BeSameAs(requests[i]);
- }
- }
- [Theory]
- [ParameterAttributeData]
- public void BulkWrite_should_throw_if_model_is_invalid([Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var pipeline = new BsonDocumentStagePipelineDefinition<BsonDocument, BsonDocument>(new[] { new BsonDocument("$project", "{ value : 1 }") });
- var update = new PipelineUpdateDefinition<BsonDocument>(pipeline);
- var arrayFilters = new List<ArrayFilterDefinition>()
- {
- new BsonDocumentArrayFilterDefinition<BsonDocument>(new BsonDocument("x", 1))
- };
- var models = new WriteModel<BsonDocument>[]
- {
- new UpdateOneModel<BsonDocument>(new BsonDocument("n", 1), update)
- {
- ArrayFilters = arrayFilters
- },
- new UpdateManyModel<BsonDocument>(new BsonDocument("n", 2), update)
- {
- ArrayFilters = arrayFilters
- }
- };
- foreach (var model in models)
- {
- Exception exception;
- if (async)
- {
- exception = Record.ExceptionAsync(async () => { await subject.BulkWriteAsync(new[] { model }); })
- .GetAwaiter()
- .GetResult();
- }
- else
- {
- exception = Record.Exception(() => { subject.BulkWrite(new[] { model }); });
- }
- exception.Should().BeOfType<NotSupportedException>();
- }
- }
- [Theory]
- [ParameterAttributeData]
- public void Count_should_execute_a_CountOperation(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var filter = new BsonDocument("x", 1);
- var options = new CountOptions
- {
- Collation = new Collation("en_US"),
- Hint = "funny",
- Limit = 10,
- MaxTime = TimeSpan.FromSeconds(20),
- Skip = 30
- };
- var cancellationToken = new CancellationTokenSource().Token;
- if (usingSession)
- {
- if (async)
- {
- #pragma warning disable 618
- subject.CountAsync(session, filter, options, cancellationToken).GetAwaiter().GetResult();
- #pragma warning restore
- }
- else
- {
- #pragma warning disable 618
- subject.Count(session, filter, options, cancellationToken);
- #pragma warning restore
- }
- }
- else
- {
- if (async)
- {
- #pragma warning disable 618
- subject.CountAsync(filter, options, cancellationToken).GetAwaiter().GetResult();
- #pragma warning restore
- }
- else
- {
- #pragma warning disable 618
- subject.Count(filter, options, cancellationToken);
- #pragma warning restore
- }
- }
- var call = _operationExecutor.GetReadCall<long>();
- VerifySessionAndCancellationToken(call, session, cancellationToken);
- var operation = call.Operation.Should().BeOfType<CountOperation>().Subject;
- operation.Collation.Should().BeSameAs(options.Collation);
- operation.CollectionNamespace.Should().Be(subject.CollectionNamespace);
- operation.Filter.Should().Be(filter);
- operation.Hint.Should().Be(options.Hint);
- operation.Limit.Should().Be(options.Limit);
- operation.MaxTime.Should().Be(options.MaxTime);
- operation.ReadConcern.Should().Be(_readConcern);
- operation.RetryRequested.Should().BeTrue();
- operation.Skip.Should().Be(options.Skip);
- }
- [Theory]
- [ParameterAttributeData]
- public void CountDocuments_should_execute_a_CountDocumentsOperation(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var filter = new BsonDocument("x", 1);
- var options = new CountOptions
- {
- Collation = new Collation("en_US"),
- Hint = "funny",
- Limit = 10,
- MaxTime = TimeSpan.FromSeconds(20),
- Skip = 30
- };
- var cancellationToken = new CancellationTokenSource().Token;
- if (usingSession)
- {
- if (async)
- {
- subject.CountDocumentsAsync(session, filter, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.CountDocuments(session, filter, options, cancellationToken);
- }
- }
- else
- {
- if (async)
- {
- subject.CountDocumentsAsync(filter, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.CountDocuments(filter, options, cancellationToken);
- }
- }
- var call = _operationExecutor.GetReadCall<long>();
- VerifySessionAndCancellationToken(call, session, cancellationToken);
- var operation = call.Operation.Should().BeOfType<CountDocumentsOperation>().Subject;
- operation.Collation.Should().BeSameAs(options.Collation);
- operation.CollectionNamespace.Should().Be(subject.CollectionNamespace);
- operation.Filter.Should().Be(filter);
- operation.Hint.Should().Be(options.Hint);
- operation.Limit.Should().Be(options.Limit);
- operation.MaxTime.Should().Be(options.MaxTime);
- operation.ReadConcern.Should().Be(_readConcern);
- operation.RetryRequested.Should().BeTrue();
- operation.Skip.Should().Be(options.Skip);
- }
- [Theory]
- [ParameterAttributeData]
- public void DeleteMany_should_execute_a_BulkMixedOperation(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var filter = new BsonDocument("a", 1);
- var collation = new Collation("en_US");
- var hint = new BsonDocument("_id", 1);
- var options = new DeleteOptions { Collation = collation };
- var cancellationToken = new CancellationTokenSource().Token;
- var processedRequest = new DeleteRequest(filter) { Collation = collation, CorrelationId = 0, Hint = hint, Limit = 0 };
- var operationResult = new BulkWriteOperationResult.Unacknowledged(9, new[] { processedRequest });
- _operationExecutor.EnqueueResult<BulkWriteOperationResult>(operationResult);
- if (usingSession)
- {
- if (async)
- {
- subject.DeleteManyAsync(session, filter, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.DeleteMany(session, filter, options, cancellationToken);
- }
- }
- else
- {
- if (async)
- {
- subject.DeleteManyAsync(filter, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.DeleteMany(filter, options, cancellationToken);
- }
- }
- var call = _operationExecutor.GetWriteCall<BulkWriteOperationResult>();
- VerifySessionAndCancellationToken(call, session, cancellationToken);
- VerifySingleWrite(call, null, true, processedRequest);
- }
- [Theory]
- [ParameterAttributeData]
- public void DeleteMany_should_throw_a_WriteException_when_an_error_occurs(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var filter = new BsonDocument("a", 1);
- var options = new DeleteOptions();
- var cancellationToken = new CancellationTokenSource().Token;
- var processedRequest = new DeleteRequest(filter) { CorrelationId = 0, Limit = 0 };
- var operationException = new MongoBulkWriteOperationException(
- _connectionId,
- new BulkWriteOperationResult.Acknowledged(
- requestCount: 1,
- matchedCount: 1,
- deletedCount: 0,
- insertedCount: 0,
- modifiedCount: 0,
- processedRequests: new[] { processedRequest },
- upserts: new List<BulkWriteOperationUpsert>()),
- new[] { new BulkWriteOperationError(10, 1, "blah", new BsonDocument()) },
- null,
- new List<WriteRequest>());
- _operationExecutor.EnqueueException<BulkWriteOperationResult>(operationException);
- Exception exception;
- if (usingSession)
- {
- if (async)
- {
- exception = Record.Exception(() => subject.DeleteManyAsync(session, filter, options, cancellationToken).GetAwaiter().GetResult());
- }
- else
- {
- exception = Record.Exception(() => subject.DeleteMany(session, filter, options, cancellationToken));
- }
- }
- else
- {
- if (async)
- {
- exception = Record.Exception(() => subject.DeleteManyAsync(filter, options, cancellationToken).GetAwaiter().GetResult());
- }
- else
- {
- exception = Record.Exception(() => subject.DeleteMany(filter, options, cancellationToken));
- }
- }
- var call = _operationExecutor.GetWriteCall<BulkWriteOperationResult>();
- VerifySessionAndCancellationToken(call, session, cancellationToken);
- exception.Should().BeOfType<MongoWriteException>();
- }
- [Theory]
- [ParameterAttributeData]
- public void DeleteOne_should_execute_a_BulkMixedOperation(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var filter = new BsonDocument("a", 1);
- var collation = new Collation("en_US");
- var hint = new BsonDocument("_id", 1);
- var options = new DeleteOptions { Collation = collation };
- var cancellationToken = new CancellationTokenSource().Token;
- var processedRequest = new DeleteRequest(filter)
- {
- Collation = collation,
- CorrelationId = 0,
- Hint = hint,
- Limit = 1
- };
- var operationResult = new BulkWriteOperationResult.Unacknowledged(9, new[] { processedRequest });
- _operationExecutor.EnqueueResult<BulkWriteOperationResult>(operationResult);
- if (usingSession)
- {
- if (async)
- {
- subject.DeleteOneAsync(session, filter, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.DeleteOne(session, filter, options, cancellationToken);
- }
- }
- else
- {
- if (async)
- {
- subject.DeleteOneAsync(filter, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.DeleteOne(filter, options, cancellationToken);
- }
- }
- var call = _operationExecutor.GetWriteCall<BulkWriteOperationResult>();
- VerifySessionAndCancellationToken(call, session, cancellationToken);
- VerifySingleWrite(call, null, true, processedRequest);
- }
- [Theory]
- [ParameterAttributeData]
- public void DeleteOne_should_throw_a_WriteException_when_an_error_occurs(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var filter = new BsonDocument("a", 1);
- var options = new DeleteOptions();
- var cancellationToken = new CancellationTokenSource().Token;
- var processedRequest = new DeleteRequest(filter) { CorrelationId = 0, Limit = 1 };
- var operationException = new MongoBulkWriteOperationException(
- _connectionId,
- new BulkWriteOperationResult.Acknowledged(
- requestCount: 1,
- matchedCount: 1,
- deletedCount: 0,
- insertedCount: 0,
- modifiedCount: 0,
- processedRequests: new[] { processedRequest },
- upserts: new List<BulkWriteOperationUpsert>()),
- new[] { new BulkWriteOperationError(0, 1, "blah", new BsonDocument()) },
- null,
- new List<WriteRequest>());
- _operationExecutor.EnqueueException<BulkWriteOperationResult>(operationException);
- Exception exception;
- if (usingSession)
- {
- if (async)
- {
- exception = Record.Exception(() => subject.DeleteOneAsync(session, filter, options, cancellationToken).GetAwaiter().GetResult());
- }
- else
- {
- exception = Record.Exception(() => subject.DeleteOne(session, filter, options, cancellationToken));
- }
- }
- else
- {
- if (async)
- {
- exception = Record.Exception(() => subject.DeleteOneAsync(filter, options, cancellationToken).GetAwaiter().GetResult());
- }
- else
- {
- exception = Record.Exception(() => subject.DeleteOne(filter, options, cancellationToken));
- }
- }
- var call = _operationExecutor.GetWriteCall<BulkWriteOperationResult>();
- VerifySessionAndCancellationToken(call, session, cancellationToken);
- exception.Should().BeOfType<MongoWriteException>();
- }
- [Theory]
- [ParameterAttributeData]
- public void Distinct_should_execute_a_DistinctOperation(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<BsonDocument>();
- var session = CreateSession(usingSession);
- var fieldName = "a.b";
- var fieldDefinition = (FieldDefinition<BsonDocument, int>)fieldName;
- var filterDocument = new BsonDocument("x", 1);
- var filterDefinition = (FilterDefinition<BsonDocument>)filterDocument;
- var options = new DistinctOptions
- {
- Collation = new Collation("en_US"),
- MaxTime = TimeSpan.FromSeconds(20)
- };
- var cancellationToken = new CancellationTokenSource().Token;
- if (usingSession)
- {
- if (async)
- {
- subject.DistinctAsync(session, fieldDefinition, filterDefinition, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.Distinct(session, fieldDefinition, filterDefinition, options, cancellationToken);
- }
- }
- else
- {
- if (async)
- {
- subject.DistinctAsync(fieldDefinition, filterDefinition, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.Distinct(fieldDefinition, filterDefinition, options, cancellationToken);
- }
- }
- var call = _operationExecutor.GetReadCall<IAsyncCursor<int>>();
- VerifySessionAndCancellationToken(call, session, cancellationToken);
- var operation = call.Operation.Should().BeOfType<DistinctOperation<int>>().Subject;
- operation.Collation.Should().BeSameAs(options.Collation);
- operation.CollectionNamespace.Should().Be(subject.CollectionNamespace);
- operation.FieldName.Should().Be(fieldName);
- operation.Filter.Should().Be(filterDocument);
- operation.MaxTime.Should().Be(options.MaxTime);
- operation.ReadConcern.Should().Be(_readConcern);
- operation.RetryRequested.Should().BeTrue();
- operation.ValueSerializer.ValueType.Should().Be(typeof(int));
- }
- private enum EnumForDistinctWithArrayField { A, B }
- private class ClassForDistinctWithArrayField
- {
- public int Id { get; set; }
- [BsonRepresentation(BsonType.String)]
- public EnumForDistinctWithArrayField[] A { get; set; }
- }
- [Theory]
- [ParameterAttributeData]
- public void Distinct_should_execute_a_DistinctOperation_when_type_parameter_is_array_field_item_type(
- [Values(false, true)] bool usingSession,
- [Values(false, true)] bool async)
- {
- var subject = CreateSubject<ClassForDistinctWithArrayField>();
- var session = CreateSession(usingSession);
- var fieldName = "A";
- var fieldDefinition = (FieldDefinition<ClassForDistinctWithArrayField, EnumForDistinctWithArrayField>)fieldName;
- var filterDocument = new BsonDocument("x", 1);
- var filterDefinition = (FilterDefinition<ClassForDistinctWithArrayField>)filterDocument;
- var options = new DistinctOptions
- {
- Collation = new Collation("en_US"),
- MaxTime = TimeSpan.FromSeconds(20)
- };
- var cancellationToken = new CancellationTokenSource().Token;
- if (usingSession)
- {
- if (async)
- {
- subject.DistinctAsync(session, fieldDefinition, filterDefinition, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.Distinct(session, fieldDefinition, filterDefinition, options, cancellationToken);
- }
- }
- else
- {
- if (async)
- {
- subject.DistinctAsync(fieldDefinition, filterDefinition, options, cancellationToken).GetAwaiter().GetResult();
- }
- else
- {
- subject.Distinct(fieldDefinition, filterDefinition, options, cancellation…