From c1f8769ff8bb2f6e2ebd10a9e492fe83dfc427bc Mon Sep 17 00:00:00 2001 From: Juan Pablo Galeotti Date: Thu, 8 Oct 2026 23:02:12 -0300 Subject: [PATCH 1/5] instrumentation and refactor: separate pipeline-based MongoCollection methods into dedicated replacement classes --- .../methodreplacement/ReplacementList.java | 2 + .../MongoCollectionClassReplacement.java | 82 +---------------- ...CollectionLegacyCountClassReplacement.java | 50 +++++++++++ ...lectionPipelineUpdateClassReplacement.java | 90 +++++++++++++++++++ .../MongoOperationClassReplacement.java | 36 ++++++++ .../MongoCollectionClassReplacementTest.java | 24 ++--- 6 files changed, 191 insertions(+), 93 deletions(-) create mode 100644 client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionLegacyCountClassReplacement.java create mode 100644 client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacement.java diff --git a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/ReplacementList.java b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/ReplacementList.java index 484e039fb4..7c615cdfb2 100644 --- a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/ReplacementList.java +++ b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/ReplacementList.java @@ -59,6 +59,8 @@ public static List getList() { new MessageBodyReaderClassReplacement(), new MethodClassReplacement(), new MongoCollectionClassReplacement(), + new MongoCollectionLegacyCountClassReplacement(), + new MongoCollectionPipelineUpdateClassReplacement(), new MongoTemplateClassReplacement(), new OpenSearchClientClassReplacement(), new Neo4JSessionClassReplacement(), diff --git a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacement.java b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacement.java index 55e7df7d68..a1c0094f6c 100644 --- a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacement.java +++ b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacement.java @@ -132,26 +132,6 @@ public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualTyp return handleUpdate("updateOneClientSessionBsonUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, update, options), filter); } - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") - public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { - return handleUpdate("updateOneBsonPipeline", mongoCollection, Arrays.asList(filter, pipeline), filter); - } - - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") - public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { - return handleUpdate("updateOneBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(filter, pipeline, options), filter); - } - - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneClientSessionBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") - public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { - return handleUpdate("updateOneClientSessionBsonPipeline", mongoCollection, Arrays.asList(clientSession, filter, pipeline), filter); - } - - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneClientSessionBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") - public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { - return handleUpdate("updateOneClientSessionBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, pipeline, options), filter); - } - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update) { return handleUpdate("updateManyBson", mongoCollection, Arrays.asList(filter, update), filter); @@ -172,26 +152,6 @@ public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualTy return handleUpdate("updateManyClientSessionBsonUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, update, options), filter); } - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") - public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { - return handleUpdate("updateManyBsonPipeline", mongoCollection, Arrays.asList(filter, pipeline), filter); - } - - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") - public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { - return handleUpdate("updateManyBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(filter, pipeline, options), filter); - } - - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyClientSessionBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") - public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { - return handleUpdate("updateManyClientSessionBsonPipeline", mongoCollection, Arrays.asList(clientSession, filter, pipeline), filter); - } - - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyClientSessionBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") - public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { - return handleUpdate("updateManyClientSessionBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, pipeline, options), filter); - } - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndDeleteBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndDelete(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleDelete("findOneAndDeleteBson", mongoCollection, Arrays.asList(filter), filter); @@ -232,26 +192,6 @@ public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(ac return handleUpdate("findOneAndUpdateClientSessionBsonFindOneAndUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, update, options), filter); } - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) - public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { - return handleUpdate("findOneAndUpdateBsonPipeline", mongoCollection, Arrays.asList(filter, pipeline), filter); - } - - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateBsonPipelineFindOneAndUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) - public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndUpdateOptions") Object options) { - return handleUpdate("findOneAndUpdateBsonPipelineFindOneAndUpdateOptions", mongoCollection, Arrays.asList(filter, pipeline, options), filter); - } - - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateClientSessionBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) - public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { - return handleUpdate("findOneAndUpdateClientSessionBsonPipeline", mongoCollection, Arrays.asList(clientSession, filter, pipeline), filter); - } - - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateClientSessionBsonPipelineFindOneAndUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) - public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndUpdateOptions") Object options) { - return handleUpdate("findOneAndUpdateClientSessionBsonPipelineFindOneAndUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, pipeline, options), filter); - } - @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndReplaceBsonTDocument", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndReplace(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, Object replacement) { return handleUpdate("findOneAndReplaceBsonTDocument", mongoCollection, Arrays.asList(filter, replacement), filter); @@ -316,27 +256,7 @@ private static Object handleUpdate(String id, Object mongoCollection, List args, Object filter) { - long start = System.currentTimeMillis(); - Method method = retrieveFindMethod(id, mongoCollection); - try { - Object result = method.invoke(mongoCollection, args.toArray()); - long end = System.currentTimeMillis(); - handleMongo(mongoCollection, filter, true, end - start); - return result; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - long end = System.currentTimeMillis(); - handleMongo(mongoCollection, filter, false, end - start); - Throwable cause = e.getCause(); - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } - if (cause instanceof Error) { - throw (Error) cause; - } - throw new RuntimeException(cause); - } + return handleEagerQuery(singleton, id, mongoCollection, args, filter); } /** diff --git a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionLegacyCountClassReplacement.java b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionLegacyCountClassReplacement.java new file mode 100644 index 0000000000..d6c68ac56f --- /dev/null +++ b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionLegacyCountClassReplacement.java @@ -0,0 +1,50 @@ +package org.evomaster.client.java.instrumentation.coverage.methodreplacement.thirdpartyclasses; + +import org.evomaster.client.java.instrumentation.coverage.methodreplacement.Replacement; +import org.evomaster.client.java.instrumentation.coverage.methodreplacement.ThirdPartyCast; +import org.evomaster.client.java.instrumentation.coverage.methodreplacement.UsageFilter; +import org.evomaster.client.java.instrumentation.shared.ReplacementCategory; +import org.evomaster.client.java.instrumentation.shared.ReplacementType; + +import java.util.Arrays; + +/** + * Replacements for MongoCollection.count(...), which was deprecated in driver 3.8 in favor of + * countDocuments(...), and removed in 4.x. + *

