Author: mreutegg
Date: Tue Jul 24 09:15:37 2018
New Revision: 1836537

URL: http://svn.apache.org/viewvc?rev=1836537&view=rev
Log:
OAK-7655: Replace fongo dependency with custom test wrapper

Added:
    
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestClient.java
   (with props)
    
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestCollection.java
   (with props)
    
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestDatabase.java
   (with props)
Removed:
    jackrabbit/oak/trunk/oak-store-document/src/test/java/com/
Modified:
    jackrabbit/oak/trunk/oak-store-document/pom.xml
    
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
    
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java
    
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoCacheConsistencyTest.java
    
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java

Modified: jackrabbit/oak/trunk/oak-store-document/pom.xml
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/pom.xml?rev=1836537&r1=1836536&r2=1836537&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-store-document/pom.xml Tue Jul 24 09:15:37 2018
@@ -318,12 +318,6 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>com.github.fakemongo</groupId>
-      <artifactId>fongo</artifactId>
-      <version>2.2.0-RC1</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>de.flapdoodle.embed</groupId>
       <artifactId>de.flapdoodle.embed.mongo</artifactId>
       <version>2.0.0</version>

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java?rev=1836537&r1=1836536&r2=1836537&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/MongoConnection.java
 Tue Jul 24 09:15:37 2018
