using System.Net; using LCU.API.Internal.DocumentLib.Utilities; using Mongo2Go; using MongoDB.Bson; using MongoDB.Bson.Serialization; using MongoDB.Driver; using MongoDB.Driver.Core.Connections; using MongoDB.Driver.Core.Servers; namespace OwnerNumberMigrationTest.TestDoubles; public class FakeMongoCollectionFactory : IMongoCollectionFactory, IDisposable { private readonly MongoDbRunner _runner = MongoDbRunner.Start(); public string ConnectionString => _runner.ConnectionString; public string DatabaseName() => typeof(T).Name + DatabasePostFix; public string CollectionName() => typeof(T).Name; public string DatabasePostFix { get; set; } = string.Empty; public TimeSpan? TooManyRequestsOnWriteFor { get; set; } public IMongoCollection GetCollection() { var collection = new MongoClient(_runner.ConnectionString) .GetDatabase(DatabaseName()) .GetCollection(CollectionName()); if (TooManyRequestsOnWriteFor is not null) { collection = new TooManyRequestsOnWriteCollectionDecorator(collection, TooManyRequestsOnWriteFor.Value); } return collection; } public void Dispose() { _runner.Dispose(); } } public class TooManyRequestsOnWriteCollectionDecorator : IMongoCollection { private IMongoCollection _collection; private readonly TimeSpan _tooManyRequestsDuring; private DateTime? _firstRequest = null; public TooManyRequestsOnWriteCollectionDecorator(IMongoCollection collection, TimeSpan tooManyRequestsDuring) { _collection = collection; _tooManyRequestsDuring = tooManyRequestsDuring; } private void CheckTimout() { if (_firstRequest is null) { _firstRequest = DateTime.Now; var dns = new DnsEndPoint("localhost", 27017); var cluster = _collection.Database.Client.Cluster.ClusterId; var server = new ServerId(cluster, dns); var connection = new ConnectionId(server); var result = new BsonDocument(); result["code"] = 16500; result["errmsg"] = $"{Guid.NewGuid()} RetryAfterMs={_tooManyRequestsDuring.TotalMilliseconds} {Guid.NewGuid()}"; throw new MongoCommandException(connection, "", new BsonDocument(), result); } if (DateTime.Now - _firstRequest < _tooManyRequestsDuring) { throw new Exception("cool it, mate"); } } public IAsyncCursor Aggregate(PipelineDefinition pipeline, AggregateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.Aggregate(pipeline, options, cancellationToken); } public IAsyncCursor Aggregate(IClientSessionHandle session, PipelineDefinition pipeline, AggregateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.Aggregate(session, pipeline, options, cancellationToken); } public Task> AggregateAsync(PipelineDefinition pipeline, AggregateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.AggregateAsync(pipeline, options, cancellationToken); } public Task> AggregateAsync(IClientSessionHandle session, PipelineDefinition pipeline, AggregateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.AggregateAsync(session, pipeline, options, cancellationToken); } public void AggregateToCollection(PipelineDefinition pipeline, AggregateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); _collection.AggregateToCollection(pipeline, options, cancellationToken); } public void AggregateToCollection(IClientSessionHandle session, PipelineDefinition pipeline, AggregateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); _collection.AggregateToCollection(session, pipeline, options, cancellationToken); } public Task AggregateToCollectionAsync(PipelineDefinition pipeline, AggregateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.AggregateToCollectionAsync(pipeline, options, cancellationToken); } public Task AggregateToCollectionAsync(IClientSessionHandle session, PipelineDefinition pipeline, AggregateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.AggregateToCollectionAsync(session, pipeline, options, cancellationToken); } public BulkWriteResult BulkWrite(IEnumerable> requests, BulkWriteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.BulkWrite(requests, options, cancellationToken); } public BulkWriteResult BulkWrite(IClientSessionHandle session, IEnumerable> requests, BulkWriteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.BulkWrite(session, requests, options, cancellationToken); } public Task> BulkWriteAsync(IEnumerable> requests, BulkWriteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.BulkWriteAsync(requests, options, cancellationToken); } public Task> BulkWriteAsync(IClientSessionHandle session, IEnumerable> requests, BulkWriteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.BulkWriteAsync(session, requests, options, cancellationToken); } public long Count(FilterDefinition filter, CountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.Count(filter, options, cancellationToken); } public long Count(IClientSessionHandle session, FilterDefinition filter, CountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.Count(session, filter, options, cancellationToken); } public Task CountAsync(FilterDefinition filter, CountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.CountAsync(filter, options, cancellationToken); } public Task CountAsync(IClientSessionHandle session, FilterDefinition filter, CountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.CountAsync(session, filter, options, cancellationToken); } public long CountDocuments(FilterDefinition filter, CountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.CountDocuments(filter, options, cancellationToken); } public long CountDocuments(IClientSessionHandle session, FilterDefinition filter, CountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.CountDocuments(session, filter, options, cancellationToken); } public Task CountDocumentsAsync(FilterDefinition filter, CountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.CountDocumentsAsync(filter, options, cancellationToken); } public Task CountDocumentsAsync(IClientSessionHandle session, FilterDefinition filter, CountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.CountDocumentsAsync(session, filter, options, cancellationToken); } public DeleteResult DeleteMany(FilterDefinition filter, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteMany(filter, cancellationToken); } public DeleteResult DeleteMany(FilterDefinition filter, DeleteOptions options, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteMany(filter, options, cancellationToken); } public DeleteResult DeleteMany(IClientSessionHandle session, FilterDefinition filter, DeleteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteMany(session, filter, options, cancellationToken); } public Task DeleteManyAsync(FilterDefinition filter, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteManyAsync(filter, cancellationToken); } public Task DeleteManyAsync(FilterDefinition filter, DeleteOptions options, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteManyAsync(filter, options, cancellationToken); } public Task DeleteManyAsync(IClientSessionHandle session, FilterDefinition filter, DeleteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteManyAsync(session, filter, options, cancellationToken); } public DeleteResult DeleteOne(FilterDefinition filter, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteOne(filter, cancellationToken); } public DeleteResult DeleteOne(FilterDefinition filter, DeleteOptions options, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteOne(filter, options, cancellationToken); } public DeleteResult DeleteOne(IClientSessionHandle session, FilterDefinition filter, DeleteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteOne(session, filter, options, cancellationToken); } public Task DeleteOneAsync(FilterDefinition filter, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteOneAsync(filter, cancellationToken); } public Task DeleteOneAsync(FilterDefinition filter, DeleteOptions options, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteOneAsync(filter, options, cancellationToken); } public Task DeleteOneAsync(IClientSessionHandle session, FilterDefinition filter, DeleteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.DeleteOneAsync(session, filter, options, cancellationToken); } public IAsyncCursor Distinct(FieldDefinition field, FilterDefinition filter, DistinctOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.Distinct(field, filter, options, cancellationToken); } public IAsyncCursor Distinct(IClientSessionHandle session, FieldDefinition field, FilterDefinition filter, DistinctOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.Distinct(session, field, filter, options, cancellationToken); } public Task> DistinctAsync(FieldDefinition field, FilterDefinition filter, DistinctOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.DistinctAsync(field, filter, options, cancellationToken); } public Task> DistinctAsync(IClientSessionHandle session, FieldDefinition field, FilterDefinition filter, DistinctOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.DistinctAsync(session, field, filter, options, cancellationToken); } public long EstimatedDocumentCount(EstimatedDocumentCountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.EstimatedDocumentCount(options, cancellationToken); } public Task EstimatedDocumentCountAsync(EstimatedDocumentCountOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.EstimatedDocumentCountAsync(options, cancellationToken); } public IAsyncCursor FindSync(FilterDefinition filter, FindOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.FindSync(filter, options, cancellationToken); } public IAsyncCursor FindSync(IClientSessionHandle session, FilterDefinition filter, FindOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.FindSync(session, filter, options, cancellationToken); } public Task> FindAsync(FilterDefinition filter, FindOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.FindAsync(filter, options, cancellationToken); } public Task> FindAsync(IClientSessionHandle session, FilterDefinition filter, FindOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.FindAsync(session, filter, options, cancellationToken); } public TProjection FindOneAndDelete(FilterDefinition filter, FindOneAndDeleteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndDelete(filter, options, cancellationToken); } public TProjection FindOneAndDelete(IClientSessionHandle session, FilterDefinition filter, FindOneAndDeleteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndDelete(session, filter, options, cancellationToken); } public Task FindOneAndDeleteAsync(FilterDefinition filter, FindOneAndDeleteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndDeleteAsync(filter, options, cancellationToken); } public Task FindOneAndDeleteAsync(IClientSessionHandle session, FilterDefinition filter, FindOneAndDeleteOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndDeleteAsync(session, filter, options, cancellationToken); } public TProjection FindOneAndReplace(FilterDefinition filter, T replacement, FindOneAndReplaceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndReplace(filter, replacement, options, cancellationToken); } public TProjection FindOneAndReplace(IClientSessionHandle session, FilterDefinition filter, T replacement, FindOneAndReplaceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndReplace(session, filter, replacement, options, cancellationToken); } public Task FindOneAndReplaceAsync(FilterDefinition filter, T replacement, FindOneAndReplaceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndReplaceAsync(filter, replacement, options, cancellationToken); } public Task FindOneAndReplaceAsync(IClientSessionHandle session, FilterDefinition filter, T replacement, FindOneAndReplaceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndReplaceAsync(session, filter, replacement, options, cancellationToken); } public TProjection FindOneAndUpdate(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndUpdate(filter, update, options, cancellationToken); } public TProjection FindOneAndUpdate(IClientSessionHandle session, FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndUpdate(session, filter, update, options, cancellationToken); } public Task FindOneAndUpdateAsync(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndUpdateAsync(filter, update, options, cancellationToken); } public Task FindOneAndUpdateAsync(IClientSessionHandle session, FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.FindOneAndUpdateAsync(session, filter, update, options, cancellationToken); } public void InsertOne(T document, InsertOneOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); _collection.InsertOne(document, options, cancellationToken); } public void InsertOne(IClientSessionHandle session, T document, InsertOneOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); _collection.InsertOne(session, document, options, cancellationToken); } public Task InsertOneAsync(T document, CancellationToken _cancellationToken) { CheckTimout(); return _collection.InsertOneAsync(document, _cancellationToken); } public Task InsertOneAsync(T document, InsertOneOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.InsertOneAsync(document, options, cancellationToken); } public Task InsertOneAsync(IClientSessionHandle session, T document, InsertOneOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.InsertOneAsync(session, document, options, cancellationToken); } public void InsertMany(IEnumerable documents, InsertManyOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); _collection.InsertMany(documents, options, cancellationToken); } public void InsertMany(IClientSessionHandle session, IEnumerable documents, InsertManyOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); _collection.InsertMany(session, documents, options, cancellationToken); } public Task InsertManyAsync(IEnumerable documents, InsertManyOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.InsertManyAsync(documents, options, cancellationToken); } public Task InsertManyAsync(IClientSessionHandle session, IEnumerable documents, InsertManyOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.InsertManyAsync(session, documents, options, cancellationToken); } public IAsyncCursor MapReduce(BsonJavaScript map, BsonJavaScript reduce, MapReduceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.MapReduce(map, reduce, options, cancellationToken); } public IAsyncCursor MapReduce(IClientSessionHandle session, BsonJavaScript map, BsonJavaScript reduce, MapReduceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.MapReduce(session, map, reduce, options, cancellationToken); } public Task> MapReduceAsync(BsonJavaScript map, BsonJavaScript reduce, MapReduceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.MapReduceAsync(map, reduce, options, cancellationToken); } public Task> MapReduceAsync(IClientSessionHandle session, BsonJavaScript map, BsonJavaScript reduce, MapReduceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.MapReduceAsync(session, map, reduce, options, cancellationToken); } public IFilteredMongoCollection OfType() where TDerivedDocument : T { return _collection.OfType(); } public ReplaceOneResult ReplaceOne(FilterDefinition filter, T replacement, ReplaceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.ReplaceOne(filter, replacement, options, cancellationToken); } public ReplaceOneResult ReplaceOne(FilterDefinition filter, T replacement, UpdateOptions options, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.ReplaceOne(filter, replacement, options, cancellationToken); } public ReplaceOneResult ReplaceOne(IClientSessionHandle session, FilterDefinition filter, T replacement, ReplaceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.ReplaceOne(session, filter, replacement, options, cancellationToken); } public ReplaceOneResult ReplaceOne(IClientSessionHandle session, FilterDefinition filter, T replacement, UpdateOptions options, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.ReplaceOne(session, filter, replacement, options, cancellationToken); } public Task ReplaceOneAsync(FilterDefinition filter, T replacement, ReplaceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.ReplaceOneAsync(filter, replacement, options, cancellationToken); } public Task ReplaceOneAsync(FilterDefinition filter, T replacement, UpdateOptions options, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.ReplaceOneAsync(filter, replacement, options, cancellationToken); } public Task ReplaceOneAsync(IClientSessionHandle session, FilterDefinition filter, T replacement, ReplaceOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.ReplaceOneAsync(session, filter, replacement, options, cancellationToken); } public Task ReplaceOneAsync(IClientSessionHandle session, FilterDefinition filter, T replacement, UpdateOptions options, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.ReplaceOneAsync(session, filter, replacement, options, cancellationToken); } public UpdateResult UpdateMany(FilterDefinition filter, UpdateDefinition update, UpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.UpdateMany(filter, update, options, cancellationToken); } public UpdateResult UpdateMany(IClientSessionHandle session, FilterDefinition filter, UpdateDefinition update, UpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.UpdateMany(session, filter, update, options, cancellationToken); } public Task UpdateManyAsync(FilterDefinition filter, UpdateDefinition update, UpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.UpdateManyAsync(filter, update, options, cancellationToken); } public Task UpdateManyAsync(IClientSessionHandle session, FilterDefinition filter, UpdateDefinition update, UpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.UpdateManyAsync(session, filter, update, options, cancellationToken); } public UpdateResult UpdateOne(FilterDefinition filter, UpdateDefinition update, UpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.UpdateOne(filter, update, options, cancellationToken); } public UpdateResult UpdateOne(IClientSessionHandle session, FilterDefinition filter, UpdateDefinition update, UpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.UpdateOne(session, filter, update, options, cancellationToken); } public Task UpdateOneAsync(FilterDefinition filter, UpdateDefinition update, UpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.UpdateOneAsync(filter, update, options, cancellationToken); } public Task UpdateOneAsync(IClientSessionHandle session, FilterDefinition filter, UpdateDefinition update, UpdateOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { CheckTimout(); return _collection.UpdateOneAsync(session, filter, update, options, cancellationToken); } public IChangeStreamCursor Watch(PipelineDefinition, TResult> pipeline, ChangeStreamOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.Watch(pipeline, options, cancellationToken); } public IChangeStreamCursor Watch(IClientSessionHandle session, PipelineDefinition, TResult> pipeline, ChangeStreamOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.Watch(session, pipeline, options, cancellationToken); } public Task> WatchAsync(PipelineDefinition, TResult> pipeline, ChangeStreamOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.WatchAsync(pipeline, options, cancellationToken); } public Task> WatchAsync(IClientSessionHandle session, PipelineDefinition, TResult> pipeline, ChangeStreamOptions options = null, CancellationToken cancellationToken = new CancellationToken()) { return _collection.WatchAsync(session, pipeline, options, cancellationToken); } public IMongoCollection WithReadConcern(ReadConcern readConcern) { return _collection.WithReadConcern(readConcern); } public IMongoCollection WithReadPreference(ReadPreference readPreference) { return _collection.WithReadPreference(readPreference); } public IMongoCollection WithWriteConcern(WriteConcern writeConcern) { return _collection.WithWriteConcern(writeConcern); } public CollectionNamespace CollectionNamespace => _collection.CollectionNamespace; public IMongoDatabase Database => _collection.Database; public IBsonSerializer DocumentSerializer => _collection.DocumentSerializer; public IMongoIndexManager Indexes => _collection.Indexes; public MongoCollectionSettings Settings => _collection.Settings; }