+ * This cannot be in {@link MongoCollectionClassReplacement}: all the original methods of a + * replacement class are resolved together, and they all must exist in the driver version + * in use. As count(...) does not exist in recent drivers, having it there would break all the other + * replacements for MongoCollection with those drivers. Here, instead, the methods are resolved + * only if a call to count(...) is replaced, which can only happen with drivers having it. + *

+ * Old versions of Spring Data (2.1 and 2.2) still use count(...) to implement exists and count. + */ +public class MongoCollectionLegacyCountClassReplacement extends MongoOperationClassReplacement { + private static final MongoCollectionLegacyCountClassReplacement singleton = new MongoCollectionLegacyCountClassReplacement(); + + @Override + protected String getNameOfThirdPartyTargetClass() { + return "com.mongodb.client.MongoCollection"; + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) + public static long count(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { + return (long) handleEagerQuery(singleton, "countBson", mongoCollection, Arrays.asList(filter), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countBsonCountOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) + public static long count(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.CountOptions") Object options) { + return (long) handleEagerQuery(singleton, "countBsonCountOptions", mongoCollection, Arrays.asList(filter, options), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) + public static long count_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { + return (long) handleEagerQuery(singleton, "countClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countClientSessionBsonCountOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) + public static long count(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.CountOptions") Object options) { + return (long) handleEagerQuery(singleton, "countClientSessionBsonCountOptions", mongoCollection, Arrays.asList(clientSession, filter, options), filter); + } +} diff --git a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacement.java b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacement.java new file mode 100644 index 0000000000..ce108927a9 --- /dev/null +++ b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacement.java @@ -0,0 +1,90 @@ +package org.evomaster.client.java.instrumentation.coverage.methodreplacement.thirdpartyclasses; + +import org.evomaster.client.java.instrumentation.coverage.methodreplacement.Replacement; +import org.evomaster.client.java.instrumentation.coverage.methodreplacement.ThirdPartyCast; +import org.evomaster.client.java.instrumentation.coverage.methodreplacement.UsageFilter; +import org.evomaster.client.java.instrumentation.shared.ReplacementCategory; +import org.evomaster.client.java.instrumentation.shared.ReplacementType; + +import java.util.Arrays; +import java.util.List; + +/** + * Replacements for the overloads of updateOne, updateMany and findOneAndUpdate that take an + * update pipeline (a list of stages) instead of a single update document. + * Those overloads were added to MongoCollection in driver 3.11. + *

+ * This cannot be in {@link MongoCollectionClassReplacement}: all the original methods of a + * replacement class are resolved together, and they all must exist in the driver version + * in use. With older drivers, having these methods there would break all the other + * replacements for MongoCollection. Here, instead, the methods are resolved + * only if a call with a pipeline is replaced, which can only happen with drivers having it. + */ +public class MongoCollectionPipelineUpdateClassReplacement extends MongoOperationClassReplacement { + private static final MongoCollectionPipelineUpdateClassReplacement singleton = new MongoCollectionPipelineUpdateClassReplacement(); + + @Override + protected String getNameOfThirdPartyTargetClass() { + return "com.mongodb.client.MongoCollection"; + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") + public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { + return handleEagerQuery(singleton, "updateOneBsonPipeline", mongoCollection, Arrays.asList(filter, pipeline), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") + public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { + return handleEagerQuery(singleton, "updateOneBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(filter, pipeline, options), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneClientSessionBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") + public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { + return handleEagerQuery(singleton, "updateOneClientSessionBsonPipeline", mongoCollection, Arrays.asList(clientSession, filter, pipeline), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneClientSessionBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") + public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { + return handleEagerQuery(singleton, "updateOneClientSessionBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, pipeline, options), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") + public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { + return handleEagerQuery(singleton, "updateManyBsonPipeline", mongoCollection, Arrays.asList(filter, pipeline), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") + public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { + return handleEagerQuery(singleton, "updateManyBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(filter, pipeline, options), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyClientSessionBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") + public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { + return handleEagerQuery(singleton, "updateManyClientSessionBsonPipeline", mongoCollection, Arrays.asList(clientSession, filter, pipeline), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyClientSessionBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") + public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { + return handleEagerQuery(singleton, "updateManyClientSessionBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, pipeline, options), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) + public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { + return handleEagerQuery(singleton, "findOneAndUpdateBsonPipeline", mongoCollection, Arrays.asList(filter, pipeline), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateBsonPipelineFindOneAndUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) + public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndUpdateOptions") Object options) { + return handleEagerQuery(singleton, "findOneAndUpdateBsonPipelineFindOneAndUpdateOptions", mongoCollection, Arrays.asList(filter, pipeline, options), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateClientSessionBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) + public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { + return handleEagerQuery(singleton, "findOneAndUpdateClientSessionBsonPipeline", mongoCollection, Arrays.asList(clientSession, filter, pipeline), filter); + } + + @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateClientSessionBsonPipelineFindOneAndUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) + public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndUpdateOptions") Object options) { + return handleEagerQuery(singleton, "findOneAndUpdateClientSessionBsonPipelineFindOneAndUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, pipeline, options), filter); + } +} diff --git a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoOperationClassReplacement.java b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoOperationClassReplacement.java index 44be213a3a..756fa27091 100644 --- a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoOperationClassReplacement.java +++ b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoOperationClassReplacement.java @@ -9,6 +9,7 @@ import org.evomaster.client.java.instrumentation.staticstate.ExecutionTracer; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Collections; import java.util.List; @@ -24,6 +25,41 @@ protected static void handleMongo(Object mongoCollection, Object bson, boolean s } + /** + * Executes an operation that, unlike find, is executed eagerly (eg, count, delete and update), + * so we know right away whether the filter was valid. The query is stored in any case. + * + * @param singleton the replacement class holding the replacement with the given id + * @param id the id of the replacement, used to retrieve the original method + * @param mongoCollection the collection on which the operation is executed + * @param args the arguments of the original call + * @param filter the query used in the operation + * @return the result of the original call + */ + protected static Object handleEagerQuery(ThirdPartyMethodReplacementClass singleton, String id, Object mongoCollection, List args, Object filter) { + long start = System.currentTimeMillis(); + Method method = getOriginal(singleton, id, mongoCollection); + try { + Object result = method.invoke(mongoCollection, args.toArray()); + long end = System.currentTimeMillis(); + handleMongo(mongoCollection, filter, true, end - start); + return result; + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + long end = System.currentTimeMillis(); + handleMongo(mongoCollection, filter, false, end - start); + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } + if (cause instanceof Error) { + throw (Error) cause; + } + throw new RuntimeException(cause); + } + } + private static Class extractDocumentsType(Object collection) { try { Class collectionClass = getCollectionClass(collection); diff --git a/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacementTest.java b/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacementTest.java index b42d64ecc7..a05aa46302 100644 --- a/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacementTest.java +++ b/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacementTest.java @@ -706,7 +706,7 @@ public void testUpdateOneWithFilterAndPipeline() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - UpdateResult result = (UpdateResult) MongoCollectionClassReplacement.updateOne(collection, new Document("age", 30), verifiedPipeline()); + UpdateResult result = (UpdateResult) MongoCollectionPipelineUpdateClassReplacement.updateOne(collection, new Document("age", 30), verifiedPipeline()); assertEquals(1, result.getMatchedCount()); BsonDocument retrievedQuery = assertSingleRecordedCommand(true); @@ -721,7 +721,7 @@ public void testUpdateOneWithFilterPipelineAndOptions() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - UpdateResult result = (UpdateResult) MongoCollectionClassReplacement.updateOne(collection, new Document("age", 30), verifiedPipeline(), new UpdateOptions()); + UpdateResult result = (UpdateResult) MongoCollectionPipelineUpdateClassReplacement.updateOne(collection, new Document("age", 30), verifiedPipeline(), new UpdateOptions()); assertEquals(1, result.getMatchedCount()); BsonDocument retrievedQuery = assertSingleRecordedCommand(true); @@ -737,7 +737,7 @@ public void testUpdateOneWithClientSessionFilterAndPipeline() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - UpdateResult result = (UpdateResult) MongoCollectionClassReplacement.updateOne(collection, clientSession, new Document("age", 30), verifiedPipeline()); + UpdateResult result = (UpdateResult) MongoCollectionPipelineUpdateClassReplacement.updateOne(collection, clientSession, new Document("age", 30), verifiedPipeline()); assertEquals(1, result.getMatchedCount()); BsonDocument retrievedQuery = assertSingleRecordedCommand(true); @@ -754,7 +754,7 @@ public void testUpdateOneWithClientSessionFilterPipelineAndOptions() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - UpdateResult result = (UpdateResult) MongoCollectionClassReplacement.updateOne(collection, clientSession, new Document("age", 30), verifiedPipeline(), new UpdateOptions()); + UpdateResult result = (UpdateResult) MongoCollectionPipelineUpdateClassReplacement.updateOne(collection, clientSession, new Document("age", 30), verifiedPipeline(), new UpdateOptions()); assertEquals(1, result.getMatchedCount()); BsonDocument retrievedQuery = assertSingleRecordedCommand(true); @@ -860,7 +860,7 @@ public void testUpdateManyWithFilterAndPipeline() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - UpdateResult result = (UpdateResult) MongoCollectionClassReplacement.updateMany(collection, new Document("age", 30), verifiedPipeline()); + UpdateResult result = (UpdateResult) MongoCollectionPipelineUpdateClassReplacement.updateMany(collection, new Document("age", 30), verifiedPipeline()); assertEquals(2, result.getMatchedCount()); BsonDocument retrievedQuery = assertSingleRecordedCommand(true); @@ -875,7 +875,7 @@ public void testUpdateManyWithFilterPipelineAndOptions() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - UpdateResult result = (UpdateResult) MongoCollectionClassReplacement.updateMany(collection, new Document("age", 30), verifiedPipeline(), new UpdateOptions()); + UpdateResult result = (UpdateResult) MongoCollectionPipelineUpdateClassReplacement.updateMany(collection, new Document("age", 30), verifiedPipeline(), new UpdateOptions()); assertEquals(2, result.getMatchedCount()); BsonDocument retrievedQuery = assertSingleRecordedCommand(true); @@ -891,7 +891,7 @@ public void testUpdateManyWithClientSessionFilterAndPipeline() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - UpdateResult result = (UpdateResult) MongoCollectionClassReplacement.updateMany(collection, clientSession, new Document("age", 30), verifiedPipeline()); + UpdateResult result = (UpdateResult) MongoCollectionPipelineUpdateClassReplacement.updateMany(collection, clientSession, new Document("age", 30), verifiedPipeline()); assertEquals(2, result.getMatchedCount()); BsonDocument retrievedQuery = assertSingleRecordedCommand(true); @@ -908,7 +908,7 @@ public void testUpdateManyWithClientSessionFilterPipelineAndOptions() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - UpdateResult result = (UpdateResult) MongoCollectionClassReplacement.updateMany(collection, clientSession, new Document("age", 30), verifiedPipeline(), new UpdateOptions()); + UpdateResult result = (UpdateResult) MongoCollectionPipelineUpdateClassReplacement.updateMany(collection, clientSession, new Document("age", 30), verifiedPipeline(), new UpdateOptions()); assertEquals(2, result.getMatchedCount()); BsonDocument retrievedQuery = assertSingleRecordedCommand(true); @@ -1102,7 +1102,7 @@ public void testFindOneAndUpdateWithFilterAndPipeline() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - Document found = (Document) MongoCollectionClassReplacement.findOneAndUpdate(collection, new Document("age", 30), verifiedPipeline()); + Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, new Document("age", 30), verifiedPipeline()); assertNotNull(found); assertEquals("John Doe", found.getString("name")); @@ -1118,7 +1118,7 @@ public void testFindOneAndUpdateWithFilterPipelineAndOptions() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - Document found = (Document) MongoCollectionClassReplacement.findOneAndUpdate(collection, new Document("age", 30), verifiedPipeline(), new FindOneAndUpdateOptions()); + Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, new Document("age", 30), verifiedPipeline(), new FindOneAndUpdateOptions()); assertNotNull(found); assertEquals("John Doe", found.getString("name")); @@ -1135,7 +1135,7 @@ public void testFindOneAndUpdateWithClientSessionFilterAndPipeline() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - Document found = (Document) MongoCollectionClassReplacement.findOneAndUpdate(collection, clientSession, new Document("age", 30), verifiedPipeline()); + Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, clientSession, new Document("age", 30), verifiedPipeline()); assertNotNull(found); assertEquals("John Doe", found.getString("name")); @@ -1153,7 +1153,7 @@ public void testFindOneAndUpdateWithClientSessionFilterPipelineAndOptions() { insertPerson("Jim Roe", 25); ExecutionTracer.setExecutingInitMongo(false); - Document found = (Document) MongoCollectionClassReplacement.findOneAndUpdate(collection, clientSession, new Document("age", 30), verifiedPipeline(), new FindOneAndUpdateOptions()); + Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, clientSession, new Document("age", 30), verifiedPipeline(), new FindOneAndUpdateOptions()); assertNotNull(found); assertEquals("John Doe", found.getString("name")); From a84c2b7318d964332c7fffaf8e16e5333d7e9418 Mon Sep 17 00:00:00 2001 From: Juan Pablo Galeotti Date: Thu, 8 Oct 2026 23:55:39 -0300 Subject: [PATCH 2/5] instrumentation: add replacements for MongoCollection methods, including find, delete, update, and count variants --- .../MongoCollectionClassReplacement.java | 201 ++++++++++++++++++ ...CollectionLegacyCountClassReplacement.java | 20 ++ ...lectionPipelineUpdateClassReplacement.java | 60 ++++++ 3 files changed, 281 insertions(+) diff --git a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacement.java b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacement.java index a1c0094f6c..8a6bc2d60f 100644 --- a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacement.java +++ b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacement.java @@ -13,6 +13,17 @@ import java.util.List; +/** + * Replacements for the methods of {@code MongoCollection} that execute a query. + *

+ * All the original methods of a replacement class are resolved together, and all must exist in the + * MongoDB Java driver in use, otherwise the replacements of the whole class fail when executed. + * The methods of this class exist from driver 3.8.0 (the first version with + * {@code com.mongodb.client.ClientSession} and {@code countDocuments}), so that is the first driver + * version supported. Methods that are only present in some driver versions are in separate classes: + * {@link MongoCollectionLegacyCountClassReplacement} (removed in 4.0.0) and + * {@link MongoCollectionPipelineUpdateClassReplacement} (added in 3.11.0). + */ public class MongoCollectionClassReplacement extends MongoOperationClassReplacement { private static final MongoCollectionClassReplacement singleton = new MongoCollectionClassReplacement(); @@ -21,192 +32,382 @@ protected String getNameOfThirdPartyTargetClass() { return "com.mongodb.client.MongoCollection"; } + /** + * Replacement for {@code MongoCollection.find()}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "find", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.FindIterable") public static Object find(Object mongoCollection) { return handleFind("find", mongoCollection, Collections.emptyList(), null); } + /** + * Replacement for {@code MongoCollection.find(Class)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findResultClass", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.FindIterable") public static Object find(Object mongoCollection, Class resultClass) { return handleFind("findResultClass", mongoCollection, Arrays.asList(resultClass), null); } + /** + * Replacement for {@code MongoCollection.find(Bson)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.FindIterable") public static Object find(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleFind("findBson", mongoCollection, Arrays.asList(filter), filter); } + /** + * Replacement for {@code MongoCollection.find(Bson, Class)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findBsonResultClass", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.FindIterable") public static Object find(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, Class resultClass) { return handleFind("findBsonResultClass", mongoCollection, Arrays.asList(filter, resultClass), filter); } + /** + * Replacement for {@code MongoCollection.find(ClientSession, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.FindIterable") public static Object find(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleFind("findClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter), filter); } + /** + * Replacement for {@code MongoCollection.find(ClientSession, Bson, Class)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findClientSessionBsonResultClass", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.FindIterable") public static Object find(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, Class resultClass) { return handleFind("findClientSessionBsonResultClass", mongoCollection, Arrays.asList(clientSession, filter, resultClass), filter); } + /** + * Replacement for {@code MongoCollection.countDocuments(Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countDocumentsBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static long countDocuments(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleCount("countDocumentsBson", mongoCollection, Arrays.asList(filter), filter); } + /** + * Replacement for {@code MongoCollection.countDocuments(Bson, CountOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countDocumentsBsonCountOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static long countDocuments(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.CountOptions") Object options) { return handleCount("countDocumentsBsonCountOptions", mongoCollection, Arrays.asList(filter, options), filter); } + /** + * Replacement for {@code MongoCollection.countDocuments(ClientSession, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countDocumentsClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static long countDocuments_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleCount("countDocumentsClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter), filter); } + /** + * Replacement for {@code MongoCollection.countDocuments(ClientSession, Bson, CountOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countDocumentsClientSessionBsonCountOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static long countDocuments(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.CountOptions") Object options) { return handleCount("countDocumentsClientSessionBsonCountOptions", mongoCollection, Arrays.asList(clientSession, filter, options), filter); } + /** + * Replacement for {@code MongoCollection.deleteOne(Bson)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "deleteOneBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.DeleteResult") public static Object deleteOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleDelete("deleteOneBson", mongoCollection, Arrays.asList(filter), filter); } + /** + * Replacement for {@code MongoCollection.deleteOne(Bson, DeleteOptions)}. + *

+ * Present in the MongoDB Java driver from 3.4.0 (not present in 3.2.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "deleteOneBsonDeleteOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.DeleteResult") public static Object deleteOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.DeleteOptions") Object options) { return handleDelete("deleteOneBsonDeleteOptions", mongoCollection, Arrays.asList(filter, options), filter); } + /** + * Replacement for {@code MongoCollection.deleteOne(ClientSession, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "deleteOneClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.DeleteResult") public static Object deleteOne_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleDelete("deleteOneClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter), filter); } + /** + * Replacement for {@code MongoCollection.deleteOne(ClientSession, Bson, DeleteOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "deleteOneClientSessionBsonDeleteOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.DeleteResult") public static Object deleteOne(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.DeleteOptions") Object options) { return handleDelete("deleteOneClientSessionBsonDeleteOptions", mongoCollection, Arrays.asList(clientSession, filter, options), filter); } + /** + * Replacement for {@code MongoCollection.deleteMany(Bson)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "deleteManyBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.DeleteResult") public static Object deleteMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleDelete("deleteManyBson", mongoCollection, Arrays.asList(filter), filter); } + /** + * Replacement for {@code MongoCollection.deleteMany(Bson, DeleteOptions)}. + *

+ * Present in the MongoDB Java driver from 3.4.0 (not present in 3.2.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "deleteManyBsonDeleteOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.DeleteResult") public static Object deleteMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.DeleteOptions") Object options) { return handleDelete("deleteManyBsonDeleteOptions", mongoCollection, Arrays.asList(filter, options), filter); } + /** + * Replacement for {@code MongoCollection.deleteMany(ClientSession, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "deleteManyClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.DeleteResult") public static Object deleteMany_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleDelete("deleteManyClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter), filter); } + /** + * Replacement for {@code MongoCollection.deleteMany(ClientSession, Bson, DeleteOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "deleteManyClientSessionBsonDeleteOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.DeleteResult") public static Object deleteMany(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.DeleteOptions") Object options) { return handleDelete("deleteManyClientSessionBsonDeleteOptions", mongoCollection, Arrays.asList(clientSession, filter, options), filter); } + /** + * Replacement for {@code MongoCollection.updateOne(Bson, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update) { return handleUpdate("updateOneBson", mongoCollection, Arrays.asList(filter, update), filter); } + /** + * Replacement for {@code MongoCollection.updateOne(Bson, Bson, UpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneBsonUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { return handleUpdate("updateOneBsonUpdateOptions", mongoCollection, Arrays.asList(filter, update, options), filter); } + /** + * Replacement for {@code MongoCollection.updateOne(ClientSession, Bson, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateOne_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update) { return handleUpdate("updateOneClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter, update), filter); } + /** + * Replacement for {@code MongoCollection.updateOne(ClientSession, Bson, Bson, UpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneClientSessionBsonUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { return handleUpdate("updateOneClientSessionBsonUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, update, options), filter); } + /** + * Replacement for {@code MongoCollection.updateMany(Bson, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update) { return handleUpdate("updateManyBson", mongoCollection, Arrays.asList(filter, update), filter); } + /** + * Replacement for {@code MongoCollection.updateMany(Bson, Bson, UpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyBsonUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { return handleUpdate("updateManyBsonUpdateOptions", mongoCollection, Arrays.asList(filter, update, options), filter); } + /** + * Replacement for {@code MongoCollection.updateMany(ClientSession, Bson, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateMany_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update) { return handleUpdate("updateManyClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter, update), filter); } + /** + * Replacement for {@code MongoCollection.updateMany(ClientSession, Bson, Bson, UpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyClientSessionBsonUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { return handleUpdate("updateManyClientSessionBsonUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, update, options), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndDelete(Bson)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndDeleteBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndDelete(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleDelete("findOneAndDeleteBson", mongoCollection, Arrays.asList(filter), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndDelete(Bson, FindOneAndDeleteOptions)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndDeleteBsonFindOneAndDeleteOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndDelete(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndDeleteOptions") Object options) { return handleDelete("findOneAndDeleteBsonFindOneAndDeleteOptions", mongoCollection, Arrays.asList(filter, options), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndDelete(ClientSession, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndDeleteClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndDelete_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return handleDelete("findOneAndDeleteClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndDelete(ClientSession, Bson, FindOneAndDeleteOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndDeleteClientSessionBsonFindOneAndDeleteOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndDelete(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndDeleteOptions") Object options) { return handleDelete("findOneAndDeleteClientSessionBsonFindOneAndDeleteOptions", mongoCollection, Arrays.asList(clientSession, filter, options), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndUpdate(Bson, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update) { return handleUpdate("findOneAndUpdateBson", mongoCollection, Arrays.asList(filter, update), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndUpdate(Bson, Bson, FindOneAndUpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateBsonFindOneAndUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndUpdateOptions") Object options) { return handleUpdate("findOneAndUpdateBsonFindOneAndUpdateOptions", mongoCollection, Arrays.asList(filter, update, options), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndUpdate(ClientSession, Bson, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndUpdate_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update) { return handleUpdate("findOneAndUpdateClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter, update), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndUpdate(ClientSession, Bson, Bson, FindOneAndUpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateClientSessionBsonFindOneAndUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object update, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndUpdateOptions") Object options) { return handleUpdate("findOneAndUpdateClientSessionBsonFindOneAndUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, update, options), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndReplace(Bson, TDocument)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndReplaceBsonTDocument", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndReplace(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, Object replacement) { return handleUpdate("findOneAndReplaceBsonTDocument", mongoCollection, Arrays.asList(filter, replacement), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndReplace(Bson, TDocument, FindOneAndReplaceOptions)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndReplaceBsonTDocumentFindOneAndReplaceOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndReplace_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, Object replacement, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndReplaceOptions") Object options) { return handleUpdate("findOneAndReplaceBsonTDocumentFindOneAndReplaceOptions", mongoCollection, Arrays.asList(filter, replacement, options), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndReplace(ClientSession, Bson, TDocument)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndReplaceClientSessionBsonTDocument", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndReplace(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, Object replacement) { return handleUpdate("findOneAndReplaceClientSessionBsonTDocument", mongoCollection, Arrays.asList(clientSession, filter, replacement), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndReplace(ClientSession, Bson, TDocument, FindOneAndReplaceOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndReplaceClientSessionBsonTDocumentFindOneAndReplaceOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndReplace(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, Object replacement, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndReplaceOptions") Object options) { return handleUpdate("findOneAndReplaceClientSessionBsonTDocumentFindOneAndReplaceOptions", mongoCollection, Arrays.asList(clientSession, filter, replacement, options), filter); diff --git a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionLegacyCountClassReplacement.java b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionLegacyCountClassReplacement.java index d6c68ac56f..c641474f0c 100644 --- a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionLegacyCountClassReplacement.java +++ b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionLegacyCountClassReplacement.java @@ -28,21 +28,41 @@ protected String getNameOfThirdPartyTargetClass() { return "com.mongodb.client.MongoCollection"; } + /** + * Replacement for {@code MongoCollection.count(Bson)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}) until 3.12.14 (the last 3.x version checked); removed in 4.0.0. + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static long count(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return (long) handleEagerQuery(singleton, "countBson", mongoCollection, Arrays.asList(filter), filter); } + /** + * Replacement for {@code MongoCollection.count(Bson, CountOptions)}. + *

+ * Present in the MongoDB Java driver from 3.0.0 (the first version with {@code MongoCollection}) until 3.12.14 (the last 3.x version checked); removed in 4.0.0. + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countBsonCountOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static long count(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.CountOptions") Object options) { return (long) handleEagerQuery(singleton, "countBsonCountOptions", mongoCollection, Arrays.asList(filter, options), filter); } + /** + * Replacement for {@code MongoCollection.count(ClientSession, Bson)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1) until 3.12.14 (the last 3.x version checked); removed in 4.0.0. + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countClientSessionBson", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static long count_EM_0(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter) { return (long) handleEagerQuery(singleton, "countClientSessionBson", mongoCollection, Arrays.asList(clientSession, filter), filter); } + /** + * Replacement for {@code MongoCollection.count(ClientSession, Bson, CountOptions)}. + *

+ * Present in the MongoDB Java driver from 3.8.0 (not present in 3.7.1) until 3.12.14 (the last 3.x version checked); removed in 4.0.0. + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "countClientSessionBsonCountOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static long count(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, @ThirdPartyCast(actualType = "com.mongodb.client.model.CountOptions") Object options) { return (long) handleEagerQuery(singleton, "countClientSessionBsonCountOptions", mongoCollection, Arrays.asList(clientSession, filter, options), filter); diff --git a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacement.java b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacement.java index ce108927a9..bc8983c59a 100644 --- a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacement.java +++ b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacement.java @@ -28,61 +28,121 @@ protected String getNameOfThirdPartyTargetClass() { return "com.mongodb.client.MongoCollection"; } + /** + * Replacement for {@code MongoCollection.updateOne(Bson, List)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { return handleEagerQuery(singleton, "updateOneBsonPipeline", mongoCollection, Arrays.asList(filter, pipeline), filter); } + /** + * Replacement for {@code MongoCollection.updateOne(Bson, List, UpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { return handleEagerQuery(singleton, "updateOneBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(filter, pipeline, options), filter); } + /** + * Replacement for {@code MongoCollection.updateOne(ClientSession, Bson, List)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneClientSessionBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { return handleEagerQuery(singleton, "updateOneClientSessionBsonPipeline", mongoCollection, Arrays.asList(clientSession, filter, pipeline), filter); } + /** + * Replacement for {@code MongoCollection.updateOne(ClientSession, Bson, List, UpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateOneClientSessionBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateOne(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { return handleEagerQuery(singleton, "updateOneClientSessionBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, pipeline, options), filter); } + /** + * Replacement for {@code MongoCollection.updateMany(Bson, List)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { return handleEagerQuery(singleton, "updateManyBsonPipeline", mongoCollection, Arrays.asList(filter, pipeline), filter); } + /** + * Replacement for {@code MongoCollection.updateMany(Bson, List, UpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { return handleEagerQuery(singleton, "updateManyBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(filter, pipeline, options), filter); } + /** + * Replacement for {@code MongoCollection.updateMany(ClientSession, Bson, List)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyClientSessionBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { return handleEagerQuery(singleton, "updateManyClientSessionBsonPipeline", mongoCollection, Arrays.asList(clientSession, filter, pipeline), filter); } + /** + * Replacement for {@code MongoCollection.updateMany(ClientSession, Bson, List, UpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "updateManyClientSessionBsonPipelineUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO, castTo = "com.mongodb.client.result.UpdateResult") public static Object updateMany(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.UpdateOptions") Object options) { return handleEagerQuery(singleton, "updateManyClientSessionBsonPipelineUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, pipeline, options), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndUpdate(Bson, List)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { return handleEagerQuery(singleton, "findOneAndUpdateBsonPipeline", mongoCollection, Arrays.asList(filter, pipeline), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndUpdate(Bson, List, FindOneAndUpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateBsonPipelineFindOneAndUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndUpdateOptions") Object options) { return handleEagerQuery(singleton, "findOneAndUpdateBsonPipelineFindOneAndUpdateOptions", mongoCollection, Arrays.asList(filter, pipeline, options), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndUpdate(ClientSession, Bson, List)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateClientSessionBsonPipeline", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline) { return handleEagerQuery(singleton, "findOneAndUpdateClientSessionBsonPipeline", mongoCollection, Arrays.asList(clientSession, filter, pipeline), filter); } + /** + * Replacement for {@code MongoCollection.findOneAndUpdate(ClientSession, Bson, List, FindOneAndUpdateOptions)}. + *

+ * Present in the MongoDB Java driver from 3.11.0 (not present in 3.10.2). + */ @Replacement(replacingStatic = false, type = ReplacementType.TRACKER, id = "findOneAndUpdateClientSessionBsonPipelineFindOneAndUpdateOptions", usageFilter = UsageFilter.ANY, category = ReplacementCategory.MONGO) public static Object findOneAndUpdate(Object mongoCollection, @ThirdPartyCast(actualType = "com.mongodb.client.ClientSession") Object clientSession, @ThirdPartyCast(actualType = "org.bson.conversions.Bson") Object filter, List pipeline, @ThirdPartyCast(actualType = "com.mongodb.client.model.FindOneAndUpdateOptions") Object options) { return handleEagerQuery(singleton, "findOneAndUpdateClientSessionBsonPipelineFindOneAndUpdateOptions", mongoCollection, Arrays.asList(clientSession, filter, pipeline, options), filter); From c4b99af7752ee7ebd2b7c5085be083da93ede5b5 Mon Sep 17 00:00:00 2001 From: Juan Pablo Galeotti Date: Fri, 9 Oct 2026 15:07:42 -0300 Subject: [PATCH 3/5] testfix: skip MongoCollectionLegacyCountClassReplacement in ReplacementListTest --- .../methodreplacement/ReplacementListTest.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/ReplacementListTest.java b/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/ReplacementListTest.java index 187d5cbcfd..cbdee4cd56 100644 --- a/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/ReplacementListTest.java +++ b/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/ReplacementListTest.java @@ -1,5 +1,6 @@ package org.evomaster.client.java.instrumentation.coverage.methodreplacement; +import org.evomaster.client.java.instrumentation.coverage.methodreplacement.thirdpartyclasses.MongoCollectionLegacyCountClassReplacement; import org.evomaster.client.java.instrumentation.shared.ReplacementType; import org.junit.jupiter.api.Test; @@ -27,6 +28,14 @@ public void testReplacementMethods() { for (MethodReplacementClass mrc : ReplacementList.getList()) { + if (mrc instanceof MongoCollectionLegacyCountClassReplacement) { + /** + * This is a special case, because the legacy count method is deprecated and removed in MongoDB 4.0, + * so we cannot test it in all environments + */ + continue; + } + //make sure that during testing all third-party libraries are available assertTrue(mrc.isAvailable(), "Not available: " + mrc.getClass().getName()); @@ -193,4 +202,4 @@ private static void checkBaseJdkType(Method m, Class typeToCheck) { m.getDeclaringClass().getName() + "#" + m.getName() ); } -} \ No newline at end of file +} From 01ac14ec2d74fe0aafc2e8db3b934c2658665dbc Mon Sep 17 00:00:00 2001 From: Juan Pablo Galeotti Date: Thu, 15 Oct 2026 19:50:39 -0300 Subject: [PATCH 4/5] removed duplicated method due to merge error --- .../MongoOperationClassReplacement.java | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoOperationClassReplacement.java b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoOperationClassReplacement.java index 94c81b7d25..e695104dc3 100644 --- a/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoOperationClassReplacement.java +++ b/client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoOperationClassReplacement.java @@ -59,41 +59,6 @@ protected static Object handleEagerQuery(ThirdPartyMethodReplacementClass single } } - /** - * Executes an operation that, unlike find, is executed eagerly (eg, count, delete and update), - * so we know right away whether the filter was valid. The query is stored in any case. - * - * @param singleton the replacement class holding the replacement with the given id - * @param id the id of the replacement, used to retrieve the original method - * @param mongoCollection the collection on which the operation is executed - * @param args the arguments of the original call - * @param filter the query used in the operation - * @return the result of the original call - */ - protected static Object handleEagerQuery(ThirdPartyMethodReplacementClass singleton, String id, Object mongoCollection, List args, Object filter) { - long start = System.currentTimeMillis(); - Method method = getOriginal(singleton, id, mongoCollection); - try { - Object result = method.invoke(mongoCollection, args.toArray()); - long end = System.currentTimeMillis(); - handleMongo(mongoCollection, filter, true, end - start); - return result; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - long end = System.currentTimeMillis(); - handleMongo(mongoCollection, filter, false, end - start); - Throwable cause = e.getCause(); - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } - if (cause instanceof Error) { - throw (Error) cause; - } - throw new RuntimeException(cause); - } - } - private static Class extractDocumentsType(Object collection) { try { Class collectionClass = getCollectionClass(collection); From fbf5bcacc1fa46eee220ca4d3bc8eb76aaf6b461 Mon Sep 17 00:00:00 2001 From: Juan Pablo Galeotti Date: Fri, 16 Oct 2026 11:10:05 -0300 Subject: [PATCH 5/5] Refactor: Move `findOneAndUpdate` pipeline tests to dedicated class. --- .../MongoCollectionClassReplacementTest.java | 66 ------------------ ...ionPipelineUpdateClassReplacementTest.java | 69 +++++++++++++++++++ 2 files changed, 69 insertions(+), 66 deletions(-) diff --git a/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacementTest.java b/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacementTest.java index b0f42bcbc1..70e70cd310 100644 --- a/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacementTest.java +++ b/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionClassReplacementTest.java @@ -692,73 +692,7 @@ public void testFindOneAndUpdateWithClientSessionFilterAndOptions() { } } - @Test - public void testFindOneAndUpdateWithFilterAndPipeline() { - final MongoCollection collection = getMongoCollection(); - insertPerson("John Doe", 30); - insertPerson("Jim Roe", 25); - - ExecutionTracer.setExecutingInitMongo(false); - Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, new Document("age", 30), verifiedPipeline()); - - assertNotNull(found); - assertEquals("John Doe", found.getString("name")); - assertEquals(1, collection.countDocuments(new Document("verified", true))); - BsonDocument retrievedQuery = assertSingleRecordedCommand(true); - assertEquals(30, retrievedQuery.getInt32("age").getValue()); - } - - @Test - public void testFindOneAndUpdateWithFilterPipelineAndOptions() { - final MongoCollection collection = getMongoCollection(); - insertPerson("John Doe", 30); - insertPerson("Jim Roe", 25); - - ExecutionTracer.setExecutingInitMongo(false); - Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, new Document("age", 30), verifiedPipeline(), new FindOneAndUpdateOptions()); - - assertNotNull(found); - assertEquals("John Doe", found.getString("name")); - assertEquals(1, collection.countDocuments(new Document("verified", true))); - BsonDocument retrievedQuery = assertSingleRecordedCommand(true); - assertEquals(30, retrievedQuery.getInt32("age").getValue()); - } - - @Test - public void testFindOneAndUpdateWithClientSessionFilterAndPipeline() { - try (ClientSession clientSession = mongoClient.startSession()) { - final MongoCollection collection = getMongoCollection(); - insertPerson("John Doe", 30); - insertPerson("Jim Roe", 25); - ExecutionTracer.setExecutingInitMongo(false); - Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, clientSession, new Document("age", 30), verifiedPipeline()); - - assertNotNull(found); - assertEquals("John Doe", found.getString("name")); - assertEquals(1, collection.countDocuments(new Document("verified", true))); - BsonDocument retrievedQuery = assertSingleRecordedCommand(true); - assertEquals(30, retrievedQuery.getInt32("age").getValue()); - } - } - - @Test - public void testFindOneAndUpdateWithClientSessionFilterPipelineAndOptions() { - try (ClientSession clientSession = mongoClient.startSession()) { - final MongoCollection collection = getMongoCollection(); - insertPerson("John Doe", 30); - insertPerson("Jim Roe", 25); - - ExecutionTracer.setExecutingInitMongo(false); - Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, clientSession, new Document("age", 30), verifiedPipeline(), new FindOneAndUpdateOptions()); - - assertNotNull(found); - assertEquals("John Doe", found.getString("name")); - assertEquals(1, collection.countDocuments(new Document("verified", true))); - BsonDocument retrievedQuery = assertSingleRecordedCommand(true); - assertEquals(30, retrievedQuery.getInt32("age").getValue()); - } - } @Test public void testFindOneAndUpdateWithFilterNoMatch() { diff --git a/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacementTest.java b/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacementTest.java index c4f7327c20..f80fcabf86 100644 --- a/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacementTest.java +++ b/client-java/instrumentation/src/test/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/MongoCollectionPipelineUpdateClassReplacementTest.java @@ -1,6 +1,7 @@ package org.evomaster.client.java.instrumentation.coverage.methodreplacement.thirdpartyclasses; import com.mongodb.client.*; +import com.mongodb.client.model.FindOneAndUpdateOptions; import com.mongodb.client.model.UpdateOptions; import com.mongodb.client.result.UpdateResult; import org.bson.BsonDocument; @@ -122,4 +123,72 @@ public void testUpdateOneWithFilterPipelineAndOptions() { BsonDocument retrievedQuery = assertSingleRecordedCommand(true); assertEquals(30, retrievedQuery.getInt32("age").getValue()); } + + @Test + public void testFindOneAndUpdateWithFilterAndPipeline() { + final MongoCollection collection = getMongoCollection(); + insertPerson("John Doe", 30); + insertPerson("Jim Roe", 25); + + ExecutionTracer.setExecutingInitMongo(false); + Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, new Document("age", 30), verifiedPipeline()); + + assertNotNull(found); + assertEquals("John Doe", found.getString("name")); + assertEquals(1, collection.countDocuments(new Document("verified", true))); + BsonDocument retrievedQuery = assertSingleRecordedCommand(true); + assertEquals(30, retrievedQuery.getInt32("age").getValue()); + } + + @Test + public void testFindOneAndUpdateWithFilterPipelineAndOptions() { + final MongoCollection collection = getMongoCollection(); + insertPerson("John Doe", 30); + insertPerson("Jim Roe", 25); + + ExecutionTracer.setExecutingInitMongo(false); + Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, new Document("age", 30), verifiedPipeline(), new FindOneAndUpdateOptions()); + + assertNotNull(found); + assertEquals("John Doe", found.getString("name")); + assertEquals(1, collection.countDocuments(new Document("verified", true))); + BsonDocument retrievedQuery = assertSingleRecordedCommand(true); + assertEquals(30, retrievedQuery.getInt32("age").getValue()); + } + + @Test + public void testFindOneAndUpdateWithClientSessionFilterAndPipeline() { + try (ClientSession clientSession = mongoClient.startSession()) { + final MongoCollection collection = getMongoCollection(); + insertPerson("John Doe", 30); + insertPerson("Jim Roe", 25); + + ExecutionTracer.setExecutingInitMongo(false); + Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, clientSession, new Document("age", 30), verifiedPipeline()); + + assertNotNull(found); + assertEquals("John Doe", found.getString("name")); + assertEquals(1, collection.countDocuments(new Document("verified", true))); + BsonDocument retrievedQuery = assertSingleRecordedCommand(true); + assertEquals(30, retrievedQuery.getInt32("age").getValue()); + } + } + + @Test + public void testFindOneAndUpdateWithClientSessionFilterPipelineAndOptions() { + try (ClientSession clientSession = mongoClient.startSession()) { + final MongoCollection collection = getMongoCollection(); + insertPerson("John Doe", 30); + insertPerson("Jim Roe", 25); + + ExecutionTracer.setExecutingInitMongo(false); + Document found = (Document) MongoCollectionPipelineUpdateClassReplacement.findOneAndUpdate(collection, clientSession, new Document("age", 30), verifiedPipeline(), new FindOneAndUpdateOptions()); + + assertNotNull(found); + assertEquals("John Doe", found.getString("name")); + assertEquals(1, collection.countDocuments(new Document("verified", true))); + BsonDocument retrievedQuery = assertSingleRecordedCommand(true); + assertEquals(30, retrievedQuery.getInt32("age").getValue()); + } + } }