@@ -87,6 +87,17 @@ public class MongoConnection {
     }
 
     /**
+     * Constructs a new {@code MongoConnection}.
+     *
+     * @param uri the connection URI.
+     * @param client the already connected client.
+     */
+    public MongoConnection(String uri, MongoClient client) {
+        mongoURI = new MongoClientURI(uri, 
MongoConnection.getDefaultBuilder());
+        mongo = client;
+    }
+
+    /**
      * @return the {@link MongoClient} for this connection.
      */
     public MongoClient getMongoClient() {

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java?rev=1836537&r1=1836536&r2=1836537&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java
 Tue Jul 24 09:15:37 2018
@@ -201,7 +201,7 @@ public abstract class DocumentStoreFixtu
     }
 
     public static class MongoFixture extends DocumentStoreFixture {
-        private List<MongoConnection> connections = Lists.newArrayList();
+        protected List<MongoConnection> connections = Lists.newArrayList();
 
         @Override
         public String getName() {

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoCacheConsistencyTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoCacheConsistencyTest.java?rev=1836537&r1=1836536&r2=1836537&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoCacheConsistencyTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoCacheConsistencyTest.java
 Tue Jul 24 09:15:37 2018
@@ -16,21 +16,16 @@
  */
 package org.apache.jackrabbit.oak.plugins.document.mongo;
 
-import java.util.List;
-
-import com.github.fakemongo.Fongo;
-import com.mongodb.BulkWriteResult;
-import com.mongodb.DBObject;
-import com.mongodb.MongoException;
-import com.mongodb.OakFongo;
-import com.mongodb.WriteConcern;
-import com.mongodb.WriteResult;
-
 import org.apache.jackrabbit.oak.plugins.document.CacheConsistencyTestBase;
 import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
 import org.apache.jackrabbit.oak.plugins.document.DocumentMKBuilderProvider;
 import org.apache.jackrabbit.oak.plugins.document.DocumentStore;
 import org.apache.jackrabbit.oak.plugins.document.DocumentStoreFixture;
+import org.apache.jackrabbit.oak.plugins.document.MongoConnectionFactory;
+import org.apache.jackrabbit.oak.plugins.document.MongoUtils;
+import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection;
+import org.junit.Assume;
+import org.junit.BeforeClass;
 import org.junit.Rule;
 
 public class MongoCacheConsistencyTest extends CacheConsistencyTestBase {
@@ -38,75 +33,32 @@ public class MongoCacheConsistencyTest e
     @Rule
     public DocumentMKBuilderProvider provider = new 
DocumentMKBuilderProvider();
 
-    private String exceptionMsg;
-
-    @Override
-    public DocumentStoreFixture getFixture() throws Exception {
-        Fongo fongo = new OakFongo("fongo") {
-
-            private String suppressedEx = null;
-
-            @Override
-            protected void afterInsert(WriteResult result) {
-                maybeThrow();
-            }
-
-            @Override
-            protected void afterFindAndModify(DBObject result) {
-                maybeThrow();
-            }
-
-            @Override
-            protected void afterUpdate(WriteResult result) {
-                maybeThrow();
-            }
-
-            @Override
-            protected void afterRemove(WriteResult result) {
-                maybeThrow();
-            }
-
-            @Override
-            protected void beforeExecuteBulkWriteOperation(boolean ordered,
-                                                           Boolean 
bypassDocumentValidation,
-                                                           List<?> 
writeRequests,
-                                                           WriteConcern 
aWriteConcern) {
-                // suppress potentially set exception message because
-                // fongo bulk writes call other update methods
-                suppressedEx = exceptionMsg;
-                exceptionMsg = null;
-            }
+    @Rule
+    public MongoConnectionFactory connectionFactory = new 
MongoConnectionFactory();
 
-            @Override
-            protected void afterExecuteBulkWriteOperation(BulkWriteResult 
result) {
-                exceptionMsg = suppressedEx;
-                suppressedEx = null;
-                maybeThrow();
-            }
+    private MongoTestClient client;
 
-            private void maybeThrow() {
-                if (exceptionMsg != null) {
-                    throw new MongoException(exceptionMsg);
-                }
-            }
-        };
-        DocumentMK.Builder builder = provider.newBuilder().setAsyncDelay(0);
-        final DocumentStore store = new MongoDocumentStore(fongo.getMongo(), 
"oak", builder);
-        return new DocumentStoreFixture() {
-            @Override
-            public String getName() {
-                return "MongoDB";
-            }
+    @BeforeClass
+    public static void checkMongoAvailable() {
+        Assume.assumeTrue(MongoUtils.isAvailable());
+    }
 
+    @Override
+    public DocumentStoreFixture getFixture() {
+        return new DocumentStoreFixture.MongoFixture() {
             @Override
             public DocumentStore createDocumentStore(DocumentMK.Builder 
builder) {
-                return store;
+                client = new MongoTestClient(MongoUtils.URL);
+                MongoConnection c = new MongoConnection(MongoUtils.URL, 
client);
+                connections.add(c);
+                builder.setAsyncDelay(0).setMongoDB(client, MongoUtils.DB);
+                return builder.getDocumentStore();
             }
         };
     }
 
     @Override
     public void setTemporaryUpdateException(String msg) {
-        this.exceptionMsg = msg;
+        client.setExceptionAfterUpdate(msg);
     }
 }

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java?rev=1836537&r1=1836536&r2=1836537&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDBExceptionTest.java
 Tue Jul 24 09:15:37 2018
@@ -16,22 +16,18 @@
  */
 package org.apache.jackrabbit.oak.plugins.document.mongo;
 
-import java.util.List;
-
-import com.mongodb.DBEncoder;
-import com.mongodb.DBObject;
-import com.mongodb.MongoException;
-import com.mongodb.OakFongo;
-import com.mongodb.WriteConcern;
-
 import org.apache.jackrabbit.oak.plugins.document.Collection;
 import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
 import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException;
+import org.apache.jackrabbit.oak.plugins.document.MongoUtils;
 import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
 import org.apache.jackrabbit.oak.plugins.document.Revision;
 import org.apache.jackrabbit.oak.plugins.document.UpdateOp;
 import org.apache.jackrabbit.oak.plugins.document.util.Utils;
+import org.junit.After;
+import org.junit.Assume;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 import static java.util.Collections.singletonList;
@@ -46,56 +42,28 @@ public class MongoDBExceptionTest {
 
     private String exceptionMsg;
 
+    private MongoTestClient client;
+
+    @BeforeClass
+    public static void checkMongoAvailable() {
+        Assume.assumeTrue(MongoUtils.isAvailable());
+    }
+
     @Before
-    public void before() throws Exception {
-        OakFongo fongo = new OakFongo("fongo") {
-            @Override
-            protected void beforeExecuteBulkWriteOperation(boolean ordered,
-                                                           Boolean 
bypassDocumentValidation,
-                                                           List<?> 
writeRequests,
-                                                           WriteConcern 
aWriteConcern) {
-                maybeThrow();
-            }
-
-            @Override
-            protected void beforeFindAndModify(DBObject query,
-                                               DBObject fields,
-                                               DBObject sort,
-                                               boolean remove,
-                                               DBObject update,
-                                               boolean returnNew,
-                                               boolean upsert) {
-                maybeThrow();
-            }
-
-            @Override
-            protected void beforeUpdate(DBObject q,
-                                        DBObject o,
-                                        boolean upsert,
-                                        boolean multi,
-                                        WriteConcern concern,
-                                        DBEncoder encoder) {
-                maybeThrow();
-            }
-
-            @Override
-            protected void beforeFind(DBObject query, DBObject projection) {
-                maybeThrow();
-            }
-
-            private void maybeThrow() {
-                if (exceptionMsg != null) {
-                    throw new MongoException(exceptionMsg);
-                }
-            }
-        };
-        store = new MongoDocumentStore(fongo.getMongo(), "oak",
+    public void before() {
+        MongoUtils.dropCollections(MongoUtils.DB);
+        client = new MongoTestClient(MongoUtils.URL);
+        store = new MongoDocumentStore(client, MongoUtils.DB,
                 new DocumentMK.Builder());
+    }
 
+    @After
+    public void after() {
+        MongoUtils.dropCollections(MongoUtils.DB);
     }
 
     @Test
-    public void idInExceptionMessage() throws Exception {
+    public void idInExceptionMessage() {
         String id = Utils.getIdFromPath("/foo");
         UpdateOp insert = new UpdateOp(id, true);
         assertTrue(store.create(Collection.NODES, singletonList(insert)));
@@ -103,6 +71,7 @@ public class MongoDBExceptionTest {
         UpdateOp op = new UpdateOp(id, false);
         NodeDocument.setModified(op, new Revision(System.currentTimeMillis(), 
0, 1));
         exceptionMsg = "findAndUpdate failed";
+        setExceptionMsg();
         try {
             store.findAndUpdate(Collection.NODES, op);
             fail("DocumentStoreException expected");
@@ -113,6 +82,7 @@ public class MongoDBExceptionTest {
         }
 
         exceptionMsg = "createOrUpdate failed";
+        setExceptionMsg();
         try {
             store.createOrUpdate(Collection.NODES, op);
             fail("DocumentStoreException expected");
@@ -123,6 +93,7 @@ public class MongoDBExceptionTest {
         }
 
         exceptionMsg = "createOrUpdate (multiple) failed";
+        setExceptionMsg();
         try {
             store.createOrUpdate(Collection.NODES, singletonList(op));
             fail("DocumentStoreException expected");
@@ -133,6 +104,7 @@ public class MongoDBExceptionTest {
         }
 
         exceptionMsg = "find failed";
+        setExceptionMsg();
         try {
             store.find(Collection.NODES, id);
             fail("DocumentStoreException expected");
@@ -145,6 +117,7 @@ public class MongoDBExceptionTest {
         String fromKey = Utils.getKeyLowerLimit("/foo");
         String toKey = Utils.getKeyUpperLimit("/foo");
         exceptionMsg = "query failed";
+        setExceptionMsg();
         try {
             store.query(Collection.NODES, fromKey, toKey, 100);
             fail("DocumentStoreException expected");
@@ -156,4 +129,9 @@ public class MongoDBExceptionTest {
                     e.getMessage().contains(toKey));
         }
     }
+
+    private void setExceptionMsg() {
+        client.setExceptionBeforeUpdate(exceptionMsg);
+        client.setExceptionBeforeQuery(exceptionMsg);
+    }
 }

Added: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestClient.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestClient.java?rev=1836537&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestClient.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestClient.java
 Tue Jul 24 09:15:37 2018
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.oak.plugins.document.mongo;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientURI;
+import com.mongodb.client.MongoDatabase;
+
+import org.jetbrains.annotations.NotNull;
+
+class MongoTestClient extends MongoClient {
+
+    private AtomicReference<String> beforeQueryException = new 
AtomicReference<>();
+    private AtomicReference<String> beforeUpdateException = new 
AtomicReference<>();
+    private AtomicReference<String> afterUpdateException = new 
AtomicReference<>();
+
+    MongoTestClient(String uri) {
+        super(new MongoClientURI(uri));
+    }
+
+    @NotNull
+    @Override
+    public MongoDatabase getDatabase(String databaseName) {
+        return new MongoTestDatabase(super.getDatabase(databaseName),
+                beforeQueryException, beforeUpdateException, 
afterUpdateException);
+    }
+
+    void setExceptionBeforeQuery(String msg) {
+        beforeQueryException.set(msg);
+    }
+
+    void setExceptionBeforeUpdate(String msg) {
+        beforeUpdateException.set(msg);
+    }
+
+    void setExceptionAfterUpdate(String msg) {
+        afterUpdateException.set(msg);
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestClient.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestCollection.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestCollection.java?rev=1836537&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestCollection.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestCollection.java
 Tue Jul 24 09:15:37 2018
@@ -0,0 +1,1021 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.oak.plugins.document.mongo;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.mongodb.MongoException;
+import com.mongodb.MongoNamespace;
+import com.mongodb.ReadConcern;
+import com.mongodb.ReadPreference;
+import com.mongodb.WriteConcern;
+import com.mongodb.bulk.BulkWriteResult;
+import com.mongodb.client.AggregateIterable;
+import com.mongodb.client.ChangeStreamIterable;
+import com.mongodb.client.DistinctIterable;
+import com.mongodb.client.FindIterable;
+import com.mongodb.client.ListIndexesIterable;
+import com.mongodb.client.MapReduceIterable;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.model.BulkWriteOptions;
+import com.mongodb.client.model.CountOptions;
+import com.mongodb.client.model.CreateIndexOptions;
+import com.mongodb.client.model.DeleteOptions;
+import com.mongodb.client.model.DropIndexOptions;
+import com.mongodb.client.model.FindOneAndDeleteOptions;
+import com.mongodb.client.model.FindOneAndReplaceOptions;
+import com.mongodb.client.model.FindOneAndUpdateOptions;
+import com.mongodb.client.model.IndexModel;
+import com.mongodb.client.model.IndexOptions;
+import com.mongodb.client.model.InsertManyOptions;
+import com.mongodb.client.model.InsertOneOptions;
+import com.mongodb.client.model.RenameCollectionOptions;
+import com.mongodb.client.model.UpdateOptions;
+import com.mongodb.client.model.WriteModel;
+import com.mongodb.client.result.DeleteResult;
+import com.mongodb.client.result.UpdateResult;
+import com.mongodb.session.ClientSession;
+
+import org.bson.Document;
+import org.bson.codecs.configuration.CodecRegistry;
+import org.bson.conversions.Bson;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+class MongoTestCollection<TDocument> implements MongoCollection<TDocument> {
+
+    private final MongoCollection<TDocument> collection;
+
+    private final AtomicReference<String> beforeQueryException;
+    private final AtomicReference<String> beforeUpdateException;
+    private final AtomicReference<String> afterUpdateException;
+
+    MongoTestCollection(MongoCollection<TDocument> collection,
+                        AtomicReference<String> beforeQueryException,
+                        AtomicReference<String> beforeUpdateException,
+                        AtomicReference<String> afterUpdateException) {
+        this.collection = collection;
+        this.beforeQueryException = beforeQueryException;
+        this.beforeUpdateException = beforeUpdateException;
+        this.afterUpdateException = afterUpdateException;
+    }
+
+    @NotNull
+    @Override
+    public MongoNamespace getNamespace() {
+        return collection.getNamespace();
+    }
+
+    @NotNull
+    @Override
+    public Class<TDocument> getDocumentClass() {
+        return collection.getDocumentClass();
+    }
+
+    @NotNull
+    @Override
+    public CodecRegistry getCodecRegistry() {
+        return collection.getCodecRegistry();
+    }
+
+    @NotNull
+    @Override
+    public ReadPreference getReadPreference() {
+        return collection.getReadPreference();
+    }
+
+    @NotNull
+    @Override
+    public WriteConcern getWriteConcern() {
+        return collection.getWriteConcern();
+    }
+
+    @NotNull
+    @Override
+    public ReadConcern getReadConcern() {
+        return collection.getReadConcern();
+    }
+
+    @NotNull
+    @Override
+    public <NewTDocument> MongoCollection<NewTDocument> 
withDocumentClass(@NotNull Class<NewTDocument> clazz) {
+        return new MongoTestCollection<>(collection.withDocumentClass(clazz), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public MongoCollection<TDocument> withCodecRegistry(@NotNull CodecRegistry 
codecRegistry) {
+        return new 
MongoTestCollection<>(collection.withCodecRegistry(codecRegistry), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public MongoCollection<TDocument> withReadPreference(@NotNull 
ReadPreference readPreference) {
+        return new 
MongoTestCollection<>(collection.withReadPreference(readPreference), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public MongoCollection<TDocument> withWriteConcern(@NotNull WriteConcern 
writeConcern) {
+        return new 
MongoTestCollection<>(collection.withWriteConcern(writeConcern), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public MongoCollection<TDocument> withReadConcern(@NotNull ReadConcern 
readConcern) {
+        return new 
MongoTestCollection<>(collection.withReadConcern(readConcern), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @Override
+    @Deprecated
+    public long count() {
+        return collection.count();
+    }
+
+    @Override
+    @Deprecated
+    public long count(@NotNull Bson filter) {
+        return collection.count(filter);
+    }
+
+    @Override
+    @Deprecated
+    public long count(@NotNull Bson filter, @NotNull CountOptions options) {
+        return collection.count(filter, options);
+    }
+
+    @Override
+    @Deprecated
+    public long count(@NotNull ClientSession clientSession) {
+        return collection.count(clientSession);
+    }
+
+    @Override
+    @Deprecated
+    public long count(@NotNull ClientSession clientSession, @NotNull Bson 
filter) {
+        return collection.count(clientSession, filter);
+    }
+
+    @Override
+    @Deprecated
+    public long count(@NotNull ClientSession clientSession,
+                      @NotNull Bson filter,
+                      @NotNull CountOptions options) {
+        return collection.count(clientSession, filter, options);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> DistinctIterable<TResult> distinct(@NotNull String 
fieldName,
+                                                        @NotNull 
Class<TResult> tResultClass) {
+        return collection.distinct(fieldName, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> DistinctIterable<TResult> distinct(@NotNull String 
fieldName,
+                                                        @NotNull Bson filter,
+                                                        @NotNull 
Class<TResult> tResultClass) {
+        return collection.distinct(fieldName, filter, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> DistinctIterable<TResult> distinct(@NotNull ClientSession 
clientSession,
+                                                        @NotNull String 
fieldName,
+                                                        @NotNull 
Class<TResult> tResultClass) {
+        return collection.distinct(clientSession, fieldName, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> DistinctIterable<TResult> distinct(@NotNull ClientSession 
clientSession,
+                                                        @NotNull String 
fieldName,
+                                                        @NotNull Bson filter,
+                                                        @NotNull 
Class<TResult> tResultClass) {
+        return collection.distinct(clientSession, fieldName, filter, 
tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public FindIterable<TDocument> find() {
+        maybeThrowExceptionBeforeQuery();
+        return collection.find();
+    }
+
+    @NotNull
+    @Override
+    public <TResult> FindIterable<TResult> find(@NotNull Class<TResult> 
tResultClass) {
+        maybeThrowExceptionBeforeQuery();
+        return collection.find(tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public FindIterable<TDocument> find(@NotNull Bson filter) {
+        maybeThrowExceptionBeforeQuery();
+        return collection.find(filter);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> FindIterable<TResult> find(@NotNull Bson filter,
+                                                @NotNull Class<TResult> 
tResultClass) {
+        maybeThrowExceptionBeforeQuery();
+        return collection.find(filter, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public FindIterable<TDocument> find(@NotNull ClientSession clientSession) {
+        maybeThrowExceptionBeforeQuery();
+        return collection.find(clientSession);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> FindIterable<TResult> find(@NotNull ClientSession 
clientSession,
+                                                @NotNull Class<TResult> 
tResultClass) {
+        maybeThrowExceptionBeforeQuery();
+        return collection.find(clientSession, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public FindIterable<TDocument> find(@NotNull ClientSession clientSession,
+                                        @NotNull Bson filter) {
+        maybeThrowExceptionBeforeQuery();
+        return collection.find(clientSession, filter);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> FindIterable<TResult> find(@NotNull ClientSession 
clientSession,
+                                                @NotNull Bson filter,
+                                                @NotNull Class<TResult> 
tResultClass) {
+        maybeThrowExceptionBeforeQuery();
+        return collection.find(clientSession, filter, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public AggregateIterable<TDocument> aggregate(@NotNull List<? extends 
Bson> pipeline) {
+        return collection.aggregate(pipeline);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> AggregateIterable<TResult> aggregate(@NotNull List<? 
extends Bson> pipeline,
+                                                          @NotNull 
Class<TResult> tResultClass) {
+        return collection.aggregate(pipeline, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public AggregateIterable<TDocument> aggregate(@NotNull ClientSession 
clientSession,
+                                                  @NotNull List<? extends 
Bson> pipeline) {
+        return collection.aggregate(clientSession, pipeline);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> AggregateIterable<TResult> aggregate(@NotNull 
ClientSession clientSession,
+                                                          @NotNull List<? 
extends Bson> pipeline,
+                                                          @NotNull 
Class<TResult> tResultClass) {
+        return collection.aggregate(clientSession, pipeline, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public ChangeStreamIterable<TDocument> watch() {
+        return collection.watch();
+    }
+
+    @NotNull
+    @Override
+    public <TResult> ChangeStreamIterable<TResult> watch(@NotNull 
Class<TResult> tResultClass) {
+        return collection.watch(tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public ChangeStreamIterable<TDocument> watch(@NotNull List<? extends Bson> 
pipeline) {
+        return collection.watch(pipeline);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> ChangeStreamIterable<TResult> watch(@NotNull List<? 
extends Bson> pipeline,
+                                                         @NotNull 
Class<TResult> tResultClass) {
+        return collection.watch(pipeline, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public ChangeStreamIterable<TDocument> watch(@NotNull ClientSession 
clientSession) {
+        return collection.watch(clientSession);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> ChangeStreamIterable<TResult> watch(@NotNull 
ClientSession clientSession,
+                                                         @NotNull 
Class<TResult> tResultClass) {
+        return collection.watch(clientSession, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public ChangeStreamIterable<TDocument> watch(@NotNull ClientSession 
clientSession,
+                                                 @NotNull List<? extends Bson> 
pipeline) {
+        return collection.watch(clientSession, pipeline);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> ChangeStreamIterable<TResult> watch(@NotNull 
ClientSession clientSession,
+                                                         @NotNull List<? 
extends Bson> pipeline,
+                                                         @NotNull 
Class<TResult> tResultClass) {
+        return collection.watch(clientSession, pipeline, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public MapReduceIterable<TDocument> mapReduce(@NotNull String mapFunction,
+                                                  @NotNull String 
reduceFunction) {
+        return collection.mapReduce(mapFunction, reduceFunction);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> MapReduceIterable<TResult> mapReduce(@NotNull String 
mapFunction,
+                                                          @NotNull String 
reduceFunction,
+                                                          @NotNull 
Class<TResult> tResultClass) {
+        return collection.mapReduce(mapFunction, reduceFunction, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public MapReduceIterable<TDocument> mapReduce(@NotNull ClientSession 
clientSession,
+                                                  @NotNull String mapFunction,
+                                                  @NotNull String 
reduceFunction) {
+        return collection.mapReduce(clientSession, mapFunction, 
reduceFunction);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> MapReduceIterable<TResult> mapReduce(@NotNull 
ClientSession clientSession,
+                                                          @NotNull String 
mapFunction,
+                                                          @NotNull String 
reduceFunction,
+                                                          @NotNull 
Class<TResult> tResultClass) {
+        return collection.mapReduce(clientSession, mapFunction, 
reduceFunction, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public BulkWriteResult bulkWrite(@NotNull List<? extends WriteModel<? 
extends TDocument>> requests) {
+        maybeThrowExceptionBeforeUpdate();
+        BulkWriteResult result = collection.bulkWrite(requests);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public BulkWriteResult bulkWrite(@NotNull List<? extends WriteModel<? 
extends TDocument>> requests,
+                                     @NotNull BulkWriteOptions options) {
+        maybeThrowExceptionBeforeUpdate();
+        BulkWriteResult result = collection.bulkWrite(requests, options);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public BulkWriteResult bulkWrite(@NotNull ClientSession clientSession,
+                                     @NotNull List<? extends WriteModel<? 
extends TDocument>> requests) {
+        maybeThrowExceptionBeforeUpdate();
+        BulkWriteResult result = collection.bulkWrite(clientSession, requests);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public BulkWriteResult bulkWrite(@NotNull ClientSession clientSession,
+                                     @NotNull List<? extends WriteModel<? 
extends TDocument>> requests,
+                                     @NotNull BulkWriteOptions options) {
+        maybeThrowExceptionBeforeUpdate();
+        BulkWriteResult result = collection.bulkWrite(clientSession, requests, 
options);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @Override
+    public void insertOne(@NotNull TDocument tDocument) {
+        maybeThrowExceptionBeforeUpdate();
+        collection.insertOne(tDocument);
+        maybeThrowExceptionAfterUpdate();
+    }
+
+    @Override
+    public void insertOne(@NotNull TDocument tDocument, @NotNull 
InsertOneOptions options) {
+        maybeThrowExceptionBeforeUpdate();
+        collection.insertOne(tDocument, options);
+        maybeThrowExceptionAfterUpdate();
+    }
+
+    @Override
+    public void insertOne(@NotNull ClientSession clientSession, @NotNull 
TDocument tDocument) {
+        maybeThrowExceptionBeforeUpdate();
+        collection.insertOne(clientSession, tDocument);
+        maybeThrowExceptionAfterUpdate();
+    }
+
+    @Override
+    public void insertOne(@NotNull ClientSession clientSession,
+                          @NotNull TDocument tDocument,
+                          @NotNull InsertOneOptions options) {
+        maybeThrowExceptionBeforeUpdate();
+        collection.insertOne(clientSession, tDocument, options);
+        maybeThrowExceptionAfterUpdate();
+    }
+
+    @Override
+    public void insertMany(@NotNull List<? extends TDocument> tDocuments) {
+        maybeThrowExceptionBeforeUpdate();
+        collection.insertMany(tDocuments);
+        maybeThrowExceptionAfterUpdate();
+    }
+
+    @Override
+    public void insertMany(@NotNull List<? extends TDocument> tDocuments,
+                           @NotNull InsertManyOptions options) {
+        maybeThrowExceptionBeforeUpdate();
+        collection.insertMany(tDocuments, options);
+        maybeThrowExceptionAfterUpdate();
+    }
+
+    @Override
+    public void insertMany(@NotNull ClientSession clientSession,
+                           @NotNull List<? extends TDocument> tDocuments) {
+        maybeThrowExceptionBeforeUpdate();
+        collection.insertMany(clientSession, tDocuments);
+        maybeThrowExceptionAfterUpdate();
+    }
+
+    @Override
+    public void insertMany(@NotNull ClientSession clientSession,
+                           @NotNull List<? extends TDocument> tDocuments,
+                           @NotNull InsertManyOptions options) {
+        maybeThrowExceptionBeforeUpdate();
+        collection.insertMany(clientSession, tDocuments, options);
+        maybeThrowExceptionAfterUpdate();
+    }
+
+    @NotNull
+    @Override
+    public DeleteResult deleteOne(@NotNull Bson filter) {
+        maybeThrowExceptionBeforeUpdate();
+        DeleteResult result = collection.deleteOne(filter);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public DeleteResult deleteOne(@NotNull Bson filter, @NotNull DeleteOptions 
options) {
+        maybeThrowExceptionBeforeUpdate();
+        DeleteResult result = collection.deleteOne(filter, options);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public DeleteResult deleteOne(@NotNull ClientSession clientSession, 
@NotNull Bson filter) {
+        maybeThrowExceptionBeforeUpdate();
+        DeleteResult result = collection.deleteOne(clientSession, filter);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public DeleteResult deleteOne(@NotNull ClientSession clientSession,
+                                  @NotNull Bson filter,
+                                  @NotNull DeleteOptions options) {
+        maybeThrowExceptionBeforeUpdate();
+        DeleteResult result = collection.deleteOne(clientSession, filter, 
options);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public DeleteResult deleteMany(@NotNull Bson filter) {
+        maybeThrowExceptionBeforeUpdate();
+        DeleteResult result = collection.deleteMany(filter);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public DeleteResult deleteMany(@NotNull Bson filter, @NotNull 
DeleteOptions options) {
+        maybeThrowExceptionBeforeUpdate();
+        DeleteResult result = collection.deleteMany(filter, options);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public DeleteResult deleteMany(@NotNull ClientSession clientSession, 
@NotNull Bson filter) {
+        maybeThrowExceptionBeforeUpdate();
+        DeleteResult result = collection.deleteMany(clientSession, filter);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public DeleteResult deleteMany(@NotNull ClientSession clientSession,
+                                   @NotNull Bson filter,
+                                   @NotNull DeleteOptions options) {
+        maybeThrowExceptionBeforeUpdate();
+        DeleteResult result = collection.deleteMany(clientSession, filter, 
options);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult replaceOne(@NotNull Bson filter, @NotNull TDocument 
replacement) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.replaceOne(filter, replacement);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    @Deprecated
+    public UpdateResult replaceOne(@NotNull Bson filter,
+                                   @NotNull TDocument replacement,
+                                   @NotNull UpdateOptions updateOptions) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.replaceOne(filter, replacement, 
updateOptions);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult replaceOne(@NotNull ClientSession clientSession,
+                                   @NotNull Bson filter,
+                                   @NotNull TDocument replacement) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.replaceOne(clientSession, filter, 
replacement);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    @Deprecated
+    public UpdateResult replaceOne(@NotNull ClientSession clientSession,
+                                   @NotNull Bson filter,
+                                   @NotNull TDocument replacement,
+                                   @NotNull UpdateOptions updateOptions) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.replaceOne(clientSession, filter, 
replacement, updateOptions);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult updateOne(@NotNull Bson filter, @NotNull Bson update) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.updateOne(filter, update);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult updateOne(@NotNull Bson filter,
+                                  @NotNull Bson update,
+                                  @NotNull UpdateOptions updateOptions) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.updateOne(filter, update, 
updateOptions);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult updateOne(@NotNull ClientSession clientSession,
+                                  @NotNull Bson filter,
+                                  @NotNull Bson update) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.updateOne(clientSession, filter, 
update);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult updateOne(@NotNull ClientSession clientSession,
+                                  @NotNull Bson filter,
+                                  @NotNull Bson update,
+                                  @NotNull UpdateOptions updateOptions) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.updateOne(clientSession, filter, 
update, updateOptions);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult updateMany(@NotNull Bson filter, @NotNull Bson update) 
{
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.updateMany(filter, update);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult updateMany(@NotNull Bson filter,
+                                   @NotNull Bson update,
+                                   @NotNull UpdateOptions updateOptions) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.updateMany(filter, update, 
updateOptions);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult updateMany(@NotNull ClientSession clientSession,
+                                   @NotNull Bson filter,
+                                   @NotNull Bson update) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.updateMany(clientSession, filter, 
update);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @NotNull
+    @Override
+    public UpdateResult updateMany(@NotNull ClientSession clientSession,
+                                   @NotNull Bson filter,
+                                   @NotNull Bson update,
+                                   @NotNull UpdateOptions updateOptions) {
+        maybeThrowExceptionBeforeUpdate();
+        UpdateResult result = collection.updateMany(clientSession, filter, 
update, updateOptions);
+        maybeThrowExceptionAfterUpdate();
+        return result;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndDelete(@NotNull Bson filter) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndDelete(filter);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndDelete(@NotNull Bson filter,
+                                      @NotNull FindOneAndDeleteOptions 
options) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndDelete(filter, options);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndDelete(@NotNull ClientSession clientSession,
+                                      @NotNull Bson filter) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndDelete(clientSession, filter);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndDelete(@NotNull ClientSession clientSession,
+                                      @NotNull Bson filter,
+                                      @NotNull FindOneAndDeleteOptions 
options) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndDelete(clientSession, filter, 
options);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndReplace(@NotNull Bson filter, @NotNull 
TDocument replacement) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndReplace(filter, replacement);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndReplace(@NotNull Bson filter,
+                                       @NotNull TDocument replacement,
+                                       @NotNull FindOneAndReplaceOptions 
options) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndReplace(filter, replacement, 
options);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndReplace(@NotNull ClientSession clientSession,
+                                       @NotNull Bson filter,
+                                       @NotNull TDocument replacement) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndReplace(clientSession, filter, 
replacement);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndReplace(@NotNull ClientSession clientSession,
+                                       @NotNull Bson filter,
+                                       @NotNull TDocument replacement,
+                                       @NotNull FindOneAndReplaceOptions 
options) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndReplace(clientSession, filter, 
replacement, options);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndUpdate(@NotNull Bson filter, @NotNull Bson 
update) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndUpdate(filter, update);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndUpdate(@NotNull Bson filter,
+                                      @NotNull Bson update,
+                                      @NotNull FindOneAndUpdateOptions 
options) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndUpdate(filter, update, options);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndUpdate(@NotNull ClientSession clientSession,
+                                      @NotNull Bson filter,
+                                      @NotNull Bson update) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndUpdate(clientSession, filter, 
update);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    @Nullable
+    public TDocument findOneAndUpdate(@NotNull ClientSession clientSession,
+                                      @NotNull Bson filter,
+                                      @NotNull Bson update,
+                                      @NotNull FindOneAndUpdateOptions 
options) {
+        maybeThrowExceptionBeforeUpdate();
+        TDocument doc = collection.findOneAndUpdate(clientSession, filter, 
update, options);
+        maybeThrowExceptionAfterUpdate();
+        return doc;
+    }
+
+    @Override
+    public void drop() {
+        collection.drop();
+    }
+
+    @Override
+    public void drop(@NotNull ClientSession clientSession) {
+        collection.drop(clientSession);
+    }
+
+    @NotNull
+    @Override
+    public String createIndex(@NotNull Bson keys) {
+        return collection.createIndex(keys);
+    }
+
+    @NotNull
+    @Override
+    public String createIndex(@NotNull Bson keys, @NotNull IndexOptions 
indexOptions) {
+        return collection.createIndex(keys, indexOptions);
+    }
+
+    @NotNull
+    @Override
+    public String createIndex(@NotNull ClientSession clientSession, @NotNull 
Bson keys) {
+        return collection.createIndex(clientSession, keys);
+    }
+
+    @NotNull
+    @Override
+    public String createIndex(@NotNull ClientSession clientSession,
+                              @NotNull Bson keys,
+                              @NotNull IndexOptions indexOptions) {
+        return collection.createIndex(clientSession, keys, indexOptions);
+    }
+
+    @NotNull
+    @Override
+    public List<String> createIndexes(@NotNull List<IndexModel> indexes) {
+        return collection.createIndexes(indexes);
+    }
+
+    @NotNull
+    @Override
+    public List<String> createIndexes(@NotNull List<IndexModel> indexes,
+                                      @NotNull CreateIndexOptions 
createIndexOptions) {
+        return collection.createIndexes(indexes, createIndexOptions);
+    }
+
+    @NotNull
+    @Override
+    public List<String> createIndexes(@NotNull ClientSession clientSession,
+                                      @NotNull List<IndexModel> indexes) {
+        return collection.createIndexes(clientSession, indexes);
+    }
+
+    @NotNull
+    @Override
+    public List<String> createIndexes(@NotNull ClientSession clientSession,
+                                      @NotNull List<IndexModel> indexes,
+                                      @NotNull CreateIndexOptions 
createIndexOptions) {
+        return collection.createIndexes(clientSession, indexes, 
createIndexOptions);
+    }
+
+    @NotNull
+    @Override
+    public ListIndexesIterable<Document> listIndexes() {
+        return collection.listIndexes();
+    }
+
+    @NotNull
+    @Override
+    public <TResult> ListIndexesIterable<TResult> listIndexes(@NotNull 
Class<TResult> tResultClass) {
+        return collection.listIndexes(tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public ListIndexesIterable<Document> listIndexes(@NotNull ClientSession 
clientSession) {
+        return collection.listIndexes(clientSession);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> ListIndexesIterable<TResult> listIndexes(@NotNull 
ClientSession clientSession,
+                                                              @NotNull 
Class<TResult> tResultClass) {
+        return collection.listIndexes(clientSession, tResultClass);
+    }
+
+    @Override
+    public void dropIndex(@NotNull String indexName) {
+        collection.dropIndex(indexName);
+    }
+
+    @Override
+    public void dropIndex(@NotNull String indexName, @NotNull DropIndexOptions 
dropIndexOptions) {
+        collection.dropIndex(indexName, dropIndexOptions);
+    }
+
+    @Override
+    public void dropIndex(@NotNull Bson keys) {
+        collection.dropIndex(keys);
+    }
+
+    @Override
+    public void dropIndex(@NotNull Bson keys, @NotNull DropIndexOptions 
dropIndexOptions) {
+        collection.dropIndex(keys, dropIndexOptions);
+    }
+
+    @Override
+    public void dropIndex(@NotNull ClientSession clientSession, @NotNull 
String indexName) {
+        collection.dropIndex(clientSession, indexName);
+    }
+
+    @Override
+    public void dropIndex(@NotNull ClientSession clientSession, @NotNull Bson 
keys) {
+        collection.dropIndex(clientSession, keys);
+    }
+
+    @Override
+    public void dropIndex(@NotNull ClientSession clientSession,
+                          @NotNull String indexName,
+                          @NotNull DropIndexOptions dropIndexOptions) {
+        collection.dropIndex(clientSession, indexName, dropIndexOptions);
+    }
+
+    @Override
+    public void dropIndex(@NotNull ClientSession clientSession,
+                          @NotNull Bson keys,
+                          @NotNull DropIndexOptions dropIndexOptions) {
+        collection.dropIndex(clientSession, keys, dropIndexOptions);
+    }
+
+    @Override
+    public void dropIndexes() {
+        collection.dropIndexes();
+    }
+
+    @Override
+    public void dropIndexes(@NotNull ClientSession clientSession) {
+        collection.dropIndexes(clientSession);
+    }
+
+    @Override
+    public void dropIndexes(@NotNull DropIndexOptions dropIndexOptions) {
+        collection.dropIndexes(dropIndexOptions);
+    }
+
+    @Override
+    public void dropIndexes(@NotNull ClientSession clientSession,
+                            @NotNull DropIndexOptions dropIndexOptions) {
+        collection.dropIndexes(clientSession, dropIndexOptions);
+    }
+
+    @Override
+    public void renameCollection(@NotNull MongoNamespace 
newCollectionNamespace) {
+        collection.renameCollection(newCollectionNamespace);
+    }
+
+    @Override
+    public void renameCollection(@NotNull MongoNamespace 
newCollectionNamespace,
+                                 @NotNull RenameCollectionOptions 
renameCollectionOptions) {
+        collection.renameCollection(newCollectionNamespace, 
renameCollectionOptions);
+    }
+
+    @Override
+    public void renameCollection(@NotNull ClientSession clientSession,
+                                 @NotNull MongoNamespace 
newCollectionNamespace) {
+        collection.renameCollection(clientSession, newCollectionNamespace);
+    }
+
+    @Override
+    public void renameCollection(@NotNull ClientSession clientSession,
+                                 @NotNull MongoNamespace 
newCollectionNamespace,
+                                 @NotNull RenameCollectionOptions 
renameCollectionOptions) {
+        collection.renameCollection(clientSession, newCollectionNamespace, 
renameCollectionOptions);
+    }
+
+    private void maybeThrowExceptionBeforeQuery() {
+        String msg = beforeQueryException.get();
+        if (msg != null) {
+            throw new MongoException(msg);
+        }
+    }
+
+    private void maybeThrowExceptionBeforeUpdate() {
+        String msg = beforeUpdateException.get();
+        if (msg != null) {
+            throw new MongoException(msg);
+        }
+    }
+
+    private void maybeThrowExceptionAfterUpdate() {
+        String msg = afterUpdateException.get();
+        if (msg != null) {
+            throw new MongoException(msg);
+        }
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestCollection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestDatabase.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestDatabase.java?rev=1836537&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestDatabase.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestDatabase.java
 Tue Jul 24 09:15:37 2018
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.oak.plugins.document.mongo;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.mongodb.ReadConcern;
+import com.mongodb.ReadPreference;
+import com.mongodb.WriteConcern;
+import com.mongodb.client.ListCollectionsIterable;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+import com.mongodb.client.MongoIterable;
+import com.mongodb.client.model.CreateCollectionOptions;
+import com.mongodb.client.model.CreateViewOptions;
+import com.mongodb.session.ClientSession;
+
+import org.bson.Document;
+import org.bson.codecs.configuration.CodecRegistry;
+import org.bson.conversions.Bson;
+import org.jetbrains.annotations.NotNull;
+
+class MongoTestDatabase implements MongoDatabase {
+
+    private final MongoDatabase db;
+
+    private final AtomicReference<String> beforeQueryException;
+    private final AtomicReference<String> beforeUpdateException;
+    private final AtomicReference<String> afterUpdateException;
+
+    MongoTestDatabase(MongoDatabase db,
+                      AtomicReference<String> beforeQueryException,
+                      AtomicReference<String> beforeUpdateException,
+                      AtomicReference<String> afterUpdateException) {
+        this.db = db;
+        this.beforeQueryException = beforeQueryException;
+        this.beforeUpdateException = beforeUpdateException;
+        this.afterUpdateException = afterUpdateException;
+    }
+
+    @NotNull
+    @Override
+    public String getName() {
+        return db.getName();
+    }
+
+    @NotNull
+    @Override
+    public CodecRegistry getCodecRegistry() {
+        return db.getCodecRegistry();
+    }
+
+    @NotNull
+    @Override
+    public ReadPreference getReadPreference() {
+        return db.getReadPreference();
+    }
+
+    @NotNull
+    @Override
+    public WriteConcern getWriteConcern() {
+        return db.getWriteConcern();
+    }
+
+    @NotNull
+    @Override
+    public ReadConcern getReadConcern() {
+        return db.getReadConcern();
+    }
+
+    @NotNull
+    @Override
+    public MongoDatabase withCodecRegistry(@NotNull CodecRegistry 
codecRegistry) {
+        return new MongoTestDatabase(db.withCodecRegistry(codecRegistry), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public MongoDatabase withReadPreference(@NotNull ReadPreference 
readPreference) {
+        return new MongoTestDatabase(db.withReadPreference(readPreference), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public MongoDatabase withWriteConcern(@NotNull WriteConcern writeConcern) {
+        return new MongoTestDatabase(db.withWriteConcern(writeConcern), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public MongoDatabase withReadConcern(@NotNull ReadConcern readConcern) {
+        return new MongoTestDatabase(db.withReadConcern(readConcern), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public MongoCollection<Document> getCollection(@NotNull String 
collectionName) {
+        return new MongoTestCollection<>(db.getCollection(collectionName), 
beforeQueryException, beforeUpdateException, afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public <TDocument> MongoCollection<TDocument> getCollection(@NotNull 
String collectionName,
+                                                                @NotNull 
Class<TDocument> tDocumentClass) {
+        return new MongoTestCollection<>(db.getCollection(collectionName, 
tDocumentClass), beforeQueryException, beforeUpdateException, 
afterUpdateException);
+    }
+
+    @NotNull
+    @Override
+    public Document runCommand(@NotNull Bson command) {
+        return db.runCommand(command);
+    }
+
+    @NotNull
+    @Override
+    public Document runCommand(@NotNull Bson command,
+                               @NotNull ReadPreference readPreference) {
+        return db.runCommand(command, readPreference);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> TResult runCommand(@NotNull Bson command,
+                                        @NotNull Class<TResult> tResultClass) {
+        return db.runCommand(command, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> TResult runCommand(@NotNull Bson command,
+                                        @NotNull ReadPreference readPreference,
+                                        @NotNull Class<TResult> tResultClass) {
+        return db.runCommand(command, readPreference, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public Document runCommand(@NotNull ClientSession clientSession,
+                               @NotNull Bson command) {
+        return db.runCommand(clientSession, command);
+    }
+
+    @NotNull
+    @Override
+    public Document runCommand(@NotNull ClientSession clientSession,
+                               @NotNull Bson command,
+                               @NotNull ReadPreference readPreference) {
+        return db.runCommand(clientSession, command, readPreference);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> TResult runCommand(@NotNull ClientSession clientSession,
+                                        @NotNull Bson command,
+                                        @NotNull Class<TResult> tResultClass) {
+        return db.runCommand(clientSession, command, tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> TResult runCommand(@NotNull ClientSession clientSession,
+                                        @NotNull Bson command,
+                                        @NotNull ReadPreference readPreference,
+                                        @NotNull Class<TResult> tResultClass) {
+        return db.runCommand(clientSession, command, readPreference, 
tResultClass);
+    }
+
+    @Override
+    public void drop() {
+        db.drop();
+    }
+
+    @Override
+    public void drop(@NotNull ClientSession clientSession) {
+        db.drop(clientSession);
+    }
+
+    @NotNull
+    @Override
+    public MongoIterable<String> listCollectionNames() {
+        return db.listCollectionNames();
+    }
+
+    @NotNull
+    @Override
+    public ListCollectionsIterable<Document> listCollections() {
+        return db.listCollections();
+    }
+
+    @NotNull
+    @Override
+    public <TResult> ListCollectionsIterable<TResult> listCollections(@NotNull 
Class<TResult> tResultClass) {
+        return db.listCollections(tResultClass);
+    }
+
+    @NotNull
+    @Override
+    public MongoIterable<String> listCollectionNames(@NotNull ClientSession 
clientSession) {
+        return db.listCollectionNames(clientSession);
+    }
+
+    @NotNull
+    @Override
+    public ListCollectionsIterable<Document> listCollections(@NotNull 
ClientSession clientSession) {
+        return db.listCollections(clientSession);
+    }
+
+    @NotNull
+    @Override
+    public <TResult> ListCollectionsIterable<TResult> listCollections(
+            @NotNull ClientSession clientSession,
+            @NotNull Class<TResult> tResultClass) {
+        return db.listCollections(clientSession, tResultClass);
+    }
+
+    @Override
+    public void createCollection(@NotNull String collectionName) {
+        db.createCollection(collectionName);
+    }
+
+    @Override
+    public void createCollection(@NotNull String collectionName,
+                                 @NotNull CreateCollectionOptions 
createCollectionOptions) {
+        db.createCollection(collectionName, createCollectionOptions);
+    }
+
+    @Override
+    public void createCollection(@NotNull ClientSession clientSession,
+                                 @NotNull String collectionName) {
+        db.createCollection(clientSession, collectionName);
+    }
+
+    @Override
+    public void createCollection(@NotNull ClientSession clientSession,
+                                 @NotNull String collectionName,
+                                 @NotNull CreateCollectionOptions 
createCollectionOptions) {
+        db.createCollection(clientSession, collectionName, 
createCollectionOptions);
+    }
+
+    @Override
+    public void createView(@NotNull String viewName,
+                           @NotNull String viewOn,
+                           @NotNull List<? extends Bson> pipeline) {
+        db.createView(viewName, viewOn, pipeline);
+    }
+
+    @Override
+    public void createView(@NotNull String viewName,
+                           @NotNull String viewOn,
+                           @NotNull List<? extends Bson> pipeline,
+                           @NotNull CreateViewOptions createViewOptions) {
+        db.createView(viewName, viewOn, pipeline, createViewOptions);
+    }
+
+    @Override
+    public void createView(@NotNull ClientSession clientSession,
+                           @NotNull String viewName,
+                           @NotNull String viewOn,
+                           @NotNull List<? extends Bson> pipeline) {
+        db.createView(clientSession, viewName, viewOn, pipeline);
+    }
+
+    @Override
+    public void createView(@NotNull ClientSession clientSession,
+                           @NotNull String viewName,
+                           @NotNull String viewOn,
+                           @NotNull List<? extends Bson> pipeline,
+                           @NotNull CreateViewOptions createViewOptions) {
+        db.createView(clientSession, viewName, viewOn, pipeline, 
createViewOptions);
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoTestDatabase.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to