From ce745ec60d90afaa67581fc07d4b0727290435cb Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Wed, 2 Oct 2024 23:09:31 +0800 Subject: [PATCH 01/13] Convert mongo tests from groovy to java --- .../src/test/groovy/MongoClientTest.groovy | 14 - .../mongo/v3_1/MongoClientTest.java | 26 + .../mongo/v3_1/MongoClientTest.groovy | 16 - .../v3_1/MongoDbAttributesGetterTest.groovy | 88 --- .../v3_1/MongoSpanNameExtractorTest.groovy | 33 - .../mongo/v3_1/MongoClientTest.java | 28 + .../v3_1/MongoDbAttributesGetterTest.java | 107 +++ .../v3_1/MongoSpanNameExtractorTest.java | 36 + .../v3_1/AbstractMongo31ClientTest.groovy | 183 ----- .../mongo/v3_1/AbstractMongo31ClientTest.java | 228 ++++++ .../src/test/groovy/MongoClientTest.groovy | 192 ----- .../mongo/v3_7/MongoClientTest.java | 249 +++++++ .../groovy/Mongo4ReactiveClientTest.groovy | 227 ------ .../src/test/groovy/MongoClientTest.groovy | 156 ----- .../mongo/v4_0/Mongo4ReactiveClientTest.java | 304 ++++++++ .../mongo/v4_0/MongoClientTest.java | 203 ++++++ .../test/groovy/MongoAsyncClientTest.groovy | 210 ------ .../mongoasync/v3_3/MongoAsyncClientTest.java | 254 +++++++ .../testing/AbstractMongoClientTest.groovy | 432 ------------ .../testing/AbstractMongoClientTest.java | 659 ++++++++++++++++++ 20 files changed, 2094 insertions(+), 1551 deletions(-) delete mode 100644 instrumentation/mongo/mongo-3.1/javaagent/src/test/groovy/MongoClientTest.groovy create mode 100644 instrumentation/mongo/mongo-3.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_1/MongoClientTest.java delete mode 100644 instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoClientTest.groovy delete mode 100644 instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.groovy delete mode 100644 instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoSpanNameExtractorTest.groovy create mode 100644 instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoClientTest.java create mode 100644 instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java create mode 100644 instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoSpanNameExtractorTest.java delete mode 100644 instrumentation/mongo/mongo-3.1/testing/src/main/groovy/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.groovy create mode 100644 instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java delete mode 100644 instrumentation/mongo/mongo-3.7/javaagent/src/test/groovy/MongoClientTest.groovy create mode 100644 instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java delete mode 100644 instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/Mongo4ReactiveClientTest.groovy delete mode 100644 instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/MongoClientTest.groovy create mode 100644 instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java create mode 100644 instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java delete mode 100644 instrumentation/mongo/mongo-async-3.3/javaagent/src/test/groovy/MongoAsyncClientTest.groovy create mode 100644 instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java delete mode 100644 instrumentation/mongo/mongo-common/testing/src/main/groovy/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.groovy create mode 100644 instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java diff --git a/instrumentation/mongo/mongo-3.1/javaagent/src/test/groovy/MongoClientTest.groovy b/instrumentation/mongo/mongo-3.1/javaagent/src/test/groovy/MongoClientTest.groovy deleted file mode 100644 index 8f8289d56dbc..000000000000 --- a/instrumentation/mongo/mongo-3.1/javaagent/src/test/groovy/MongoClientTest.groovy +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import com.mongodb.MongoClientOptions -import io.opentelemetry.instrumentation.mongo.v3_1.AbstractMongo31ClientTest -import io.opentelemetry.instrumentation.test.AgentTestTrait - -class MongoClientTest extends AbstractMongo31ClientTest implements AgentTestTrait { - @Override - void configureMongoClientOptions(MongoClientOptions.Builder options) { - } -} diff --git a/instrumentation/mongo/mongo-3.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_1/MongoClientTest.java b/instrumentation/mongo/mongo-3.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_1/MongoClientTest.java new file mode 100644 index 000000000000..b3cacf89ac32 --- /dev/null +++ b/instrumentation/mongo/mongo-3.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_1/MongoClientTest.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mongo.v3_1; + +import com.mongodb.MongoClientOptions; +import io.opentelemetry.instrumentation.mongo.v3_1.AbstractMongo31ClientTest; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import org.junit.jupiter.api.extension.RegisterExtension; + +class MongoClientTest extends AbstractMongo31ClientTest { + + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + @Override + protected void configureMongoClientOptions(MongoClientOptions.Builder options) {} + + @Override + protected InstrumentationExtension testing() { + return testing; + } +} diff --git a/instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoClientTest.groovy b/instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoClientTest.groovy deleted file mode 100644 index 47799519ced4..000000000000 --- a/instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoClientTest.groovy +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.mongo.v3_1 - -import com.mongodb.MongoClientOptions -import io.opentelemetry.instrumentation.test.LibraryTestTrait - -class MongoClientTest extends AbstractMongo31ClientTest implements LibraryTestTrait { - @Override - void configureMongoClientOptions(MongoClientOptions.Builder options) { - options.addCommandListener(MongoTelemetry.create(openTelemetry).newCommandListener()) - } -} diff --git a/instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.groovy b/instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.groovy deleted file mode 100644 index 85a887b14c5a..000000000000 --- a/instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.groovy +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.mongo.v3_1 - -import org.bson.BsonArray -import org.bson.BsonDocument -import org.bson.BsonInt32 -import org.bson.BsonString -import spock.lang.Specification - -import static MongoTelemetryBuilder.DEFAULT_MAX_NORMALIZED_QUERY_LENGTH -import static java.util.Arrays.asList - -class MongoDbAttributesGetterTest extends Specification { - - def 'should sanitize statements to json'() { - setup: - def extractor = new MongoDbAttributesGetter(true, DEFAULT_MAX_NORMALIZED_QUERY_LENGTH) - - expect: - sanitizeStatementAcrossVersions(extractor, - new BsonDocument("cmd", new BsonInt32(1))) == - '{"cmd": "?"}' - - sanitizeStatementAcrossVersions(extractor, - new BsonDocument("cmd", new BsonInt32(1)) - .append("sub", new BsonDocument("a", new BsonInt32(1)))) == - '{"cmd": "?", "sub": {"a": "?"}}' - - sanitizeStatementAcrossVersions(extractor, - new BsonDocument("cmd", new BsonInt32(1)) - .append("sub", new BsonArray(asList(new BsonInt32(1))))) == - '{"cmd": "?", "sub": ["?"]}' - } - - def 'should only preserve string value if it is the value of the first top-level key'() { - setup: - def extractor = new MongoDbAttributesGetter(true, DEFAULT_MAX_NORMALIZED_QUERY_LENGTH) - - expect: - sanitizeStatementAcrossVersions(extractor, - new BsonDocument("cmd", new BsonString("c")) - .append("f", new BsonString("c")) - .append("sub", new BsonString("c"))) == - '{"cmd": "c", "f": "?", "sub": "?"}' - } - - def 'should truncate simple command'() { - setup: - def extractor = new MongoDbAttributesGetter(true, 20) - - def normalized = sanitizeStatementAcrossVersions(extractor, - new BsonDocument("cmd", new BsonString("c")) - .append("f1", new BsonString("c1")) - .append("f2", new BsonString("c2"))) - expect: - // this can vary because of different whitespace for different mongo versions - normalized == '{"cmd": "c", "f1": "' || normalized == '{"cmd": "c", "f1" ' - } - - def 'should truncate array'() { - setup: - def extractor = new MongoDbAttributesGetter(true, 27) - - def normalized = sanitizeStatementAcrossVersions(extractor, - new BsonDocument("cmd", new BsonString("c")) - .append("f1", new BsonArray(asList(new BsonString("c1"), new BsonString("c2")))) - .append("f2", new BsonString("c3"))) - expect: - // this can vary because of different whitespace for different mongo versions - normalized == '{"cmd": "c", "f1": ["?", "?' || normalized == '{"cmd": "c", "f1": ["?",' - } - - def sanitizeStatementAcrossVersions(MongoDbAttributesGetter extractor, BsonDocument query) { - return sanitizeAcrossVersions(extractor.sanitizeStatement(query)) - } - - def sanitizeAcrossVersions(String json) { - json = json.replaceAll('\\{ ', '{') - json = json.replaceAll(' }', '}') - json = json.replaceAll(' :', ':') - return json - } - -} diff --git a/instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoSpanNameExtractorTest.groovy b/instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoSpanNameExtractorTest.groovy deleted file mode 100644 index 368e41337e6e..000000000000 --- a/instrumentation/mongo/mongo-3.1/library/src/test/groovy/io/opentelemetry/instrumentation/mongo/v3_1/MongoSpanNameExtractorTest.groovy +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.mongo.v3_1 - -import com.mongodb.event.CommandStartedEvent -import org.bson.BsonDocument -import org.bson.BsonInt32 -import spock.lang.Specification - -import static MongoTelemetryBuilder.DEFAULT_MAX_NORMALIZED_QUERY_LENGTH - -class MongoSpanNameExtractorTest extends Specification { - - def 'test span name with no dbName'() { - setup: - def nameExtractor = new MongoSpanNameExtractor(new MongoDbAttributesGetter(true, DEFAULT_MAX_NORMALIZED_QUERY_LENGTH), new MongoAttributesExtractor()) - def event = new CommandStartedEvent( - 0, null, null, command, new BsonDocument(command, new BsonInt32(1))) - - when: - def spanName = nameExtractor.extract(event) - - then: - spanName == command - - where: - command = "listDatabases" - } - -} diff --git a/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoClientTest.java b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoClientTest.java new file mode 100644 index 000000000000..7124b410a2f6 --- /dev/null +++ b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoClientTest.java @@ -0,0 +1,28 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.mongo.v3_1; + +import com.mongodb.MongoClientOptions; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; +import org.junit.jupiter.api.extension.RegisterExtension; + +class MongoClientTest extends AbstractMongo31ClientTest { + + @RegisterExtension + private static final InstrumentationExtension testing = LibraryInstrumentationExtension.create(); + + @Override + protected void configureMongoClientOptions(MongoClientOptions.Builder options) { + options.addCommandListener( + MongoTelemetry.create(testing().getOpenTelemetry()).newCommandListener()); + } + + @Override + protected InstrumentationExtension testing() { + return testing; + } +} diff --git a/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java new file mode 100644 index 000000000000..9a4b3b91fc70 --- /dev/null +++ b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java @@ -0,0 +1,107 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.mongo.v3_1; + +import static io.opentelemetry.instrumentation.mongo.v3_1.MongoTelemetryBuilder.DEFAULT_MAX_NORMALIZED_QUERY_LENGTH; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import org.bson.BsonArray; +import org.bson.BsonDocument; +import org.bson.BsonInt32; +import org.bson.BsonString; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class MongoDbAttributesGetterTest { + + @Test + @DisplayName("should sanitize statements to json") + void shouldSanitizeStatementsToJson() { + MongoDbAttributesGetter extractor = + new MongoDbAttributesGetter(true, DEFAULT_MAX_NORMALIZED_QUERY_LENGTH); + + assertThat( + sanitizeStatementAcrossVersions(extractor, new BsonDocument("cmd", new BsonInt32(1)))) + .isEqualTo("{\"cmd\": \"?\"}"); + + assertThat( + sanitizeStatementAcrossVersions( + extractor, + new BsonDocument("cmd", new BsonInt32(1)) + .append("sub", new BsonDocument("a", new BsonInt32(1))))) + .isEqualTo("{\"cmd\": \"?\", \"sub\": {\"a\": \"?\"}}"); + + assertThat( + sanitizeStatementAcrossVersions( + extractor, + new BsonDocument("cmd", new BsonInt32(1)) + .append("sub", new BsonArray(singletonList(new BsonInt32(1)))))) + .isEqualTo("{\"cmd\": \"?\", \"sub\": [\"?\"]}"); + } + + @Test + @DisplayName("should only preserve string value if it is the value of the first top-level key") + void shouldOnlyPreserveStringValueIfItIsTheValueOfTheFirstTopLevelKey() { + MongoDbAttributesGetter extractor = + new MongoDbAttributesGetter(true, DEFAULT_MAX_NORMALIZED_QUERY_LENGTH); + + assertThat( + sanitizeStatementAcrossVersions( + extractor, + new BsonDocument("cmd", new BsonString("c")) + .append("f", new BsonString("c")) + .append("sub", new BsonString("c")))) + .isEqualTo("{\"cmd\": \"c\", \"f\": \"?\", \"sub\": \"?\"}"); + } + + @Test + @DisplayName("should truncate simple command") + void shouldTruncateSimpleCommand() { + MongoDbAttributesGetter extractor = new MongoDbAttributesGetter(true, 20); + + String normalized = + sanitizeStatementAcrossVersions( + extractor, + new BsonDocument("cmd", new BsonString("c")) + .append("f1", new BsonString("c1")) + .append("f2", new BsonString("c2"))); + + // This can vary because of different whitespace for different MongoDB versions + assertThat(normalized).containsAnyOf("{\"cmd\": \"c\", \"f1\": \"", "{\"cmd\": \"c\", \"f1\" "); + } + + @Test + @DisplayName("should truncate array") + void shouldTruncateArray() { + MongoDbAttributesGetter extractor = new MongoDbAttributesGetter(true, 27); + + String normalized = + sanitizeStatementAcrossVersions( + extractor, + new BsonDocument("cmd", new BsonString("c")) + .append( + "f1", new BsonArray(Arrays.asList(new BsonString("c1"), new BsonString("c2")))) + .append("f2", new BsonString("c3"))); + + // This can vary because of different whitespace for different MongoDB versions + assertThat(normalized) + .containsAnyOf("{\"cmd\": \"c\", \"f1\": [\"?\", \"?", "{\"cmd\": \"c\", \"f1\": [\"?\","); + } + + static String sanitizeStatementAcrossVersions( + MongoDbAttributesGetter extractor, BsonDocument query) { + return sanitizeAcrossVersions(extractor.sanitizeStatement(query)); + } + + static String sanitizeAcrossVersions(String json) { + json = json.replaceAll("\\{ ", "{"); + json = json.replaceAll(" }", "}"); + json = json.replaceAll(" :", ":"); + return json; + } +} diff --git a/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoSpanNameExtractorTest.java b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoSpanNameExtractorTest.java new file mode 100644 index 000000000000..fce0cbb1fdb9 --- /dev/null +++ b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoSpanNameExtractorTest.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.mongo.v3_1; + +import static io.opentelemetry.instrumentation.mongo.v3_1.MongoTelemetryBuilder.DEFAULT_MAX_NORMALIZED_QUERY_LENGTH; +import static org.assertj.core.api.Assertions.assertThat; + +import com.mongodb.event.CommandStartedEvent; +import org.bson.BsonDocument; +import org.bson.BsonInt32; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class MongoSpanNameExtractorTest { + + @Test + @DisplayName("test span name with no dbName") + void testSpanNameWithNoDbName() { + MongoSpanNameExtractor nameExtractor = + new MongoSpanNameExtractor( + new MongoDbAttributesGetter(true, DEFAULT_MAX_NORMALIZED_QUERY_LENGTH), + new MongoAttributesExtractor()); + + String command = "listDatabases"; + CommandStartedEvent event = + new CommandStartedEvent( + 0, null, null, command, new BsonDocument(command, new BsonInt32(1))); + + String spanName = nameExtractor.extract(event); + + assertThat(spanName).isEqualTo(command); + } +} diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/groovy/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.groovy b/instrumentation/mongo/mongo-3.1/testing/src/main/groovy/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.groovy deleted file mode 100644 index 63d74fc90341..000000000000 --- a/instrumentation/mongo/mongo-3.1/testing/src/main/groovy/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.groovy +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.mongo.v3_1 - - -import com.mongodb.MongoClient -import com.mongodb.MongoClientOptions -import com.mongodb.MongoTimeoutException -import com.mongodb.ServerAddress -import com.mongodb.client.MongoCollection -import com.mongodb.client.MongoDatabase -import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest -import io.opentelemetry.instrumentation.test.utils.PortUtils -import org.bson.BsonDocument -import org.bson.BsonString -import org.bson.Document -import spock.lang.Shared - -abstract class AbstractMongo31ClientTest extends AbstractMongoClientTest> { - - abstract void configureMongoClientOptions(MongoClientOptions.Builder options); - - @Shared - MongoClient client - - def setupSpec() throws Exception { - def options = MongoClientOptions.builder().description("some-description") - configureMongoClientOptions(options) - client = new MongoClient(new ServerAddress(host, port), options.build()) - } - - def cleanupSpec() throws Exception { - client?.close() - client = null - } - - @Override - void createCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - void createCollectionNoDescription(String dbName, String collectionName) { - def options = MongoClientOptions.builder() - configureMongoClientOptions(options) - MongoDatabase db = new MongoClient(new ServerAddress(host, port), options.build()).getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { - def clientOptions = client.mongoClientOptions - def newClientOptions = MongoClientOptions.builder(clientOptions).build() - MongoDatabase db = new MongoClient(new ServerAddress(host, port), newClientOptions).getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - void createCollectionCallingBuildTwice(String dbName, String collectionName) { - def options = MongoClientOptions.builder().description("some-description") - configureMongoClientOptions(options) - options.build() - MongoDatabase db = new MongoClient(new ServerAddress(host, port), options.build()).getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - int getCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - return db.getCollection(collectionName).count() - } - - @Override - MongoCollection setupInsert(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int insert(MongoCollection collection) { - collection.insertOne(new Document("password", "SECRET")) - return collection.count() - } - - @Override - MongoCollection setupUpdate(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - def coll = db.getCollection(collectionName) - coll.insertOne(new Document("password", "OLDPW")) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int update(MongoCollection collection) { - def result = collection.updateOne( - new BsonDocument("password", new BsonString("OLDPW")), - new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW")))) - collection.count() - return result.modifiedCount - } - - @Override - MongoCollection setupDelete(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - def coll = db.getCollection(collectionName) - coll.insertOne(new Document("password", "SECRET")) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int delete(MongoCollection collection) { - def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))) - collection.count() - return result.deletedCount - } - - @Override - MongoCollection setupGetMore(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def coll = db.getCollection(collectionName) - coll.insertMany([new Document("_id", 0), new Document("_id", 1), new Document("_id", 2)]) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - void getMore(MongoCollection collection) { - collection.find().filter(new Document("_id", new Document('$gte', 0))) - .batchSize(2).into(new ArrayList()) - } - - @Override - void error(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - collection.updateOne(new BsonDocument(), new BsonDocument()) - } - - def "test client failure"() { - setup: - def options = MongoClientOptions.builder().serverSelectionTimeout(10).build() - def client = new MongoClient(new ServerAddress(host, PortUtils.UNUSABLE_PORT), [], options) - - when: - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - - then: - thrown(MongoTimeoutException) - // Unfortunately not caught by our instrumentation. - assertTraces(0) {} - - where: - dbName = "test_db" - collectionName = createCollectionName() - } -} diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java new file mode 100644 index 000000000000..e2ae6568e3bc --- /dev/null +++ b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java @@ -0,0 +1,228 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.mongo.v3_1; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import com.mongodb.MongoClient; +import com.mongodb.MongoClientOptions; +import com.mongodb.MongoTimeoutException; +import com.mongodb.ServerAddress; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest; +import io.opentelemetry.instrumentation.test.utils.PortUtils; +import java.util.ArrayList; +import org.bson.BsonDocument; +import org.bson.BsonString; +import org.bson.Document; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public abstract class AbstractMongo31ClientTest + extends AbstractMongoClientTest> { + + protected abstract void configureMongoClientOptions(MongoClientOptions.Builder options); + + private MongoClient client; + + @BeforeAll + public void setupSpec() { + MongoClientOptions.Builder options = + MongoClientOptions.builder().description("some-description"); + configureMongoClientOptions(options); + client = new MongoClient(new ServerAddress(host, port), options.build()); + } + + @AfterAll + public void cleanupSpec() { + if (client != null) { + client.close(); + } + client = null; + } + + @Override + protected void createCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + } + + @Override + protected void createCollectionNoDescription(String dbName, String collectionName) { + MongoClientOptions.Builder options = MongoClientOptions.builder(); + configureMongoClientOptions(options); + try (MongoClient client = new MongoClient(new ServerAddress(host, port), options.build())) { + client.getDatabase(dbName).createCollection(collectionName); + } + } + + @Override + protected void createCollectionWithAlreadyBuiltClientOptions( + String dbName, String collectionName) { + MongoClientOptions clientOptions = client.getMongoClientOptions(); + MongoClientOptions newClientOptions = MongoClientOptions.builder(clientOptions).build(); + try (MongoClient client = new MongoClient(new ServerAddress(host, port), newClientOptions)) { + client.getDatabase(dbName).createCollection(collectionName); + } + } + + @Override + protected void createCollectionCallingBuildTwice(String dbName, String collectionName) { + MongoClientOptions.Builder options = + MongoClientOptions.builder().description("some-description"); + configureMongoClientOptions(options); + options.build(); + try (MongoClient client = new MongoClient(new ServerAddress(host, port), options.build())) { + client.getDatabase(dbName).createCollection(collectionName); + } + } + + @Override + protected int getCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + return (int) db.getCollection(collectionName).count(); + } + + @Override + protected MongoCollection setupInsert(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + protected int insert(MongoCollection collection) { + collection.insertOne(new Document("password", "SECRET")); + return (int) collection.count(); + } + + @Override + protected MongoCollection setupUpdate(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + MongoCollection coll = db.getCollection(collectionName); + coll.insertOne(new Document("password", "OLDPW")); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + protected int update(MongoCollection collection) { + UpdateResult result = + collection.updateOne( + new BsonDocument("password", new BsonString("OLDPW")), + new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))); + collection.count(); + return (int) result.getModifiedCount(); + } + + @Override + protected MongoCollection setupDelete(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + MongoCollection coll = db.getCollection(collectionName); + coll.insertOne(new Document("password", "SECRET")); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + protected int delete(MongoCollection collection) { + DeleteResult result = + collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))); + collection.count(); + return (int) result.getDeletedCount(); + } + + @Override + protected MongoCollection setupGetMore(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + MongoCollection coll = db.getCollection(collectionName); + coll.insertMany( + asList( + new Document("_id", 0), new Document("_id", 1), new Document("_id", 2))); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + protected void getMore(MongoCollection collection) { + collection + .find() + .filter(new Document("_id", new Document("$gte", 0))) + .batchSize(2) + .into(new ArrayList<>()); + } + + @Override + protected void error(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + collection.updateOne(new BsonDocument(), new BsonDocument()); + } + + @Test + @DisplayName("test client failure") + public void testClientFailure() { + MongoClientOptions options = MongoClientOptions.builder().serverSelectionTimeout(10).build(); + MongoClient client = new MongoClient(new ServerAddress(host, PortUtils.UNUSABLE_PORT), options); + + String dbName = "test_db"; + String collectionName = createCollectionName(); + + assertThatExceptionOfType(MongoTimeoutException.class) + .isThrownBy( + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + }); + // Unfortunately not caught by our instrumentation. + testing().waitAndAssertTraces(); + } +} diff --git a/instrumentation/mongo/mongo-3.7/javaagent/src/test/groovy/MongoClientTest.groovy b/instrumentation/mongo/mongo-3.7/javaagent/src/test/groovy/MongoClientTest.groovy deleted file mode 100644 index 188262e4faa2..000000000000 --- a/instrumentation/mongo/mongo-3.7/javaagent/src/test/groovy/MongoClientTest.groovy +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import com.mongodb.MongoClientSettings -import com.mongodb.MongoTimeoutException -import com.mongodb.ServerAddress -import com.mongodb.client.MongoClient -import com.mongodb.client.MongoClients -import com.mongodb.client.MongoCollection -import com.mongodb.client.MongoDatabase -import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest -import io.opentelemetry.instrumentation.test.AgentTestTrait -import org.bson.BsonDocument -import org.bson.BsonString -import org.bson.Document -import spock.lang.Shared - -import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT - -class MongoClientTest extends AbstractMongoClientTest> implements AgentTestTrait { - - @Shared - MongoClient client - - def setupSpec() throws Exception { - client = MongoClients.create(MongoClientSettings.builder() - .applyToClusterSettings({ builder -> - builder.hosts(Arrays.asList( - new ServerAddress(host, port))) - .description("some-description") - }) - .build()) - } - - def cleanupSpec() throws Exception { - client?.close() - client = null - } - - @Override - void createCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - void createCollectionNoDescription(String dbName, String collectionName) { - MongoDatabase db = MongoClients.create("mongodb://$host:${port}").getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { - def clientSettings = MongoClientSettings.builder() - .applyToClusterSettings({ builder -> - builder.hosts(Arrays.asList( - new ServerAddress(host, port))) - .description("some-description") - }) - .build() - def newClientSettings = MongoClientSettings.builder(clientSettings).build() - MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - void createCollectionCallingBuildTwice(String dbName, String collectionName) { - def clientSettings = MongoClientSettings.builder() - .applyToClusterSettings({ builder -> - builder.hosts(Arrays.asList( - new ServerAddress(host, port))) - .description("some-description") - }) - clientSettings.build() - MongoDatabase db = MongoClients.create(clientSettings.build()).getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - int getCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - return db.getCollection(collectionName).count() - } - - @Override - MongoCollection setupInsert(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int insert(MongoCollection collection) { - collection.insertOne(new Document("password", "SECRET")) - return collection.count() - } - - @Override - MongoCollection setupUpdate(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - def coll = db.getCollection(collectionName) - coll.insertOne(new Document("password", "OLDPW")) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int update(MongoCollection collection) { - def result = collection.updateOne( - new BsonDocument("password", new BsonString("OLDPW")), - new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW")))) - collection.count() - return result.modifiedCount - } - - @Override - MongoCollection setupDelete(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - def coll = db.getCollection(collectionName) - coll.insertOne(new Document("password", "SECRET")) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int delete(MongoCollection collection) { - def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))) - collection.count() - return result.deletedCount - } - - @Override - MongoCollection setupGetMore(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def coll = db.getCollection(collectionName) - coll.insertMany([new Document("_id", 0), new Document("_id", 1), new Document("_id", 2)]) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - void getMore(MongoCollection collection) { - collection.find().filter(new Document("_id", new Document('$gte', 0))) - .batchSize(2).into(new ArrayList()) - } - - @Override - void error(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - collection.updateOne(new BsonDocument(), new BsonDocument()) - } - - def "test client failure"() { - setup: - def client = MongoClients.create("mongodb://" + host + ":" + UNUSABLE_PORT + "/?connectTimeoutMS=10") - - when: - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - - then: - thrown(MongoTimeoutException) - // Unfortunately not caught by our instrumentation. - assertTraces(0) {} - - where: - dbName = "test_db" - collectionName = createCollectionName() - } -} diff --git a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java new file mode 100644 index 000000000000..f822f6b76b48 --- /dev/null +++ b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java @@ -0,0 +1,249 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mongo.v3_7; + +import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.mongodb.MongoClientSettings; +import com.mongodb.MongoTimeoutException; +import com.mongodb.ServerAddress; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import java.util.ArrayList; +import java.util.Arrays; +import org.bson.BsonDocument; +import org.bson.BsonString; +import org.bson.Document; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +class MongoClientTest extends AbstractMongoClientTest> { + + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private MongoClient client; + + @BeforeAll + void setupSpec() { + client = + MongoClients.create( + MongoClientSettings.builder() + .applyToClusterSettings( + builder -> + builder + .hosts(singletonList(new ServerAddress(host, port))) + .description("some-description")) + .build()); + } + + @AfterAll + void cleanupSpec() { + if (client != null) { + client.close(); + client = null; + } + } + + @Override + protected InstrumentationExtension testing() { + return testing; + } + + @Override + protected void createCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + } + + @Override + protected void createCollectionNoDescription(String dbName, String collectionName) { + MongoDatabase db = MongoClients.create("mongodb://" + host + ":" + port).getDatabase(dbName); + db.createCollection(collectionName); + } + + @Override + protected void createCollectionWithAlreadyBuiltClientOptions( + String dbName, String collectionName) { + MongoClientSettings clientSettings = + MongoClientSettings.builder() + .applyToClusterSettings( + builder -> + builder + .hosts(singletonList(new ServerAddress(host, port))) + .description("some-description")) + .build(); + MongoClientSettings newClientSettings = MongoClientSettings.builder(clientSettings).build(); + MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName); + db.createCollection(collectionName); + } + + @Override + protected void createCollectionCallingBuildTwice(String dbName, String collectionName) { + MongoClientSettings.Builder clientSettings = + MongoClientSettings.builder() + .applyToClusterSettings( + builder -> + builder + .hosts(singletonList(new ServerAddress(host, port))) + .description("some-description")); + clientSettings.build(); + MongoDatabase db = MongoClients.create(clientSettings.build()).getDatabase(dbName); + db.createCollection(collectionName); + } + + @Override + protected int getCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + return (int) db.getCollection(collectionName).estimatedDocumentCount(); + } + + @Override + protected MongoCollection setupInsert(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + protected int insert(MongoCollection collection) { + collection.insertOne(new Document("password", "SECRET")); + return (int) collection.estimatedDocumentCount(); + } + + @Override + protected MongoCollection setupUpdate(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + MongoCollection coll = db.getCollection(collectionName); + coll.insertOne(new Document("password", "OLDPW")); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + protected int update(MongoCollection collection) { + UpdateResult result = + collection.updateOne( + new BsonDocument("password", new BsonString("OLDPW")), + new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))); + collection.estimatedDocumentCount(); + return (int) result.getModifiedCount(); + } + + @Override + protected MongoCollection setupDelete(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + MongoCollection coll = db.getCollection(collectionName); + coll.insertOne(new Document("password", "SECRET")); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + protected int delete(MongoCollection collection) { + DeleteResult result = + collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))); + collection.estimatedDocumentCount(); + return (int) result.getDeletedCount(); + } + + @Override + protected MongoCollection setupGetMore(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + MongoCollection coll = db.getCollection(collectionName); + coll.insertMany( + Arrays.asList( + new Document("_id", 0), new Document("_id", 1), new Document("_id", 2))); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + protected void getMore(MongoCollection collection) { + collection + .find() + .filter(new Document("_id", new Document("$gte", 0))) + .batchSize(2) + .into(new ArrayList<>()); + } + + @Override + protected void error(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + collection.updateOne(new BsonDocument(), new BsonDocument()); + } + + @Test + @DisplayName("test client failure") + void testClientFailure() { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + MongoClient client = + MongoClients.create("mongodb://" + host + ":" + UNUSABLE_PORT + "/?connectTimeoutMS=10"); + + assertThatThrownBy( + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + }) + .isInstanceOf(MongoTimeoutException.class); + // Unfortunately not caught by our instrumentation. + testing().waitAndAssertTraces(); + } +} diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/Mongo4ReactiveClientTest.groovy b/instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/Mongo4ReactiveClientTest.groovy deleted file mode 100644 index c9afc1d5ca03..000000000000 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/Mongo4ReactiveClientTest.groovy +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import com.mongodb.MongoClientSettings -import com.mongodb.ServerAddress -import com.mongodb.client.result.DeleteResult -import com.mongodb.client.result.UpdateResult -import com.mongodb.reactivestreams.client.MongoClient -import com.mongodb.reactivestreams.client.MongoClients -import com.mongodb.reactivestreams.client.MongoCollection -import com.mongodb.reactivestreams.client.MongoDatabase -import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest -import io.opentelemetry.instrumentation.test.AgentTestTrait -import org.bson.BsonDocument -import org.bson.BsonString -import org.bson.Document -import org.opentest4j.TestAbortedException -import org.reactivestreams.Subscriber -import org.reactivestreams.Subscription -import spock.lang.Shared - -import java.util.concurrent.CompletableFuture -import java.util.concurrent.CountDownLatch -import java.util.concurrent.TimeUnit - -class Mongo4ReactiveClientTest extends AbstractMongoClientTest> implements AgentTestTrait { - - @Shared - MongoClient client - @Shared - List cleanup = [] - - def setupSpec() throws Exception { - client = MongoClients.create("mongodb://$host:$port") - } - - def cleanupSpec() throws Exception { - client?.close() - client = null - cleanup.forEach { - it.close() - } - } - - @Override - void createCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - def latch = new CountDownLatch(1) - db.createCollection(collectionName).subscribe(toSubscriber { latch.countDown() }) - latch.await(30, TimeUnit.SECONDS) - } - - @Override - void createCollectionNoDescription(String dbName, String collectionName) { - def tmpClient = MongoClients.create("mongodb://$host:${port}") - cleanup.add(tmpClient) - MongoDatabase db = tmpClient.getDatabase(dbName) - def latch = new CountDownLatch(1) - db.createCollection(collectionName).subscribe(toSubscriber { latch.countDown() }) - latch.await(30, TimeUnit.SECONDS) - } - - @Override - void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { - throw new TestAbortedException("not tested on 4.0") - } - - @Override - void createCollectionCallingBuildTwice(String dbName, String collectionName) { - def settings = MongoClientSettings.builder() - .applyToClusterSettings({ builder -> - builder.hosts(Arrays.asList( - new ServerAddress(host, port))) - }) - settings.build() - def tmpClient = MongoClients.create(settings.build()) - cleanup.add(tmpClient) - MongoDatabase db = tmpClient.getDatabase(dbName) - def latch = new CountDownLatch(1) - db.createCollection(collectionName).subscribe(toSubscriber { latch.countDown() }) - latch.await(30, TimeUnit.SECONDS) - } - - @Override - int getCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - def count = new CompletableFuture() - db.getCollection(collectionName).estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) }) - return count.get(30, TimeUnit.SECONDS) - } - - @Override - MongoCollection setupInsert(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def latch1 = new CountDownLatch(1) - db.createCollection(collectionName).subscribe(toSubscriber { latch1.countDown() }) - latch1.await(30, TimeUnit.SECONDS) - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int insert(MongoCollection collection) { - def count = new CompletableFuture() - collection.insertOne(new Document("password", "SECRET")).subscribe(toSubscriber { - collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) }) - }) - return count.get(30, TimeUnit.SECONDS) - } - - @Override - MongoCollection setupUpdate(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def latch1 = new CountDownLatch(1) - db.createCollection(collectionName).subscribe(toSubscriber { latch1.countDown() }) - latch1.await(30, TimeUnit.SECONDS) - def coll = db.getCollection(collectionName) - def latch2 = new CountDownLatch(1) - coll.insertOne(new Document("password", "OLDPW")).subscribe(toSubscriber { latch2.countDown() }) - latch2.await(30, TimeUnit.SECONDS) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int update(MongoCollection collection) { - def result = new CompletableFuture() - def count = new CompletableFuture() - collection.updateOne( - new BsonDocument("password", new BsonString("OLDPW")), - new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW")))).subscribe(toSubscriber { - result.complete(it) - collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) }) - }) - return result.get(30, TimeUnit.SECONDS).modifiedCount - } - - @Override - MongoCollection setupDelete(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def latch1 = new CountDownLatch(1) - db.createCollection(collectionName).subscribe(toSubscriber { latch1.countDown() }) - latch1.await(30, TimeUnit.SECONDS) - def coll = db.getCollection(collectionName) - def latch2 = new CountDownLatch(1) - coll.insertOne(new Document("password", "SECRET")).subscribe(toSubscriber { latch2.countDown() }) - latch2.await(30, TimeUnit.SECONDS) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int delete(MongoCollection collection) { - def result = new CompletableFuture() - def count = new CompletableFuture() - collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))).subscribe(toSubscriber { - result.complete(it) - collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) }) - }) - return result.get(30, TimeUnit.SECONDS).deletedCount - } - - @Override - MongoCollection setupGetMore(String dbName, String collectionName) { - throw new TestAbortedException("not tested on reactive") - } - - @Override - void getMore(MongoCollection collection) { - throw new TestAbortedException("not tested on reactive") - } - - @Override - void error(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def latch = new CountDownLatch(1) - db.createCollection(collectionName).subscribe(toSubscriber { - latch.countDown() - }) - latch.await(30, TimeUnit.SECONDS) - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - def result = new CompletableFuture() - collection.updateOne(new BsonDocument(), new BsonDocument()).subscribe(toSubscriber { - result.complete(it) - }) - throw result.get(30, TimeUnit.SECONDS) - } - - Subscriber toSubscriber(Closure closure) { - return new Subscriber() { - boolean hasResult - - @Override - void onSubscribe(Subscription s) { - s.request(1) // must request 1 value to trigger async call - } - - @Override - void onNext(Object o) { hasResult = true; closure.call(o) } - - @Override - void onError(Throwable t) { hasResult = true; closure.call(t) } - - @Override - void onComplete() { - if (!hasResult) { - hasResult = true - closure.call() - } - } - } - } -} diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/MongoClientTest.groovy b/instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/MongoClientTest.groovy deleted file mode 100644 index 5daec24039fe..000000000000 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/MongoClientTest.groovy +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import com.mongodb.MongoClientSettings -import com.mongodb.ServerAddress -import com.mongodb.client.MongoClient -import com.mongodb.client.MongoClients -import com.mongodb.client.MongoCollection -import com.mongodb.client.MongoDatabase -import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest -import io.opentelemetry.instrumentation.test.AgentTestTrait -import org.bson.BsonDocument -import org.bson.BsonString -import org.bson.Document -import org.opentest4j.TestAbortedException -import spock.lang.Shared - -class MongoClientTest extends AbstractMongoClientTest> implements AgentTestTrait { - - @Shared - MongoClient client - - def setupSpec() throws Exception { - client = MongoClients.create("mongodb://$host:$port") - } - - def cleanupSpec() throws Exception { - client?.close() - client = null - } - - @Override - void createCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - void createCollectionNoDescription(String dbName, String collectionName) { - MongoDatabase db = MongoClients.create("mongodb://$host:${port}").getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { - throw new TestAbortedException("not tested on 4.0") - } - - @Override - void createCollectionCallingBuildTwice(String dbName, String collectionName) { - def settings = MongoClientSettings.builder() - .applyToClusterSettings({ builder -> - builder.hosts(Arrays.asList( - new ServerAddress(host, port))) - }) - settings.build() - MongoDatabase db = MongoClients.create(settings.build()).getDatabase(dbName) - db.createCollection(collectionName) - } - - @Override - int getCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - return db.getCollection(collectionName).estimatedDocumentCount() - } - - @Override - MongoCollection setupInsert(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int insert(MongoCollection collection) { - collection.insertOne(new Document("password", "SECRET")) - return collection.estimatedDocumentCount() - } - - @Override - MongoCollection setupUpdate(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - def coll = db.getCollection(collectionName) - coll.insertOne(new Document("password", "OLDPW")) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int update(MongoCollection collection) { - def result = collection.updateOne( - new BsonDocument("password", new BsonString("OLDPW")), - new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW")))) - collection.estimatedDocumentCount() - return result.modifiedCount - } - - @Override - MongoCollection setupDelete(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - def coll = db.getCollection(collectionName) - coll.insertOne(new Document("password", "SECRET")) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int delete(MongoCollection collection) { - def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))) - collection.estimatedDocumentCount() - return result.deletedCount - } - - @Override - MongoCollection setupGetMore(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def coll = db.getCollection(collectionName) - coll.insertMany([new Document("_id", 0), new Document("_id", 1), new Document("_id", 2)]) - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - void getMore(MongoCollection collection) { - collection.find().filter(new Document("_id", new Document('$gte', 0))) - .batchSize(2).into(new ArrayList()) - } - - @Override - void error(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName) - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - collection.updateOne(new BsonDocument(), new BsonDocument()) - } -} diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java new file mode 100644 index 000000000000..b83c423a03dc --- /dev/null +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java @@ -0,0 +1,304 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mongo.v4_0; + +import com.mongodb.MongoClientSettings; +import com.mongodb.ServerAddress; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import com.mongodb.reactivestreams.client.MongoClient; +import com.mongodb.reactivestreams.client.MongoClients; +import com.mongodb.reactivestreams.client.MongoCollection; +import com.mongodb.reactivestreams.client.MongoDatabase; +import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; +import org.bson.BsonDocument; +import org.bson.BsonString; +import org.bson.Document; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.opentest4j.TestAbortedException; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; + +class Mongo4ReactiveClientTest extends AbstractMongoClientTest> { + + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private MongoClient client; + + private final List cleanup = new ArrayList<>(); + + @BeforeAll + public void setupSpec() { + client = MongoClients.create("mongodb://" + host + ":" + port); + } + + @AfterAll + public void cleanupSpec() throws Exception { + if (client != null) { + client.close(); + client = null; + } + for (AutoCloseable resource : cleanup) { + resource.close(); + } + } + + @Override + protected InstrumentationExtension testing() { + return testing; + } + + @Override + public void createCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName).subscribe(toSubscriber(o -> latch.countDown())); + + try { + latch.await(30, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + @Override + public void createCollectionNoDescription(String dbName, String collectionName) + throws InterruptedException { + MongoClient tmpClient = MongoClients.create("mongodb://" + host + ":" + port); + cleanup.add(tmpClient); + MongoDatabase db = tmpClient.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName).subscribe(toSubscriber(o -> latch.countDown())); + latch.await(30, TimeUnit.SECONDS); + } + + @Override + public void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { + throw new TestAbortedException("not tested on 4.0"); + } + + @Override + public void createCollectionCallingBuildTwice(String dbName, String collectionName) + throws InterruptedException { + MongoClientSettings.Builder settings = + MongoClientSettings.builder() + .applyToClusterSettings( + builder -> builder.hosts(Collections.singletonList(new ServerAddress(host, port)))); + settings.build(); + MongoClient tmpClient = MongoClients.create(settings.build()); + cleanup.add(tmpClient); + MongoDatabase db = tmpClient.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName).subscribe(toSubscriber(o -> latch.countDown())); + latch.await(30, TimeUnit.SECONDS); + } + + @Override + public int getCollection(String dbName, String collectionName) + throws ExecutionException, InterruptedException, TimeoutException { + MongoDatabase db = client.getDatabase(dbName); + CompletableFuture count = new CompletableFuture<>(); + db.getCollection(collectionName) + .estimatedDocumentCount() + .subscribe(toSubscriber(o -> count.complete(((Long) o)))); + return Math.toIntExact(count.get(30, TimeUnit.SECONDS)); + } + + @Override + public MongoCollection setupInsert(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName) + .subscribe(toSubscriber(o -> latch.countDown())); + latch.await(30, TimeUnit.SECONDS); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int insert(MongoCollection collection) throws Exception { + CompletableFuture count = new CompletableFuture<>(); + collection + .insertOne(new Document("password", "SECRET")) + .subscribe( + toSubscriber( + result -> + collection + .estimatedDocumentCount() + .subscribe(toSubscriber(c -> count.complete(((Long) c)))))); + return Math.toIntExact(count.get(30, TimeUnit.SECONDS)); + } + + @Override + public MongoCollection setupUpdate(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch1 = new CountDownLatch(1); + db.createCollection(collectionName) + .subscribe(toSubscriber(o -> latch1.countDown())); + latch1.await(30, TimeUnit.SECONDS); + MongoCollection coll = db.getCollection(collectionName); + CountDownLatch latch2 = new CountDownLatch(1); + coll.insertOne(new Document("password", "OLDPW")) + .subscribe(toSubscriber(o -> latch2.countDown())); + latch2.await(30, TimeUnit.SECONDS); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int update(MongoCollection collection) throws Exception { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); + collection + .updateOne( + new BsonDocument("password", new BsonString("OLDPW")), + new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))) + .subscribe( + toSubscriber( + updateResult -> { + result.complete(((UpdateResult) updateResult)); + collection + .estimatedDocumentCount() + .subscribe(toSubscriber(o -> count.complete(((Integer) o)))); + })); + return (int) result.get(30, TimeUnit.SECONDS).getModifiedCount(); + } + + @Override + public MongoCollection setupDelete(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch1 = new CountDownLatch(1); + db.createCollection(collectionName) + .subscribe(toSubscriber(o -> latch1.countDown())); + latch1.await(30, TimeUnit.SECONDS); + MongoCollection coll = db.getCollection(collectionName); + CountDownLatch latch2 = new CountDownLatch(1); + coll.insertOne(new Document("password", "SECRET")) + .subscribe(toSubscriber(o -> latch2.countDown())); + latch2.await(30, TimeUnit.SECONDS); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int delete(MongoCollection collection) + throws ExecutionException, InterruptedException, TimeoutException { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); + collection + .deleteOne(new BsonDocument("password", new BsonString("SECRET"))) + .subscribe( + toSubscriber( + deleteResult -> { + result.complete(((DeleteResult) deleteResult)); + collection + .estimatedDocumentCount() + .subscribe(toSubscriber(o -> count.complete(((Integer) o)))); + })); + return (int) result.get(30, TimeUnit.SECONDS).getDeletedCount(); + } + + @Override + public MongoCollection setupGetMore(String dbName, String collectionName) { + throw new TestAbortedException("not tested on reactive"); + } + + @Override + public void getMore(MongoCollection collection) { + throw new TestAbortedException("not tested on reactive"); + } + + @Override + public void error(String dbName, String collectionName) throws Throwable { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName) + .subscribe(toSubscriber(o -> latch.countDown())); + latch.await(30, TimeUnit.SECONDS); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + CompletableFuture result = new CompletableFuture<>(); + collection + .updateOne(new BsonDocument(), new BsonDocument()) + .subscribe(toSubscriber(t -> result.complete(((Throwable) t)))); + throw result.get(30, TimeUnit.SECONDS); + } + + Subscriber toSubscriber(Consumer consumer) { + return new Subscriber() { + private boolean hasResult; + + @Override + public void onSubscribe(Subscription s) { + s.request(1); // must request 1 value to trigger async call + } + + @Override + public void onNext(Object o) { + hasResult = true; + consumer.accept(o); + } + + @Override + public void onError(Throwable t) { + hasResult = true; + consumer.accept(t); + } + + @Override + public void onComplete() { + if (!hasResult) { + hasResult = true; + consumer.accept(null); + } + } + }; + } +} diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java new file mode 100644 index 000000000000..c6b5764496a5 --- /dev/null +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java @@ -0,0 +1,203 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mongo.v4_0; + +import com.mongodb.MongoClientSettings; +import com.mongodb.ServerAddress; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import org.bson.BsonDocument; +import org.bson.BsonString; +import org.bson.Document; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.opentest4j.TestAbortedException; + +class MongoClientTest extends AbstractMongoClientTest> { + + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private MongoClient client; + + @BeforeAll + public void setupSpec() { + client = MongoClients.create("mongodb://" + host + ":" + port); + } + + @AfterAll + public void cleanupSpec() { + if (client != null) { + client.close(); + client = null; + } + } + + @Override + protected InstrumentationExtension testing() { + return testing; + } + + @Override + public void createCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + } + + @Override + public void createCollectionNoDescription(String dbName, String collectionName) { + MongoDatabase db = MongoClients.create("mongodb://" + host + ":" + port).getDatabase(dbName); + db.createCollection(collectionName); + } + + @Override + public void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { + throw new TestAbortedException("not tested on 4.0"); + } + + @Override + public void createCollectionCallingBuildTwice(String dbName, String collectionName) { + MongoClientSettings settings = + MongoClientSettings.builder() + .applyToClusterSettings( + builder -> builder.hosts(Collections.singletonList(new ServerAddress(host, port)))) + .build(); + MongoDatabase db = MongoClients.create(settings).getDatabase(dbName); + db.createCollection(collectionName); + } + + @Override + public int getCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + return (int) db.getCollection(collectionName).estimatedDocumentCount(); + } + + @Override + public MongoCollection setupInsert(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int insert(MongoCollection collection) { + collection.insertOne(new Document("password", "SECRET")); + return (int) collection.estimatedDocumentCount(); + } + + @Override + public MongoCollection setupUpdate(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + MongoCollection coll = db.getCollection(collectionName); + coll.insertOne(new Document("password", "OLDPW")); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int update(MongoCollection collection) { + UpdateResult result = + collection.updateOne( + new BsonDocument("password", new BsonString("OLDPW")), + new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))); + collection.estimatedDocumentCount(); + return (int) result.getModifiedCount(); + } + + @Override + public MongoCollection setupDelete(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + MongoCollection coll = db.getCollection(collectionName); + coll.insertOne(new Document("password", "SECRET")); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int delete(MongoCollection collection) { + DeleteResult result = + collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))); + collection.estimatedDocumentCount(); + return (int) result.getDeletedCount(); + } + + @Override + public MongoCollection setupGetMore(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + MongoCollection coll = db.getCollection(collectionName); + coll.insertMany( + Arrays.asList( + new Document("_id", 0), new Document("_id", 1), new Document("_id", 2))); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public void getMore(MongoCollection collection) { + collection + .find() + .filter(new Document("_id", new Document("$gte", 0))) + .batchSize(2) + .into(new ArrayList<>()); + } + + @Override + public void error(String dbName, String collectionName) { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + collection.updateOne(new BsonDocument(), new BsonDocument()); + } +} diff --git a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/groovy/MongoAsyncClientTest.groovy b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/groovy/MongoAsyncClientTest.groovy deleted file mode 100644 index dea675af2c98..000000000000 --- a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/groovy/MongoAsyncClientTest.groovy +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import com.mongodb.ConnectionString -import com.mongodb.async.SingleResultCallback -import com.mongodb.async.client.MongoClient -import com.mongodb.async.client.MongoClientSettings -import com.mongodb.async.client.MongoClients -import com.mongodb.async.client.MongoCollection -import com.mongodb.async.client.MongoDatabase -import com.mongodb.client.result.DeleteResult -import com.mongodb.client.result.UpdateResult -import com.mongodb.connection.ClusterSettings -import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest -import io.opentelemetry.instrumentation.test.AgentTestTrait -import org.bson.BsonDocument -import org.bson.BsonString -import org.bson.Document -import org.opentest4j.TestAbortedException -import spock.lang.Shared - -import java.util.concurrent.CompletableFuture -import java.util.concurrent.CountDownLatch - -class MongoAsyncClientTest extends AbstractMongoClientTest> implements AgentTestTrait { - - @Shared - MongoClient client - - def setupSpec() throws Exception { - client = MongoClients.create( - MongoClientSettings.builder() - .clusterSettings( - ClusterSettings.builder() - .description("some-description") - .applyConnectionString(new ConnectionString("mongodb://$host:$port")) - .build()) - .build()) - } - - def cleanupSpec() throws Exception { - client?.close() - client = null - } - - @Override - void createCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - db.createCollection(collectionName, toCallback {}) - } - - @Override - void createCollectionNoDescription(String dbName, String collectionName) { - MongoDatabase db = MongoClients.create("mongodb://$host:$port").getDatabase(dbName) - db.createCollection(collectionName, toCallback {}) - } - - @Override - void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { - def clientSettings = client.settings - def newClientSettings = MongoClientSettings.builder(clientSettings).build() - MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName) - db.createCollection(collectionName, toCallback {}) - } - - @Override - void createCollectionCallingBuildTwice(String dbName, String collectionName) { - def settings = MongoClientSettings.builder() - .clusterSettings( - ClusterSettings.builder() - .description("some-description") - .applyConnectionString(new ConnectionString("mongodb://$host:$port")) - .build()) - settings.build() - MongoDatabase db = MongoClients.create(settings.build()).getDatabase(dbName) - db.createCollection(collectionName, toCallback {}) - } - - @Override - int getCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName) - def count = new CompletableFuture() - db.getCollection(collectionName).count toCallback { count.complete(it) } - return count.join() - } - - @Override - MongoCollection setupInsert(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def latch1 = new CountDownLatch(1) - db.createCollection(collectionName, toCallback { latch1.countDown() }) - latch1.await() - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int insert(MongoCollection collection) { - def count = new CompletableFuture() - collection.insertOne(new Document("password", "SECRET"), toCallback { - collection.count toCallback { count.complete(it) } - }) - return count.get() - } - - @Override - MongoCollection setupUpdate(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def latch1 = new CountDownLatch(1) - db.createCollection(collectionName, toCallback { latch1.countDown() }) - latch1.await() - def coll = db.getCollection(collectionName) - def latch2 = new CountDownLatch(1) - coll.insertOne(new Document("password", "OLDPW"), toCallback { latch2.countDown() }) - latch2.await() - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int update(MongoCollection collection) { - def result = new CompletableFuture() - def count = new CompletableFuture() - collection.updateOne( - new BsonDocument("password", new BsonString("OLDPW")), - new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))), toCallback { - result.complete(it) - collection.count toCallback { count.complete(it) } - }) - return result.get().modifiedCount - } - - @Override - MongoCollection setupDelete(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def latch1 = new CountDownLatch(1) - db.createCollection(collectionName, toCallback { latch1.countDown() }) - latch1.await() - def coll = db.getCollection(collectionName) - def latch2 = new CountDownLatch(1) - coll.insertOne(new Document("password", "SECRET"), toCallback { latch2.countDown() }) - latch2.await() - return coll - } - ignoreTracesAndClear(1) - return collection - } - - @Override - int delete(MongoCollection collection) { - def result = new CompletableFuture() - def count = new CompletableFuture() - collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")), toCallback { - result.complete(it) - collection.count toCallback { count.complete(it) } - }) - return result.get().deletedCount - } - - @Override - MongoCollection setupGetMore(String dbName, String collectionName) { - throw new TestAbortedException("not tested on async") - } - - @Override - void getMore(MongoCollection collection) { - throw new TestAbortedException("not tested on async") - } - - @Override - void error(String dbName, String collectionName) { - MongoCollection collection = runWithSpan("setup") { - MongoDatabase db = client.getDatabase(dbName) - def latch = new CountDownLatch(1) - db.createCollection(collectionName, toCallback { - latch.countDown() - }) - latch.await() - return db.getCollection(collectionName) - } - ignoreTracesAndClear(1) - def result = new CompletableFuture() - collection.updateOne(new BsonDocument(), new BsonDocument(), toCallback { - result.complete(it) - }) - throw result.join() - } - - SingleResultCallback toCallback(Closure closure) { - return new SingleResultCallback() { - @Override - void onResult(Object result, Throwable t) { - if (t) { - closure.call(t) - } else { - closure.call(result) - } - } - } - } -} diff --git a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java new file mode 100644 index 000000000000..c7eeb40c172c --- /dev/null +++ b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java @@ -0,0 +1,254 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mongoasync.v3_3; + +import com.mongodb.ConnectionString; +import com.mongodb.async.SingleResultCallback; +import com.mongodb.async.client.MongoClient; +import com.mongodb.async.client.MongoClientSettings; +import com.mongodb.async.client.MongoClients; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.async.client.MongoDatabase; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import com.mongodb.connection.ClusterSettings; +import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; +import org.bson.BsonDocument; +import org.bson.BsonString; +import org.bson.Document; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.opentest4j.TestAbortedException; + +class MongoAsyncClientTest extends AbstractMongoClientTest> { + + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private MongoClient client; + + @BeforeAll + public void setupSpec() { + client = + MongoClients.create( + MongoClientSettings.builder() + .clusterSettings( + ClusterSettings.builder() + .description("some-description") + .applyConnectionString( + new ConnectionString("mongodb://" + host + ":" + port)) + .build()) + .build()); + } + + @AfterAll + public void cleanupSpec() { + if (client != null) { + client.close(); + client = null; + } + } + + @Override + protected InstrumentationExtension testing() { + return testing; + } + + @Override + public void createCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> {})); + } + + @Override + public void createCollectionNoDescription(String dbName, String collectionName) { + MongoDatabase db = MongoClients.create("mongodb://" + host + ":" + port).getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> {})); + } + + @Override + public void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { + MongoClientSettings clientSettings = client.getSettings(); + MongoClientSettings newClientSettings = MongoClientSettings.builder(clientSettings).build(); + MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> {})); + } + + @Override + public void createCollectionCallingBuildTwice(String dbName, String collectionName) { + MongoClientSettings.Builder settings = + MongoClientSettings.builder() + .clusterSettings( + ClusterSettings.builder() + .description("some-description") + .applyConnectionString(new ConnectionString("mongodb://" + host + ":" + port)) + .build()); + settings.build(); + MongoDatabase db = MongoClients.create(settings.build()).getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> {})); + } + + @Override + public int getCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + CompletableFuture count = new CompletableFuture<>(); + db.getCollection(collectionName).count(toCallback(o -> count.complete(((Long) o)))); + return count.join().intValue(); + } + + @Override + public MongoCollection setupInsert(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch.countDown())); + latch.await(); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int insert(MongoCollection collection) { + CompletableFuture count = new CompletableFuture<>(); + collection.insertOne( + new Document("password", "SECRET"), + toCallback( + result -> { + collection.count(toCallback(o -> count.complete(((Long) o)))); + })); + return count.join().intValue(); + } + + @Override + public MongoCollection setupUpdate(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch1 = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch1.countDown())); + latch1.await(); + MongoCollection coll = db.getCollection(collectionName); + CountDownLatch latch2 = new CountDownLatch(1); + coll.insertOne( + new Document("password", "OLDPW"), toCallback(result -> latch2.countDown())); + latch2.await(); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int update(MongoCollection collection) { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); + collection.updateOne( + new BsonDocument("password", new BsonString("OLDPW")), + new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW"))), + toCallback( + res -> { + result.complete(((UpdateResult) res)); + collection.count(toCallback(o -> count.complete(((Long) o)))); + })); + return (int) result.join().getModifiedCount(); + } + + @Override + public MongoCollection setupDelete(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch1 = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch1.countDown())); + latch1.await(); + MongoCollection coll = db.getCollection(collectionName); + CountDownLatch latch2 = new CountDownLatch(1); + coll.insertOne( + new Document("password", "SECRET"), toCallback(result -> latch2.countDown())); + latch2.await(); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int delete(MongoCollection collection) { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); + collection.deleteOne( + new BsonDocument("password", new BsonString("SECRET")), + toCallback( + res -> { + result.complete((DeleteResult) res); + collection.count(toCallback(value -> count.complete(((Long) value)))); + })); + return (int) result.join().getDeletedCount(); + } + + @Override + public MongoCollection setupGetMore(String dbName, String collectionName) { + throw new TestAbortedException("not tested on async"); + } + + @Override + public void getMore(MongoCollection collection) { + throw new TestAbortedException("not tested on async"); + } + + @Override + public void error(String dbName, String collectionName) throws Throwable { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch.countDown())); + latch.await(); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + CompletableFuture result = new CompletableFuture<>(); + collection.updateOne( + new BsonDocument(), + new BsonDocument(), + toCallback(res -> result.complete((Throwable) res))); + throw result.join(); + } + + SingleResultCallback toCallback(Consumer closure) { + return (result, t) -> { + if (t != null) { + closure.accept(t); + } else { + closure.accept(result); + } + }; + } +} diff --git a/instrumentation/mongo/mongo-common/testing/src/main/groovy/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.groovy b/instrumentation/mongo/mongo-common/testing/src/main/groovy/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.groovy deleted file mode 100644 index 3cd9dafc2afe..000000000000 --- a/instrumentation/mongo/mongo-common/testing/src/main/groovy/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.groovy +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.mongo.testing - -import io.opentelemetry.api.trace.SpanKind -import io.opentelemetry.instrumentation.test.InstrumentationSpecification -import io.opentelemetry.instrumentation.test.asserts.TraceAssert -import io.opentelemetry.sdk.trace.data.SpanData -import io.opentelemetry.semconv.incubating.DbIncubatingAttributes -import io.opentelemetry.semconv.ServerAttributes -import org.slf4j.LoggerFactory -import org.testcontainers.containers.GenericContainer -import org.testcontainers.containers.output.Slf4jLogConsumer -import spock.lang.Shared - -import java.util.concurrent.atomic.AtomicInteger - -import static io.opentelemetry.api.trace.SpanKind.CLIENT - -abstract class AbstractMongoClientTest extends InstrumentationSpecification { - - @Shared - GenericContainer mongodb - - @Shared - String host - - @Shared - int port - - def setupSpec() { - mongodb = new GenericContainer("mongo:4.0") - .withExposedPorts(27017) - .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("mongodb"))) - mongodb.start() - host = mongodb.getHost() - port = mongodb.getMappedPort(27017) - } - - def cleanupSpec() throws Exception { - mongodb.stop() - } - - // Different client versions have different APIs to do these operations. If adding a test for a new - // version, refer to existing ones on how to implement these operations. - - abstract void createCollection(String dbName, String collectionName) - - abstract void createCollectionNoDescription(String dbName, String collectionName) - - // Tests the fix for https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/457 - // TracingCommandListener might get added multiple times if clientOptions are built using existing clientOptions or when calling a build method twice. - // This test asserts that duplicate traces are not created in those cases. - abstract void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) - - abstract void createCollectionCallingBuildTwice(String dbName, String collectionName) - - abstract int getCollection(String dbName, String collectionName) - - abstract T setupInsert(String dbName, String collectionName) - - abstract int insert(T collection) - - abstract T setupUpdate(String dbName, String collectionName) - - abstract int update(T collection) - - abstract T setupDelete(String dbName, String collectionName) - - abstract int delete(T collection) - - abstract T setupGetMore(String dbName, String collectionName) - - abstract void getMore(T collection) - - abstract void error(String dbName, String collectionName) - - def "test port open"() { - when: - new Socket(host, port) - - then: - noExceptionThrown() - } - - def "test create collection"() { - when: - runWithSpan("parent") { - createCollection(dbName, collectionName) - } - - then: - assertTraces(1) { - trace(0, 2) { - span(0) { - name "parent" - kind SpanKind.INTERNAL - hasNoParent() - } - mongoSpan(it, 1, "create", collectionName, dbName, span(0)) { - assert it == '{"create":"' + collectionName + '","capped":"?"}' || - it == '{"create":"' + collectionName + '","capped":"?","$db":"?"}' || - it == '{"create":"' + collectionName + '","capped":"?","$db":"?","$readPreference":{"mode":"?"}}' || - it == '{"create":"' + collectionName + '","capped":"?","$db":"?","lsid":{"id":"?"}}' - true - } - } - } - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - def "test create collection no description"() { - when: - runWithSpan("parent") { - createCollectionNoDescription(dbName, collectionName) - } - - then: - assertTraces(1) { - trace(0, 2) { - span(0) { - name "parent" - kind SpanKind.INTERNAL - hasNoParent() - } - mongoSpan(it, 1, "create", collectionName, dbName, span(0), { - assert it == '{"create":"' + collectionName + '","capped":"?"}' || - it == '{"create":"' + collectionName + '","capped":"?","$db":"?"}' || - it == '{"create":"' + collectionName + '","capped":"?","$db":"?","$readPreference":{"mode":"?"}}' || - it == '{"create":"' + collectionName + '","capped":"?","$db":"?","lsid":{"id":"?"}}' - true - }) - } - } - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - def "test create collection calling build twice"() { - when: - runWithSpan("parent") { - createCollectionCallingBuildTwice(dbName, collectionName) - } - - then: - assertTraces(1) { - trace(0, 2) { - span(0) { - name "parent" - kind SpanKind.INTERNAL - hasNoParent() - } - mongoSpan(it, 1, "create", collectionName, dbName, span(0)) { - assert it == '{"create":"' + collectionName + '","capped":"?"}' || - it == '{"create":"' + collectionName + '","capped":"?","$db":"?"}' || - it == '{"create":"' + collectionName + '","capped":"?","$db":"?","$readPreference":{"mode":"?"}}' || - it == '{"create":"' + collectionName + '","capped":"?","$db":"?","lsid":{"id":"?"}}' - true - } - } - } - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - def "test get collection"() { - when: - def count = runWithSpan("parent") { - getCollection(dbName, collectionName) - } - - then: - count == 0 - assertTraces(1) { - trace(0, 2) { - span(0) { - name "parent" - kind SpanKind.INTERNAL - hasNoParent() - } - mongoSpan(it, 1, "count", collectionName, dbName, span(0)) { - assert it == '{"count":"' + collectionName + '","query":{}}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?"}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?","lsid":{"id":"?"}}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?","$readPreference":{"mode":"?"}}' || - it == '{"count":"' + collectionName + '","$db":"?","lsid":{"id":"?"}}' - true - } - } - } - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - def "test insert"() { - when: - def collection = setupInsert(dbName, collectionName) - def count = runWithSpan("parent") { - insert(collection) - } - - then: - count == 1 - assertTraces(1) { - trace(0, 3) { - span(0) { - name "parent" - kind SpanKind.INTERNAL - hasNoParent() - } - mongoSpan(it, 1, "insert", collectionName, dbName, span(0)) { - assert it == '{"insert":"' + collectionName + '","ordered":"?","documents":[{"_id":"?","password":"?"}]}' || - it == '{"insert":"' + collectionName + '","ordered":"?","$db":"?","documents":[{"_id":"?","password":"?"}]}' || - it == '{"insert":"' + collectionName + '","ordered":"?","$db":"?","lsid":{"id":"?"},"documents":[{"_id":"?","password":"?"}]}' - true - } - mongoSpan(it, 2, "count", collectionName, dbName, span(0)) { - assert it == '{"count":"' + collectionName + '","query":{}}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?"}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?","lsid":{"id":"?"}}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?","$readPreference":{"mode":"?"}}' || - it == '{"count":"' + collectionName + '","$db":"?","lsid":{"id":"?"}}' - true - } - } - } - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - def "test update"() { - when: - def collection = setupUpdate(dbName, collectionName) - int modifiedCount = runWithSpan("parent") { - update(collection) - } - - then: - modifiedCount == 1 - assertTraces(1) { - trace(0, 3) { - span(0) { - name "parent" - kind SpanKind.INTERNAL - hasNoParent() - } - mongoSpan(it, 1, "update", collectionName, dbName, span(0)) { - assert it == '{"update":"' + collectionName + '","ordered":"?","updates":[{"q":{"password":"?"},"u":{"$set":{"password":"?"}}}]}' || - it == '{"update":"' + collectionName + '","ordered":"?","$db":"?","updates":[{"q":{"password":"?"},"u":{"$set":{"password":"?"}}}]}' || - it == '{"update":"' + collectionName + '","ordered":"?","$db":"?","lsid":{"id":"?"},"updates":[{"q":{"password":"?"},"u":{"$set":{"password":"?"}}}]}' - true - } - mongoSpan(it, 2, "count", collectionName, dbName, span(0)) { - assert it == '{"count":"' + collectionName + '","query":{}}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?"}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?","lsid":{"id":"?"}}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?","$readPreference":{"mode":"?"}}' || - it == '{"count":"' + collectionName + '","$db":"?","lsid":{"id":"?"}}' - true - } - } - } - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - def "test delete"() { - when: - def collection = setupDelete(dbName, collectionName) - int deletedCount = runWithSpan("parent") { - delete(collection) - } - - then: - deletedCount == 1 - assertTraces(1) { - trace(0, 3) { - span(0) { - name "parent" - kind SpanKind.INTERNAL - hasNoParent() - } - mongoSpan(it, 1, "delete", collectionName, dbName, span(0)) { - assert it == '{"delete":"' + collectionName + '","ordered":"?","deletes":[{"q":{"password":"?"},"limit":"?"}]}' || - it == '{"delete":"' + collectionName + '","ordered":"?","$db":"?","deletes":[{"q":{"password":"?"},"limit":"?"}]}' || - it == '{"delete":"' + collectionName + '","ordered":"?","$db":"?","lsid":{"id":"?"},"deletes":[{"q":{"password":"?"},"limit":"?"}]}' - true - } - mongoSpan(it, 2, "count", collectionName, dbName, span(0)) { - assert it == '{"count":"' + collectionName + '","query":{}}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?"}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?","lsid":{"id":"?"}}' || - it == '{"count":"' + collectionName + '","query":{},"$db":"?","$readPreference":{"mode":"?"}}' || - it == '{"count":"' + collectionName + '","$db":"?","lsid":{"id":"?"}}' - true - } - } - } - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - def "test collection name for getMore command"() { - when: - def collection = setupGetMore(dbName, collectionName) - runWithSpan("parent") { - getMore(collection) - } - - then: - assertTraces(1) { - trace(0, 3) { - span(0) { - name "parent" - kind SpanKind.INTERNAL - hasNoParent() - } - mongoSpan(it, 1, "find", collectionName, dbName, span(0)) { - assert it == '{"find":"' + collectionName + '","filter":{"_id":{"$gte":"?"}},"batchSize":"?"}' || - it == '{"find":"' + collectionName + '","filter":{"_id":{"$gte":"?"}},"batchSize":"?","$db":"?"}' || - it == '{"find":"' + collectionName + '","filter":{"_id":{"$gte":"?"}},"batchSize":"?","$db":"?","$readPreference":{"mode":"?"}}' || - it == '{"find":"' + collectionName + '","filter":{"_id":{"$gte":"?"}},"batchSize":"?","$db":"?","lsid":{"id":"?"}}' - true - } - mongoSpan(it, 2, "getMore", collectionName, dbName, span(0)) { - assert it == '{"getMore":"?","collection":"?","batchSize":"?"}' || - it == '{"getMore":"?","collection":"?","batchSize":"?","$db":"?"}' || - it == '{"getMore":"?","collection":"?","batchSize":"?","$db":"?","$readPreference":{"mode":"?"}}' || - it == '{"getMore":"?","collection":"?","batchSize":"?","$db":"?","lsid":{"id":"?"}}' - true - } - } - } - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - def "test error"() { - when: - error(dbName, collectionName) - - then: - thrown(IllegalArgumentException) - // Unfortunately not caught by our instrumentation. - assertTraces(0) {} - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - def "test create collection with already built ClientOptions"() { - when: - runWithSpan("parent") { - createCollectionWithAlreadyBuiltClientOptions(dbName, collectionName) - } - - then: - assertTraces(1) { - trace(0, 2) { - span(0) { - name "parent" - kind SpanKind.INTERNAL - hasNoParent() - } - mongoSpan(it, 1, "create", collectionName, dbName, span(0)) { - assert it == '{"create":"' + collectionName + '","capped":"?"}' || - '{"create":"' + collectionName + '","capped":"?","$readPreference":{"mode":"?"}}' - true - } - } - } - - where: - dbName = "test_db" - collectionName = createCollectionName() - } - - private static final AtomicInteger collectionIndex = new AtomicInteger() - - def createCollectionName() { - return "testCollection-${collectionIndex.getAndIncrement()}" - } - - @SuppressWarnings("deprecation") // TODO DbIncubatingAttributes.DB_CONNECTION_STRING deprecation - def mongoSpan(TraceAssert trace, int index, - String operation, String collection, - String dbName, Object parentSpan, - Closure statementEval) { - trace.span(index) { - name operation + " " + dbName + "." + collection - kind CLIENT - if (parentSpan == null) { - hasNoParent() - } else { - childOf((SpanData) parentSpan) - } - attributes { - "$ServerAttributes.SERVER_ADDRESS" host - "$ServerAttributes.SERVER_PORT" port - "$DbIncubatingAttributes.DB_STATEMENT" { - statementEval.call(it.replaceAll(" ", "")) - } - "$DbIncubatingAttributes.DB_SYSTEM" "mongodb" - "$DbIncubatingAttributes.DB_CONNECTION_STRING" "mongodb://localhost:" + port - "$DbIncubatingAttributes.DB_NAME" dbName - "$DbIncubatingAttributes.DB_OPERATION" operation - "$DbIncubatingAttributes.DB_MONGODB_COLLECTION" collection - } - } - } -} diff --git a/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java new file mode 100644 index 000000000000..838436b9df62 --- /dev/null +++ b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java @@ -0,0 +1,659 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.mongo.testing; + +import static io.opentelemetry.api.trace.SpanKind.CLIENT; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; + +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; +import io.opentelemetry.sdk.testing.assertj.TraceAssert; +import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.semconv.ServerAttributes; +import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; +import java.net.Socket; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import org.assertj.core.api.Condition; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.platform.commons.util.StringUtils; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.output.Slf4jLogConsumer; + +@TestInstance(PER_CLASS) +public abstract class AbstractMongoClientTest { + + private static final AtomicInteger collectionIndex = new AtomicInteger(); + + private GenericContainer mongodb; + protected String host; + protected int port; + + @BeforeAll + void setupSpec() { + mongodb = + new GenericContainer<>("mongo:4.0") + .withExposedPorts(27017) + .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("mongodb"))); + mongodb.start(); + host = mongodb.getHost(); + port = mongodb.getMappedPort(27017); + } + + @AfterAll + void cleanupSpec() { + if (mongodb != null) { + mongodb.stop(); + } + } + + protected abstract InstrumentationExtension testing(); + + // Different client versions have different APIs to do these operations. If adding a test for a + // new + // version, refer to existing ones on how to implement these operations. + protected abstract void createCollection(String dbName, String collectionName); + + protected abstract void createCollectionNoDescription(String dbName, String collectionName) + throws InterruptedException; + + // Tests the fix for + // https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/457 + // TracingCommandListener might get added multiple times if clientOptions are built using existing + // clientOptions or when calling a build method twice. + // This test asserts that duplicate traces are not created in those cases. + protected abstract void createCollectionWithAlreadyBuiltClientOptions( + String dbName, String collectionName); + + protected abstract void createCollectionCallingBuildTwice(String dbName, String collectionName) + throws InterruptedException; + + protected abstract int getCollection(String dbName, String collectionName) throws Exception; + + protected abstract T setupInsert(String dbName, String collectionName) + throws InterruptedException; + + protected abstract int insert(T collection) throws Exception; + + protected abstract T setupUpdate(String dbName, String collectionName) + throws InterruptedException; + + protected abstract int update(T collection) throws Exception; + + protected abstract T setupDelete(String dbName, String collectionName) + throws InterruptedException; + + protected abstract int delete(T collection) throws Exception; + + protected abstract T setupGetMore(String dbName, String collectionName); + + protected abstract void getMore(T collection); + + protected abstract void error(String dbName, String collectionName) throws Throwable; + + protected void ignoreTracesAndClear(int numberOfTraces) { + testing().waitForTraces(numberOfTraces); + testing().clearData(); + } + + @Test + @DisplayName("test port open") + void testPortOpen() { + assertThatNoException().isThrownBy(() -> new Socket(host, port)); + } + + @Test + @DisplayName("test create collection") + void testCreateCollection() throws InterruptedException { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + testing().runWithSpan("parent", () -> createCollection(dbName, collectionName)); + testing() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), + span -> + mongoSpan( + trace, + 1, + "create", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, + "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}") + || Objects.equals( + str, + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\"}") + || Objects.equals( + str, + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") + || Objects.equals( + str, + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + } + + @Test + @DisplayName("test create collection no description") + void testCreateCollectionNoDescription() throws InterruptedException { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + testing().runWithSpan("parent", () -> createCollectionNoDescription(dbName, collectionName)); + + testing() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), + span -> + mongoSpan( + trace, + 1, + "create", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, + "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}") + || Objects.equals( + str, + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\"}") + || Objects.equals( + str, + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") + || Objects.equals( + str, + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + } + + @Test + @DisplayName("test create collection calling build twice") + void testCreateCollectionCallingBuildTwice() throws InterruptedException { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + testing() + .runWithSpan("parent", () -> createCollectionCallingBuildTwice(dbName, collectionName)); + + testing() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), + span -> + mongoSpan( + trace, + 1, + "create", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, + "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}") + || Objects.equals( + str, + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\"}") + || Objects.equals( + str, + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") + || Objects.equals( + str, + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + } + + @Test + @DisplayName("test get collection") + void testGetCollection() throws Exception { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + int count = testing().runWithSpan("parent", () -> getCollection(dbName, collectionName)); + assertThat(count).isEqualTo(0); + + testing() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), + span -> + mongoSpan( + trace, + 1, + "count", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, "{\"count\":\"" + collectionName + "\",\"query\":{}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\"}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + } + + @Test + @DisplayName("test insert") + void testInsert() throws Exception { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + T collection = setupInsert(dbName, collectionName); + int count = testing().runWithSpan("parent", () -> insert(collection)); + + assertThat(count).isEqualTo(1); + + testing() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), + span -> + mongoSpan( + trace, + 1, + "insert", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, + "{\"insert\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}") + || Objects.equals( + str, + "{\"insert\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}") + || Objects.equals( + str, + "{\"insert\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")), + span -> + mongoSpan( + trace, + 2, + "count", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, "{\"count\":\"" + collectionName + "\",\"query\":{}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\"}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + } + + @Test + @DisplayName("test update") + void testUpdate() throws Exception { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + T collection = setupUpdate(dbName, collectionName); + int modifiedCount = testing().runWithSpan("parent", () -> update(collection)); + + assertThat(modifiedCount).isEqualTo(1); + + testing() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), + span -> + mongoSpan( + trace, + 1, + "update", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, + "{\"update\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}") + || Objects.equals( + str, + "{\"update\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}") + || Objects.equals( + str, + "{\"update\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}")), + span -> + mongoSpan( + trace, + 2, + "count", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, "{\"count\":\"" + collectionName + "\",\"query\":{}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\"}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + } + + @Test + @DisplayName("test delete") + void testDelete() throws Exception { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + T collection = setupDelete(dbName, collectionName); + int deletedCount = testing().runWithSpan("parent", () -> delete(collection)); + + assertThat(deletedCount).isEqualTo(1); + + testing() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), + span -> + mongoSpan( + trace, + 1, + "delete", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, + "{\"delete\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}") + || Objects.equals( + str, + "{\"delete\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}") + || Objects.equals( + str, + "{\"delete\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")), + span -> + mongoSpan( + trace, + 2, + "count", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, "{\"count\":\"" + collectionName + "\",\"query\":{}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\"}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") + || Objects.equals( + str, + "{\"count\":\"" + + collectionName + + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + } + + @Test + @DisplayName("test collection name for getMore command") + void testCollectionNameForGetMoreCommand() { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + T collection = setupGetMore(dbName, collectionName); + testing().runWithSpan("parent", () -> getMore(collection)); + + testing() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), + span -> + mongoSpan( + trace, + 1, + "find", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, + "{\"find\":\"" + + collectionName + + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\"}") + || Objects.equals( + str, + "{\"find\":\"" + + collectionName + + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\"}") + || Objects.equals( + str, + "{\"find\":\"" + + collectionName + + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") + || Objects.equals( + str, + "{\"find\":\"" + + collectionName + + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")), + span -> + mongoSpan( + trace, + 2, + "getMore", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, + "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\"}") + || Objects.equals( + str, + "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\",\"$db\":\"?\"}") + || Objects.equals( + str, + "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") + || Objects.equals( + str, + "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + } + + @Test + @DisplayName("test error") + void testError() { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + assertThatIllegalArgumentException().isThrownBy(() -> error(dbName, collectionName)); + // Unfortunately not caught by our instrumentation. + testing().waitAndAssertTraces(); + } + + @Test + @DisplayName("test create collection with already built ClientOptions") + void testCreateCollectionWithAlreadyBuiltClientOptions() { + String dbName = "test_db"; + String collectionName = createCollectionName(); + + testing() + .runWithSpan( + "parent", () -> createCollectionWithAlreadyBuiltClientOptions(dbName, collectionName)); + + testing() + .waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), + span -> + mongoSpan( + trace, + 1, + "create", + collectionName, + dbName, + trace.getSpan(0), + str -> + Objects.equals( + str, + "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}") + || StringUtils.isNotBlank( + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}")))); + } + + protected String createCollectionName() { + return "testCollection-" + collectionIndex.getAndIncrement(); + } + + @SuppressWarnings("deprecation") + // TODO DbIncubatingAttributes.DB_CONNECTION_STRING deprecation + void mongoSpan( + TraceAssert trace, + int index, + String operation, + String collection, + String dbName, + Object parentSpan, + Function statementEval) { + SpanDataAssert span = + trace.element(index).hasName(operation + " " + dbName + "." + collection).hasKind(CLIENT); + if (parentSpan == null) { + span.hasNoParent(); + } else { + span.hasParent((SpanData) parentSpan); + } + + span.hasAttributesSatisfyingExactly( + equalTo(ServerAttributes.SERVER_ADDRESS, host), + equalTo(ServerAttributes.SERVER_PORT, port), + satisfies( + DbIncubatingAttributes.DB_STATEMENT, + val -> + val.is( + new Condition<>( + statement -> statementEval.apply(statement.replaceAll(" ", "")), ""))), + equalTo(DbIncubatingAttributes.DB_SYSTEM, "mongodb"), + equalTo(DbIncubatingAttributes.DB_CONNECTION_STRING, "mongodb://localhost:" + port), + equalTo(DbIncubatingAttributes.DB_NAME, dbName), + equalTo(DbIncubatingAttributes.DB_OPERATION, operation), + equalTo(DbIncubatingAttributes.DB_MONGODB_COLLECTION, collection)); + } +} From d5e1efc12c5b3907273a8c26ba884467b3808986 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Thu, 3 Oct 2024 01:42:33 +0800 Subject: [PATCH 02/13] Fix unit test errors --- .../mongo/v3_1/AbstractMongo31ClientTest.java | 18 +- .../mongoasync/v3_3/MongoAsyncClientTest.java | 449 +++++++++--------- 2 files changed, 235 insertions(+), 232 deletions(-) diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java index e2ae6568e3bc..fac1489087f0 100644 --- a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java +++ b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java @@ -60,9 +60,9 @@ protected void createCollection(String dbName, String collectionName) { protected void createCollectionNoDescription(String dbName, String collectionName) { MongoClientOptions.Builder options = MongoClientOptions.builder(); configureMongoClientOptions(options); - try (MongoClient client = new MongoClient(new ServerAddress(host, port), options.build())) { - client.getDatabase(dbName).createCollection(collectionName); - } + MongoDatabase db = new MongoClient(new ServerAddress(host, port), options.build()).getDatabase( + dbName); + db.createCollection(collectionName); } @Override @@ -70,9 +70,9 @@ protected void createCollectionWithAlreadyBuiltClientOptions( String dbName, String collectionName) { MongoClientOptions clientOptions = client.getMongoClientOptions(); MongoClientOptions newClientOptions = MongoClientOptions.builder(clientOptions).build(); - try (MongoClient client = new MongoClient(new ServerAddress(host, port), newClientOptions)) { - client.getDatabase(dbName).createCollection(collectionName); - } + MongoDatabase db = new MongoClient(new ServerAddress(host, port), newClientOptions).getDatabase( + dbName); + db.createCollection(collectionName); } @Override @@ -81,9 +81,9 @@ protected void createCollectionCallingBuildTwice(String dbName, String collectio MongoClientOptions.builder().description("some-description"); configureMongoClientOptions(options); options.build(); - try (MongoClient client = new MongoClient(new ServerAddress(host, port), options.build())) { - client.getDatabase(dbName).createCollection(collectionName); - } + MongoDatabase db = new MongoClient(new ServerAddress(host, port), options.build()).getDatabase( + dbName); + db.createCollection(collectionName); } @Override diff --git a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java index c7eeb40c172c..b13ed03e61c4 100644 --- a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java +++ b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java @@ -18,9 +18,6 @@ import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.function.Consumer; import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.Document; @@ -29,226 +26,232 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.opentest4j.TestAbortedException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; + class MongoAsyncClientTest extends AbstractMongoClientTest> { - @RegisterExtension - static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); - - private MongoClient client; - - @BeforeAll - public void setupSpec() { - client = - MongoClients.create( - MongoClientSettings.builder() - .clusterSettings( - ClusterSettings.builder() - .description("some-description") - .applyConnectionString( - new ConnectionString("mongodb://" + host + ":" + port)) - .build()) - .build()); - } - - @AfterAll - public void cleanupSpec() { - if (client != null) { - client.close(); - client = null; - } - } - - @Override - protected InstrumentationExtension testing() { - return testing; - } - - @Override - public void createCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName); - db.createCollection(collectionName, toCallback(result -> {})); - } - - @Override - public void createCollectionNoDescription(String dbName, String collectionName) { - MongoDatabase db = MongoClients.create("mongodb://" + host + ":" + port).getDatabase(dbName); - db.createCollection(collectionName, toCallback(result -> {})); - } - - @Override - public void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { - MongoClientSettings clientSettings = client.getSettings(); - MongoClientSettings newClientSettings = MongoClientSettings.builder(clientSettings).build(); - MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName); - db.createCollection(collectionName, toCallback(result -> {})); - } - - @Override - public void createCollectionCallingBuildTwice(String dbName, String collectionName) { - MongoClientSettings.Builder settings = - MongoClientSettings.builder() - .clusterSettings( - ClusterSettings.builder() - .description("some-description") - .applyConnectionString(new ConnectionString("mongodb://" + host + ":" + port)) - .build()); - settings.build(); - MongoDatabase db = MongoClients.create(settings.build()).getDatabase(dbName); - db.createCollection(collectionName, toCallback(result -> {})); - } - - @Override - public int getCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName); - CompletableFuture count = new CompletableFuture<>(); - db.getCollection(collectionName).count(toCallback(o -> count.complete(((Long) o)))); - return count.join().intValue(); - } - - @Override - public MongoCollection setupInsert(String dbName, String collectionName) - throws InterruptedException { - MongoCollection collection = - testing() - .runWithSpan( - "setup", - () -> { - MongoDatabase db = client.getDatabase(dbName); - CountDownLatch latch = new CountDownLatch(1); - db.createCollection(collectionName, toCallback(result -> latch.countDown())); - latch.await(); - return db.getCollection(collectionName); - }); - ignoreTracesAndClear(1); - return collection; - } - - @Override - public int insert(MongoCollection collection) { - CompletableFuture count = new CompletableFuture<>(); - collection.insertOne( - new Document("password", "SECRET"), - toCallback( - result -> { - collection.count(toCallback(o -> count.complete(((Long) o)))); - })); - return count.join().intValue(); - } - - @Override - public MongoCollection setupUpdate(String dbName, String collectionName) - throws InterruptedException { - MongoCollection collection = - testing() - .runWithSpan( - "setup", - () -> { - MongoDatabase db = client.getDatabase(dbName); - CountDownLatch latch1 = new CountDownLatch(1); - db.createCollection(collectionName, toCallback(result -> latch1.countDown())); - latch1.await(); - MongoCollection coll = db.getCollection(collectionName); - CountDownLatch latch2 = new CountDownLatch(1); - coll.insertOne( - new Document("password", "OLDPW"), toCallback(result -> latch2.countDown())); - latch2.await(); - return coll; - }); - ignoreTracesAndClear(1); - return collection; - } - - @Override - public int update(MongoCollection collection) { - CompletableFuture result = new CompletableFuture<>(); - CompletableFuture count = new CompletableFuture<>(); - collection.updateOne( - new BsonDocument("password", new BsonString("OLDPW")), - new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW"))), - toCallback( - res -> { - result.complete(((UpdateResult) res)); - collection.count(toCallback(o -> count.complete(((Long) o)))); - })); - return (int) result.join().getModifiedCount(); - } - - @Override - public MongoCollection setupDelete(String dbName, String collectionName) - throws InterruptedException { - MongoCollection collection = - testing() - .runWithSpan( - "setup", - () -> { - MongoDatabase db = client.getDatabase(dbName); - CountDownLatch latch1 = new CountDownLatch(1); - db.createCollection(collectionName, toCallback(result -> latch1.countDown())); - latch1.await(); - MongoCollection coll = db.getCollection(collectionName); - CountDownLatch latch2 = new CountDownLatch(1); - coll.insertOne( - new Document("password", "SECRET"), toCallback(result -> latch2.countDown())); - latch2.await(); - return coll; - }); - ignoreTracesAndClear(1); - return collection; - } - - @Override - public int delete(MongoCollection collection) { - CompletableFuture result = new CompletableFuture<>(); - CompletableFuture count = new CompletableFuture<>(); - collection.deleteOne( - new BsonDocument("password", new BsonString("SECRET")), - toCallback( - res -> { - result.complete((DeleteResult) res); - collection.count(toCallback(value -> count.complete(((Long) value)))); - })); - return (int) result.join().getDeletedCount(); - } - - @Override - public MongoCollection setupGetMore(String dbName, String collectionName) { - throw new TestAbortedException("not tested on async"); - } - - @Override - public void getMore(MongoCollection collection) { - throw new TestAbortedException("not tested on async"); - } - - @Override - public void error(String dbName, String collectionName) throws Throwable { - MongoCollection collection = - testing() - .runWithSpan( - "setup", - () -> { - MongoDatabase db = client.getDatabase(dbName); - CountDownLatch latch = new CountDownLatch(1); - db.createCollection(collectionName, toCallback(result -> latch.countDown())); - latch.await(); - return db.getCollection(collectionName); - }); - ignoreTracesAndClear(1); - CompletableFuture result = new CompletableFuture<>(); - collection.updateOne( - new BsonDocument(), - new BsonDocument(), - toCallback(res -> result.complete((Throwable) res))); - throw result.join(); - } - - SingleResultCallback toCallback(Consumer closure) { - return (result, t) -> { - if (t != null) { - closure.accept(t); - } else { - closure.accept(result); - } - }; - } + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private MongoClient client; + + @BeforeAll + public void setupSpec() { + client = + MongoClients.create( + MongoClientSettings.builder() + .clusterSettings( + ClusterSettings.builder() + .description("some-description") + .applyConnectionString( + new ConnectionString("mongodb://" + host + ":" + port)) + .build()) + .build()); + } + + @AfterAll + public void cleanupSpec() { + if (client != null) { + client.close(); + client = null; + } + } + + @Override + protected InstrumentationExtension testing() { + return testing; + } + + @Override + public void createCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> { + })); + } + + @Override + public void createCollectionNoDescription(String dbName, String collectionName) { + MongoDatabase db = MongoClients.create("mongodb://" + host + ":" + port).getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> { + })); + } + + @Override + public void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { + MongoClientSettings clientSettings = client.getSettings(); + MongoClientSettings newClientSettings = MongoClientSettings.builder(clientSettings).build(); + MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> { + })); + } + + @Override + public void createCollectionCallingBuildTwice(String dbName, String collectionName) { + MongoClientSettings.Builder settings = + MongoClientSettings.builder() + .clusterSettings( + ClusterSettings.builder() + .description("some-description") + .applyConnectionString(new ConnectionString("mongodb://" + host + ":" + port)) + .build()); + settings.build(); + MongoDatabase db = MongoClients.create(settings.build()).getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> { + })); + } + + @Override + public int getCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + CompletableFuture count = new CompletableFuture<>(); + db.getCollection(collectionName).count(toCallback(o -> count.complete(((Long) o)))); + return count.join().intValue(); + } + + @Override + public MongoCollection setupInsert(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch.countDown())); + latch.await(); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int insert(MongoCollection collection) { + CompletableFuture count = new CompletableFuture<>(); + collection.insertOne( + new Document("password", "SECRET"), + toCallback( + result -> collection.count(toCallback(o -> count.complete(((Long) o)))))); + return count.join().intValue(); + } + + @Override + public MongoCollection setupUpdate(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch1 = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch1.countDown())); + latch1.await(); + MongoCollection coll = db.getCollection(collectionName); + CountDownLatch latch2 = new CountDownLatch(1); + coll.insertOne( + new Document("password", "OLDPW"), toCallback(result -> latch2.countDown())); + latch2.await(); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int update(MongoCollection collection) { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); + collection.updateOne( + new BsonDocument("password", new BsonString("OLDPW")), + new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW"))), + toCallback( + res -> { + result.complete(((UpdateResult) res)); + collection.count(toCallback(o -> count.complete(((Long) o)))); + })); + return (int) result.join().getModifiedCount(); + } + + @Override + public MongoCollection setupDelete(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch1 = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch1.countDown())); + latch1.await(); + MongoCollection coll = db.getCollection(collectionName); + CountDownLatch latch2 = new CountDownLatch(1); + coll.insertOne( + new Document("password", "SECRET"), toCallback(result -> latch2.countDown())); + latch2.await(); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int delete(MongoCollection collection) { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); + collection.deleteOne( + new BsonDocument("password", new BsonString("SECRET")), + toCallback( + res -> { + result.complete((DeleteResult) res); + collection.count(toCallback(value -> count.complete(((Long) value)))); + })); + return (int) result.join().getDeletedCount(); + } + + @Override + public MongoCollection setupGetMore(String dbName, String collectionName) { + throw new TestAbortedException("not tested on async"); + } + + @Override + public void getMore(MongoCollection collection) { + throw new TestAbortedException("not tested on async"); + } + + @Override + public void error(String dbName, String collectionName) throws Throwable { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch.countDown())); + latch.await(); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + CompletableFuture result = new CompletableFuture<>(); + collection.updateOne( + new BsonDocument(), + new BsonDocument(), + toCallback(res -> result.complete((Throwable) res))); + throw result.join(); + } + + SingleResultCallback toCallback(Consumer closure) { + return (result, t) -> { + if (t != null) { + closure.accept(t); + } else { + closure.accept(result); + } + }; + } } From bec97ce4427521db84abe1abd38bb6c0d12c8628 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Thu, 3 Oct 2024 01:53:51 +0800 Subject: [PATCH 03/13] Spotless apply --- .../mongo/v3_1/AbstractMongo31ClientTest.java | 12 +- .../mongoasync/v3_3/MongoAsyncClientTest.java | 446 +++++++++--------- 2 files changed, 226 insertions(+), 232 deletions(-) diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java index fac1489087f0..5065d1035cde 100644 --- a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java +++ b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java @@ -60,8 +60,8 @@ protected void createCollection(String dbName, String collectionName) { protected void createCollectionNoDescription(String dbName, String collectionName) { MongoClientOptions.Builder options = MongoClientOptions.builder(); configureMongoClientOptions(options); - MongoDatabase db = new MongoClient(new ServerAddress(host, port), options.build()).getDatabase( - dbName); + MongoDatabase db = + new MongoClient(new ServerAddress(host, port), options.build()).getDatabase(dbName); db.createCollection(collectionName); } @@ -70,8 +70,8 @@ protected void createCollectionWithAlreadyBuiltClientOptions( String dbName, String collectionName) { MongoClientOptions clientOptions = client.getMongoClientOptions(); MongoClientOptions newClientOptions = MongoClientOptions.builder(clientOptions).build(); - MongoDatabase db = new MongoClient(new ServerAddress(host, port), newClientOptions).getDatabase( - dbName); + MongoDatabase db = + new MongoClient(new ServerAddress(host, port), newClientOptions).getDatabase(dbName); db.createCollection(collectionName); } @@ -81,8 +81,8 @@ protected void createCollectionCallingBuildTwice(String dbName, String collectio MongoClientOptions.builder().description("some-description"); configureMongoClientOptions(options); options.build(); - MongoDatabase db = new MongoClient(new ServerAddress(host, port), options.build()).getDatabase( - dbName); + MongoDatabase db = + new MongoClient(new ServerAddress(host, port), options.build()).getDatabase(dbName); db.createCollection(collectionName); } diff --git a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java index b13ed03e61c4..94556b615aa0 100644 --- a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java +++ b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java @@ -18,6 +18,9 @@ import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.Document; @@ -26,232 +29,223 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.opentest4j.TestAbortedException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.function.Consumer; - class MongoAsyncClientTest extends AbstractMongoClientTest> { - @RegisterExtension - static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); - - private MongoClient client; - - @BeforeAll - public void setupSpec() { - client = - MongoClients.create( - MongoClientSettings.builder() - .clusterSettings( - ClusterSettings.builder() - .description("some-description") - .applyConnectionString( - new ConnectionString("mongodb://" + host + ":" + port)) - .build()) - .build()); - } - - @AfterAll - public void cleanupSpec() { - if (client != null) { - client.close(); - client = null; - } - } - - @Override - protected InstrumentationExtension testing() { - return testing; - } - - @Override - public void createCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName); - db.createCollection(collectionName, toCallback(result -> { - })); - } - - @Override - public void createCollectionNoDescription(String dbName, String collectionName) { - MongoDatabase db = MongoClients.create("mongodb://" + host + ":" + port).getDatabase(dbName); - db.createCollection(collectionName, toCallback(result -> { - })); - } - - @Override - public void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { - MongoClientSettings clientSettings = client.getSettings(); - MongoClientSettings newClientSettings = MongoClientSettings.builder(clientSettings).build(); - MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName); - db.createCollection(collectionName, toCallback(result -> { - })); - } - - @Override - public void createCollectionCallingBuildTwice(String dbName, String collectionName) { - MongoClientSettings.Builder settings = - MongoClientSettings.builder() - .clusterSettings( - ClusterSettings.builder() - .description("some-description") - .applyConnectionString(new ConnectionString("mongodb://" + host + ":" + port)) - .build()); - settings.build(); - MongoDatabase db = MongoClients.create(settings.build()).getDatabase(dbName); - db.createCollection(collectionName, toCallback(result -> { - })); - } - - @Override - public int getCollection(String dbName, String collectionName) { - MongoDatabase db = client.getDatabase(dbName); - CompletableFuture count = new CompletableFuture<>(); - db.getCollection(collectionName).count(toCallback(o -> count.complete(((Long) o)))); - return count.join().intValue(); - } - - @Override - public MongoCollection setupInsert(String dbName, String collectionName) - throws InterruptedException { - MongoCollection collection = - testing() - .runWithSpan( - "setup", - () -> { - MongoDatabase db = client.getDatabase(dbName); - CountDownLatch latch = new CountDownLatch(1); - db.createCollection(collectionName, toCallback(result -> latch.countDown())); - latch.await(); - return db.getCollection(collectionName); - }); - ignoreTracesAndClear(1); - return collection; - } - - @Override - public int insert(MongoCollection collection) { - CompletableFuture count = new CompletableFuture<>(); - collection.insertOne( - new Document("password", "SECRET"), - toCallback( - result -> collection.count(toCallback(o -> count.complete(((Long) o)))))); - return count.join().intValue(); - } - - @Override - public MongoCollection setupUpdate(String dbName, String collectionName) - throws InterruptedException { - MongoCollection collection = - testing() - .runWithSpan( - "setup", - () -> { - MongoDatabase db = client.getDatabase(dbName); - CountDownLatch latch1 = new CountDownLatch(1); - db.createCollection(collectionName, toCallback(result -> latch1.countDown())); - latch1.await(); - MongoCollection coll = db.getCollection(collectionName); - CountDownLatch latch2 = new CountDownLatch(1); - coll.insertOne( - new Document("password", "OLDPW"), toCallback(result -> latch2.countDown())); - latch2.await(); - return coll; - }); - ignoreTracesAndClear(1); - return collection; - } - - @Override - public int update(MongoCollection collection) { - CompletableFuture result = new CompletableFuture<>(); - CompletableFuture count = new CompletableFuture<>(); - collection.updateOne( - new BsonDocument("password", new BsonString("OLDPW")), - new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW"))), - toCallback( - res -> { - result.complete(((UpdateResult) res)); - collection.count(toCallback(o -> count.complete(((Long) o)))); - })); - return (int) result.join().getModifiedCount(); - } - - @Override - public MongoCollection setupDelete(String dbName, String collectionName) - throws InterruptedException { - MongoCollection collection = - testing() - .runWithSpan( - "setup", - () -> { - MongoDatabase db = client.getDatabase(dbName); - CountDownLatch latch1 = new CountDownLatch(1); - db.createCollection(collectionName, toCallback(result -> latch1.countDown())); - latch1.await(); - MongoCollection coll = db.getCollection(collectionName); - CountDownLatch latch2 = new CountDownLatch(1); - coll.insertOne( - new Document("password", "SECRET"), toCallback(result -> latch2.countDown())); - latch2.await(); - return coll; - }); - ignoreTracesAndClear(1); - return collection; - } - - @Override - public int delete(MongoCollection collection) { - CompletableFuture result = new CompletableFuture<>(); - CompletableFuture count = new CompletableFuture<>(); - collection.deleteOne( - new BsonDocument("password", new BsonString("SECRET")), - toCallback( - res -> { - result.complete((DeleteResult) res); - collection.count(toCallback(value -> count.complete(((Long) value)))); - })); - return (int) result.join().getDeletedCount(); - } - - @Override - public MongoCollection setupGetMore(String dbName, String collectionName) { - throw new TestAbortedException("not tested on async"); - } - - @Override - public void getMore(MongoCollection collection) { - throw new TestAbortedException("not tested on async"); - } - - @Override - public void error(String dbName, String collectionName) throws Throwable { - MongoCollection collection = - testing() - .runWithSpan( - "setup", - () -> { - MongoDatabase db = client.getDatabase(dbName); - CountDownLatch latch = new CountDownLatch(1); - db.createCollection(collectionName, toCallback(result -> latch.countDown())); - latch.await(); - return db.getCollection(collectionName); - }); - ignoreTracesAndClear(1); - CompletableFuture result = new CompletableFuture<>(); - collection.updateOne( - new BsonDocument(), - new BsonDocument(), - toCallback(res -> result.complete((Throwable) res))); - throw result.join(); - } - - SingleResultCallback toCallback(Consumer closure) { - return (result, t) -> { - if (t != null) { - closure.accept(t); - } else { - closure.accept(result); - } - }; - } + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private MongoClient client; + + @BeforeAll + public void setupSpec() { + client = + MongoClients.create( + MongoClientSettings.builder() + .clusterSettings( + ClusterSettings.builder() + .description("some-description") + .applyConnectionString( + new ConnectionString("mongodb://" + host + ":" + port)) + .build()) + .build()); + } + + @AfterAll + public void cleanupSpec() { + if (client != null) { + client.close(); + client = null; + } + } + + @Override + protected InstrumentationExtension testing() { + return testing; + } + + @Override + public void createCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> {})); + } + + @Override + public void createCollectionNoDescription(String dbName, String collectionName) { + MongoDatabase db = MongoClients.create("mongodb://" + host + ":" + port).getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> {})); + } + + @Override + public void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) { + MongoClientSettings clientSettings = client.getSettings(); + MongoClientSettings newClientSettings = MongoClientSettings.builder(clientSettings).build(); + MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> {})); + } + + @Override + public void createCollectionCallingBuildTwice(String dbName, String collectionName) { + MongoClientSettings.Builder settings = + MongoClientSettings.builder() + .clusterSettings( + ClusterSettings.builder() + .description("some-description") + .applyConnectionString(new ConnectionString("mongodb://" + host + ":" + port)) + .build()); + settings.build(); + MongoDatabase db = MongoClients.create(settings.build()).getDatabase(dbName); + db.createCollection(collectionName, toCallback(result -> {})); + } + + @Override + public int getCollection(String dbName, String collectionName) { + MongoDatabase db = client.getDatabase(dbName); + CompletableFuture count = new CompletableFuture<>(); + db.getCollection(collectionName).count(toCallback(o -> count.complete(((Long) o)))); + return count.join().intValue(); + } + + @Override + public MongoCollection setupInsert(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch.countDown())); + latch.await(); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int insert(MongoCollection collection) { + CompletableFuture count = new CompletableFuture<>(); + collection.insertOne( + new Document("password", "SECRET"), + toCallback(result -> collection.count(toCallback(o -> count.complete(((Long) o)))))); + return count.join().intValue(); + } + + @Override + public MongoCollection setupUpdate(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch1 = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch1.countDown())); + latch1.await(); + MongoCollection coll = db.getCollection(collectionName); + CountDownLatch latch2 = new CountDownLatch(1); + coll.insertOne( + new Document("password", "OLDPW"), toCallback(result -> latch2.countDown())); + latch2.await(); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int update(MongoCollection collection) { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); + collection.updateOne( + new BsonDocument("password", new BsonString("OLDPW")), + new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW"))), + toCallback( + res -> { + result.complete(((UpdateResult) res)); + collection.count(toCallback(o -> count.complete(((Long) o)))); + })); + return (int) result.join().getModifiedCount(); + } + + @Override + public MongoCollection setupDelete(String dbName, String collectionName) + throws InterruptedException { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch1 = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch1.countDown())); + latch1.await(); + MongoCollection coll = db.getCollection(collectionName); + CountDownLatch latch2 = new CountDownLatch(1); + coll.insertOne( + new Document("password", "SECRET"), toCallback(result -> latch2.countDown())); + latch2.await(); + return coll; + }); + ignoreTracesAndClear(1); + return collection; + } + + @Override + public int delete(MongoCollection collection) { + CompletableFuture result = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); + collection.deleteOne( + new BsonDocument("password", new BsonString("SECRET")), + toCallback( + res -> { + result.complete((DeleteResult) res); + collection.count(toCallback(value -> count.complete(((Long) value)))); + })); + return (int) result.join().getDeletedCount(); + } + + @Override + public MongoCollection setupGetMore(String dbName, String collectionName) { + throw new TestAbortedException("not tested on async"); + } + + @Override + public void getMore(MongoCollection collection) { + throw new TestAbortedException("not tested on async"); + } + + @Override + public void error(String dbName, String collectionName) throws Throwable { + MongoCollection collection = + testing() + .runWithSpan( + "setup", + () -> { + MongoDatabase db = client.getDatabase(dbName); + CountDownLatch latch = new CountDownLatch(1); + db.createCollection(collectionName, toCallback(result -> latch.countDown())); + latch.await(); + return db.getCollection(collectionName); + }); + ignoreTracesAndClear(1); + CompletableFuture result = new CompletableFuture<>(); + collection.updateOne( + new BsonDocument(), + new BsonDocument(), + toCallback(res -> result.complete((Throwable) res))); + throw result.join(); + } + + SingleResultCallback toCallback(Consumer closure) { + return (result, t) -> { + if (t != null) { + closure.accept(t); + } else { + closure.accept(result); + } + }; + } } From 3f52cabb8b048abb69492fccfd56cebda1b66ea7 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Thu, 3 Oct 2024 14:23:46 +0800 Subject: [PATCH 04/13] 1. Rename the function names "setupSpec" and "cleanupSpec" to "setup" and "cleanup" 2. Collection tool class methods use static import Signed-off-by: xiepuhuan --- .../mongo/v3_1/MongoDbAttributesGetterTest.java | 5 ++--- .../mongo/v3_1/AbstractMongo31ClientTest.java | 4 ++-- .../instrumentation/mongo/v3_7/MongoClientTest.java | 8 ++++---- .../mongo/v4_0/Mongo4ReactiveClientTest.java | 9 +++++---- .../instrumentation/mongo/v4_0/MongoClientTest.java | 13 +++++++------ .../mongoasync/v3_3/MongoAsyncClientTest.java | 4 ++-- .../mongo/testing/AbstractMongoClientTest.java | 4 ++-- 7 files changed, 24 insertions(+), 23 deletions(-) diff --git a/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java index 9a4b3b91fc70..b9f08adc0ab3 100644 --- a/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java +++ b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java @@ -6,10 +6,10 @@ package io.opentelemetry.instrumentation.mongo.v3_1; import static io.opentelemetry.instrumentation.mongo.v3_1.MongoTelemetryBuilder.DEFAULT_MAX_NORMALIZED_QUERY_LENGTH; +import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; -import java.util.Arrays; import org.bson.BsonArray; import org.bson.BsonDocument; import org.bson.BsonInt32; @@ -84,8 +84,7 @@ void shouldTruncateArray() { sanitizeStatementAcrossVersions( extractor, new BsonDocument("cmd", new BsonString("c")) - .append( - "f1", new BsonArray(Arrays.asList(new BsonString("c1"), new BsonString("c2")))) + .append("f1", new BsonArray(asList(new BsonString("c1"), new BsonString("c2")))) .append("f2", new BsonString("c3"))); // This can vary because of different whitespace for different MongoDB versions diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java index 5065d1035cde..0b08b88cb729 100644 --- a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java +++ b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java @@ -35,7 +35,7 @@ public abstract class AbstractMongo31ClientTest private MongoClient client; @BeforeAll - public void setupSpec() { + public void setup() { MongoClientOptions.Builder options = MongoClientOptions.builder().description("some-description"); configureMongoClientOptions(options); @@ -43,7 +43,7 @@ public void setupSpec() { } @AfterAll - public void cleanupSpec() { + public void cleanup() { if (client != null) { client.close(); } diff --git a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java index f822f6b76b48..7e5df74e08bf 100644 --- a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java +++ b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.mongo.v3_7; import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT; +import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -22,7 +23,6 @@ import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import java.util.ArrayList; -import java.util.Arrays; import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.Document; @@ -40,7 +40,7 @@ class MongoClientTest extends AbstractMongoClientTest> private MongoClient client; @BeforeAll - void setupSpec() { + void setup() { client = MongoClients.create( MongoClientSettings.builder() @@ -53,7 +53,7 @@ void setupSpec() { } @AfterAll - void cleanupSpec() { + void cleanup() { if (client != null) { client.close(); client = null; @@ -196,7 +196,7 @@ protected MongoCollection setupGetMore(String dbName, String collectio MongoDatabase db = client.getDatabase(dbName); MongoCollection coll = db.getCollection(collectionName); coll.insertMany( - Arrays.asList( + asList( new Document("_id", 0), new Document("_id", 1), new Document("_id", 2))); return coll; }); diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java index b83c423a03dc..9b4b549e9ef4 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java @@ -5,6 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.mongo.v4_0; +import static java.util.Collections.singletonList; + import com.mongodb.MongoClientSettings; import com.mongodb.ServerAddress; import com.mongodb.client.result.DeleteResult; @@ -17,7 +19,6 @@ import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; @@ -45,12 +46,12 @@ class Mongo4ReactiveClientTest extends AbstractMongoClientTest cleanup = new ArrayList<>(); @BeforeAll - public void setupSpec() { + public void setup() { client = MongoClients.create("mongodb://" + host + ":" + port); } @AfterAll - public void cleanupSpec() throws Exception { + public void cleanup() throws Exception { if (client != null) { client.close(); client = null; @@ -100,7 +101,7 @@ public void createCollectionCallingBuildTwice(String dbName, String collectionNa MongoClientSettings.Builder settings = MongoClientSettings.builder() .applyToClusterSettings( - builder -> builder.hosts(Collections.singletonList(new ServerAddress(host, port)))); + builder -> builder.hosts(singletonList(new ServerAddress(host, port)))); settings.build(); MongoClient tmpClient = MongoClients.create(settings.build()); cleanup.add(tmpClient); diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java index c6b5764496a5..32eec3e84103 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java @@ -5,6 +5,9 @@ package io.opentelemetry.javaagent.instrumentation.mongo.v4_0; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; + import com.mongodb.MongoClientSettings; import com.mongodb.ServerAddress; import com.mongodb.client.MongoClient; @@ -17,8 +20,6 @@ import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.Document; @@ -35,12 +36,12 @@ class MongoClientTest extends AbstractMongoClientTest> private MongoClient client; @BeforeAll - public void setupSpec() { + public void setup() { client = MongoClients.create("mongodb://" + host + ":" + port); } @AfterAll - public void cleanupSpec() { + public void cleanup() { if (client != null) { client.close(); client = null; @@ -74,7 +75,7 @@ public void createCollectionCallingBuildTwice(String dbName, String collectionNa MongoClientSettings settings = MongoClientSettings.builder() .applyToClusterSettings( - builder -> builder.hosts(Collections.singletonList(new ServerAddress(host, port)))) + builder -> builder.hosts(singletonList(new ServerAddress(host, port)))) .build(); MongoDatabase db = MongoClients.create(settings).getDatabase(dbName); db.createCollection(collectionName); @@ -169,7 +170,7 @@ public MongoCollection setupGetMore(String dbName, String collectionNa MongoDatabase db = client.getDatabase(dbName); MongoCollection coll = db.getCollection(collectionName); coll.insertMany( - Arrays.asList( + asList( new Document("_id", 0), new Document("_id", 1), new Document("_id", 2))); return coll; }); diff --git a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java index 94556b615aa0..be8c41b93125 100644 --- a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java +++ b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java @@ -37,7 +37,7 @@ class MongoAsyncClientTest extends AbstractMongoClientTest { protected int port; @BeforeAll - void setupSpec() { + void setup() { mongodb = new GenericContainer<>("mongo:4.0") .withExposedPorts(27017) @@ -56,7 +56,7 @@ void setupSpec() { } @AfterAll - void cleanupSpec() { + void cleanup() { if (mongodb != null) { mongodb.stop(); } From ad90b35260d5748b6c0d1eb8eb778fd88baf5c2e Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Thu, 3 Oct 2024 19:10:23 +0800 Subject: [PATCH 05/13] Make function to package private Signed-off-by: xiepuhuan --- .../mongo/v3_1/AbstractMongo31ClientTest.java | 6 +++--- .../instrumentation/mongo/v3_7/MongoClientTest.java | 7 ++----- .../mongo/v4_0/Mongo4ReactiveClientTest.java | 4 ++-- .../instrumentation/mongo/v4_0/MongoClientTest.java | 4 ++-- .../mongoasync/v3_3/MongoAsyncClientTest.java | 4 ++-- .../mongo/testing/AbstractMongoClientTest.java | 5 +---- 6 files changed, 12 insertions(+), 18 deletions(-) diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java index 0b08b88cb729..f7036898cfe3 100644 --- a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java +++ b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java @@ -35,7 +35,7 @@ public abstract class AbstractMongo31ClientTest private MongoClient client; @BeforeAll - public void setup() { + void setup() { MongoClientOptions.Builder options = MongoClientOptions.builder().description("some-description"); configureMongoClientOptions(options); @@ -43,7 +43,7 @@ public void setup() { } @AfterAll - public void cleanup() { + void cleanup() { if (client != null) { client.close(); } @@ -209,7 +209,7 @@ protected void error(String dbName, String collectionName) { @Test @DisplayName("test client failure") - public void testClientFailure() { + void testClientFailure() { MongoClientOptions options = MongoClientOptions.builder().serverSelectionTimeout(10).build(); MongoClient client = new MongoClient(new ServerAddress(host, PortUtils.UNUSABLE_PORT), options); diff --git a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java index 7e5df74e08bf..4c7a741bf585 100644 --- a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java +++ b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java @@ -231,16 +231,13 @@ protected void error(String dbName, String collectionName) { @Test @DisplayName("test client failure") void testClientFailure() { - String dbName = "test_db"; - String collectionName = createCollectionName(); - MongoClient client = MongoClients.create("mongodb://" + host + ":" + UNUSABLE_PORT + "/?connectTimeoutMS=10"); assertThatThrownBy( () -> { - MongoDatabase db = client.getDatabase(dbName); - db.createCollection(collectionName); + MongoDatabase db = client.getDatabase("test_db"); + db.createCollection(createCollectionName()); }) .isInstanceOf(MongoTimeoutException.class); // Unfortunately not caught by our instrumentation. diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java index 9b4b549e9ef4..1014580239fb 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java @@ -46,12 +46,12 @@ class Mongo4ReactiveClientTest extends AbstractMongoClientTest cleanup = new ArrayList<>(); @BeforeAll - public void setup() { + void setup() { client = MongoClients.create("mongodb://" + host + ":" + port); } @AfterAll - public void cleanup() throws Exception { + void cleanup() throws Exception { if (client != null) { client.close(); client = null; diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java index 32eec3e84103..8cce2b0060b6 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java @@ -36,12 +36,12 @@ class MongoClientTest extends AbstractMongoClientTest> private MongoClient client; @BeforeAll - public void setup() { + void setup() { client = MongoClients.create("mongodb://" + host + ":" + port); } @AfterAll - public void cleanup() { + void cleanup() { if (client != null) { client.close(); client = null; diff --git a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java index be8c41b93125..70e3dbd5fd58 100644 --- a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java +++ b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java @@ -37,7 +37,7 @@ class MongoAsyncClientTest extends AbstractMongoClientTest error(dbName, collectionName)); + assertThatIllegalArgumentException().isThrownBy(() -> error("test_db", createCollectionName())); // Unfortunately not caught by our instrumentation. testing().waitAndAssertTraces(); } From b65591dbc7d00606b12e44cc3e793d2c34cebc23 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Thu, 3 Oct 2024 19:15:01 +0800 Subject: [PATCH 06/13] Remove local variable definition Signed-off-by: xiepuhuan --- .../mongo/v3_1/AbstractMongo31ClientTest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java index f7036898cfe3..f608e4e128b5 100644 --- a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java +++ b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java @@ -213,14 +213,11 @@ void testClientFailure() { MongoClientOptions options = MongoClientOptions.builder().serverSelectionTimeout(10).build(); MongoClient client = new MongoClient(new ServerAddress(host, PortUtils.UNUSABLE_PORT), options); - String dbName = "test_db"; - String collectionName = createCollectionName(); - assertThatExceptionOfType(MongoTimeoutException.class) .isThrownBy( () -> { - MongoDatabase db = client.getDatabase(dbName); - db.createCollection(collectionName); + MongoDatabase db = client.getDatabase("test_db"); + db.createCollection(createCollectionName()); }); // Unfortunately not caught by our instrumentation. testing().waitAndAssertTraces(); From c3b848b1dc4faf1d3bc83996b929c573e90c01ed Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Sat, 5 Oct 2024 21:20:39 +0800 Subject: [PATCH 07/13] 1. Remove useless lines of code. 2. Convert long to int using `Math.toIntExam`. Signed-off-by: xiepuhuan --- .../mongo/v3_1/AbstractMongo31ClientTest.java | 9 ++++----- .../instrumentation/mongo/v3_7/MongoClientTest.java | 9 ++++----- .../mongo/v4_0/Mongo4ReactiveClientTest.java | 13 ++++++------- .../instrumentation/mongo/v4_0/MongoClientTest.java | 9 ++++----- .../mongoasync/v3_3/MongoAsyncClientTest.java | 5 ++--- 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java index f608e4e128b5..1e5acea3b86f 100644 --- a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java +++ b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java @@ -47,7 +47,6 @@ void cleanup() { if (client != null) { client.close(); } - client = null; } @Override @@ -89,7 +88,7 @@ protected void createCollectionCallingBuildTwice(String dbName, String collectio @Override protected int getCollection(String dbName, String collectionName) { MongoDatabase db = client.getDatabase(dbName); - return (int) db.getCollection(collectionName).count(); + return Math.toIntExact(db.getCollection(collectionName).count()); } @Override @@ -110,7 +109,7 @@ protected MongoCollection setupInsert(String dbName, String collection @Override protected int insert(MongoCollection collection) { collection.insertOne(new Document("password", "SECRET")); - return (int) collection.count(); + return Math.toIntExact(collection.count()); } @Override @@ -137,7 +136,7 @@ protected int update(MongoCollection collection) { new BsonDocument("password", new BsonString("OLDPW")), new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))); collection.count(); - return (int) result.getModifiedCount(); + return Math.toIntExact(result.getModifiedCount()); } @Override @@ -162,7 +161,7 @@ protected int delete(MongoCollection collection) { DeleteResult result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))); collection.count(); - return (int) result.getDeletedCount(); + return Math.toIntExact(result.getDeletedCount()); } @Override diff --git a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java index 4c7a741bf585..b7be2d206fe8 100644 --- a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java +++ b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java @@ -56,7 +56,6 @@ void setup() { void cleanup() { if (client != null) { client.close(); - client = null; } } @@ -110,7 +109,7 @@ protected void createCollectionCallingBuildTwice(String dbName, String collectio @Override protected int getCollection(String dbName, String collectionName) { MongoDatabase db = client.getDatabase(dbName); - return (int) db.getCollection(collectionName).estimatedDocumentCount(); + return Math.toIntExact(db.getCollection(collectionName).estimatedDocumentCount()); } @Override @@ -131,7 +130,7 @@ protected MongoCollection setupInsert(String dbName, String collection @Override protected int insert(MongoCollection collection) { collection.insertOne(new Document("password", "SECRET")); - return (int) collection.estimatedDocumentCount(); + return Math.toIntExact(collection.estimatedDocumentCount()); } @Override @@ -158,7 +157,7 @@ protected int update(MongoCollection collection) { new BsonDocument("password", new BsonString("OLDPW")), new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))); collection.estimatedDocumentCount(); - return (int) result.getModifiedCount(); + return Math.toIntExact(result.getModifiedCount()); } @Override @@ -183,7 +182,7 @@ protected int delete(MongoCollection collection) { DeleteResult result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))); collection.estimatedDocumentCount(); - return (int) result.getDeletedCount(); + return Math.toIntExact(result.getDeletedCount()); } @Override diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java index 1014580239fb..2c73cbe804f5 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java @@ -54,7 +54,6 @@ void setup() { void cleanup() throws Exception { if (client != null) { client.close(); - client = null; } for (AutoCloseable resource : cleanup) { resource.close(); @@ -182,7 +181,7 @@ public MongoCollection setupUpdate(String dbName, String collectionNam @Override public int update(MongoCollection collection) throws Exception { CompletableFuture result = new CompletableFuture<>(); - CompletableFuture count = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); collection .updateOne( new BsonDocument("password", new BsonString("OLDPW")), @@ -193,9 +192,9 @@ public int update(MongoCollection collection) throws Exception { result.complete(((UpdateResult) updateResult)); collection .estimatedDocumentCount() - .subscribe(toSubscriber(o -> count.complete(((Integer) o)))); + .subscribe(toSubscriber(o -> count.complete(((Long) o)))); })); - return (int) result.get(30, TimeUnit.SECONDS).getModifiedCount(); + return Math.toIntExact(result.get(30, TimeUnit.SECONDS).getModifiedCount()); } @Override @@ -226,7 +225,7 @@ public MongoCollection setupDelete(String dbName, String collectionNam public int delete(MongoCollection collection) throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture result = new CompletableFuture<>(); - CompletableFuture count = new CompletableFuture<>(); + CompletableFuture count = new CompletableFuture<>(); collection .deleteOne(new BsonDocument("password", new BsonString("SECRET"))) .subscribe( @@ -235,9 +234,9 @@ public int delete(MongoCollection collection) result.complete(((DeleteResult) deleteResult)); collection .estimatedDocumentCount() - .subscribe(toSubscriber(o -> count.complete(((Integer) o)))); + .subscribe(toSubscriber(o -> count.complete(((Long) o)))); })); - return (int) result.get(30, TimeUnit.SECONDS).getDeletedCount(); + return Math.toIntExact(result.get(30, TimeUnit.SECONDS).getDeletedCount()); } @Override diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java index 8cce2b0060b6..1a3599615252 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java @@ -44,7 +44,6 @@ void setup() { void cleanup() { if (client != null) { client.close(); - client = null; } } @@ -84,7 +83,7 @@ public void createCollectionCallingBuildTwice(String dbName, String collectionNa @Override public int getCollection(String dbName, String collectionName) { MongoDatabase db = client.getDatabase(dbName); - return (int) db.getCollection(collectionName).estimatedDocumentCount(); + return Math.toIntExact(db.getCollection(collectionName).estimatedDocumentCount()); } @Override @@ -105,7 +104,7 @@ public MongoCollection setupInsert(String dbName, String collectionNam @Override public int insert(MongoCollection collection) { collection.insertOne(new Document("password", "SECRET")); - return (int) collection.estimatedDocumentCount(); + return Math.toIntExact(collection.estimatedDocumentCount()); } @Override @@ -132,7 +131,7 @@ public int update(MongoCollection collection) { new BsonDocument("password", new BsonString("OLDPW")), new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))); collection.estimatedDocumentCount(); - return (int) result.getModifiedCount(); + return Math.toIntExact(result.getModifiedCount()); } @Override @@ -157,7 +156,7 @@ public int delete(MongoCollection collection) { DeleteResult result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))); collection.estimatedDocumentCount(); - return (int) result.getDeletedCount(); + return Math.toIntExact(result.getDeletedCount()); } @Override diff --git a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java index 70e3dbd5fd58..b8cb064356c7 100644 --- a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java +++ b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java @@ -54,7 +54,6 @@ void setup() { void cleanup() { if (client != null) { client.close(); - client = null; } } @@ -167,7 +166,7 @@ public int update(MongoCollection collection) { result.complete(((UpdateResult) res)); collection.count(toCallback(o -> count.complete(((Long) o)))); })); - return (int) result.join().getModifiedCount(); + return Math.toIntExact(result.join().getModifiedCount()); } @Override @@ -204,7 +203,7 @@ public int delete(MongoCollection collection) { result.complete((DeleteResult) res); collection.count(toCallback(value -> count.complete(((Long) value)))); })); - return (int) result.join().getDeletedCount(); + return Math.toIntExact(result.join().getDeletedCount()); } @Override From 533d2f649e902a8bf821a9043268c48de9d348f8 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Tue, 8 Oct 2024 13:06:32 +0800 Subject: [PATCH 08/13] Delete useless dependencies. --- instrumentation/mongo/mongo-3.1/testing/build.gradle.kts | 2 -- instrumentation/mongo/mongo-common/testing/build.gradle.kts | 2 -- 2 files changed, 4 deletions(-) diff --git a/instrumentation/mongo/mongo-3.1/testing/build.gradle.kts b/instrumentation/mongo/mongo-3.1/testing/build.gradle.kts index 458c5f0b8ae8..949d4ed4ef66 100644 --- a/instrumentation/mongo/mongo-3.1/testing/build.gradle.kts +++ b/instrumentation/mongo/mongo-3.1/testing/build.gradle.kts @@ -7,7 +7,5 @@ dependencies { compileOnly("org.mongodb:mongo-java-driver:3.1.0") - implementation("org.apache.groovy:groovy") implementation("io.opentelemetry:opentelemetry-api") - implementation("org.spockframework:spock-core") } diff --git a/instrumentation/mongo/mongo-common/testing/build.gradle.kts b/instrumentation/mongo/mongo-common/testing/build.gradle.kts index 307ad9abc8f4..777c9b3d9d5e 100644 --- a/instrumentation/mongo/mongo-common/testing/build.gradle.kts +++ b/instrumentation/mongo/mongo-common/testing/build.gradle.kts @@ -6,7 +6,5 @@ dependencies { api(project(":testing-common")) api("org.testcontainers:mongodb") - implementation("org.apache.groovy:groovy") implementation("io.opentelemetry:opentelemetry-api") - implementation("org.spockframework:spock-core") } From dda22cbfda564339834cc442cfe40966f4270fda Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Wed, 16 Oct 2024 18:59:36 +0800 Subject: [PATCH 09/13] 1. Use assertThat instead of waitAndAssertTraces 2. Close resources using AutoCleanupExtension 3. Reconstruct the mongoSpan method --- .../mongo/v3_1/AbstractMongo31ClientTest.java | 3 +- .../mongo/v3_7/MongoClientTest.java | 3 +- .../mongo/v4_0/Mongo4ReactiveClientTest.java | 16 +- .../mongo/v4_0/MongoClientTest.java | 8 +- .../testing/AbstractMongoClientTest.java | 390 +++++++----------- 5 files changed, 154 insertions(+), 266 deletions(-) diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java index 1e5acea3b86f..1f05832a3226 100644 --- a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java +++ b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.mongo.v3_1; import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import com.mongodb.MongoClient; @@ -219,6 +220,6 @@ void testClientFailure() { db.createCollection(createCollectionName()); }); // Unfortunately not caught by our instrumentation. - testing().waitAndAssertTraces(); + assertThat(testing().spans().size()).isEqualTo(0); } } diff --git a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java index b7be2d206fe8..998cc2089eb0 100644 --- a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java +++ b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java @@ -8,6 +8,7 @@ import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.mongodb.MongoClientSettings; @@ -240,6 +241,6 @@ void testClientFailure() { }) .isInstanceOf(MongoTimeoutException.class); // Unfortunately not caught by our instrumentation. - testing().waitAndAssertTraces(); + assertThat(testing().spans().size()).isEqualTo(0); } } diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java index 2c73cbe804f5..f5c25f70d223 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java @@ -16,10 +16,9 @@ import com.mongodb.reactivestreams.client.MongoCollection; import com.mongodb.reactivestreams.client.MongoDatabase; import io.opentelemetry.instrumentation.mongo.testing.AbstractMongoClientTest; +import io.opentelemetry.instrumentation.testing.internal.AutoCleanupExtension; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; @@ -41,9 +40,9 @@ class Mongo4ReactiveClientTest extends AbstractMongoClientTest cleanup = new ArrayList<>(); + private MongoClient client; @BeforeAll void setup() { @@ -51,13 +50,10 @@ void setup() { } @AfterAll - void cleanup() throws Exception { + void cleanup() { if (client != null) { client.close(); } - for (AutoCloseable resource : cleanup) { - resource.close(); - } } @Override @@ -82,7 +78,7 @@ public void createCollection(String dbName, String collectionName) { public void createCollectionNoDescription(String dbName, String collectionName) throws InterruptedException { MongoClient tmpClient = MongoClients.create("mongodb://" + host + ":" + port); - cleanup.add(tmpClient); + cleanup.deferCleanup(tmpClient); MongoDatabase db = tmpClient.getDatabase(dbName); CountDownLatch latch = new CountDownLatch(1); db.createCollection(collectionName).subscribe(toSubscriber(o -> latch.countDown())); @@ -103,7 +99,7 @@ public void createCollectionCallingBuildTwice(String dbName, String collectionNa builder -> builder.hosts(singletonList(new ServerAddress(host, port)))); settings.build(); MongoClient tmpClient = MongoClients.create(settings.build()); - cleanup.add(tmpClient); + cleanup.deferCleanup(tmpClient); MongoDatabase db = tmpClient.getDatabase(dbName); CountDownLatch latch = new CountDownLatch(1); db.createCollection(collectionName).subscribe(toSubscriber(o -> latch.countDown())); diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java index 1a3599615252..665df13340b3 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java @@ -71,12 +71,12 @@ public void createCollectionWithAlreadyBuiltClientOptions(String dbName, String @Override public void createCollectionCallingBuildTwice(String dbName, String collectionName) { - MongoClientSettings settings = + MongoClientSettings.Builder settings = MongoClientSettings.builder() .applyToClusterSettings( - builder -> builder.hosts(singletonList(new ServerAddress(host, port)))) - .build(); - MongoDatabase db = MongoClients.create(settings).getDatabase(dbName); + builder -> builder.hosts(singletonList(new ServerAddress(host, port)))); + settings.build(); + MongoDatabase db = MongoClients.create(settings.build()).getDatabase(dbName); db.createCollection(collectionName); } diff --git a/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java index 6f58164f7b92..516c167f6256 100644 --- a/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java +++ b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java @@ -8,6 +8,7 @@ import static io.opentelemetry.api.trace.SpanKind.CLIENT; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; +import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatNoException; @@ -21,16 +22,13 @@ import io.opentelemetry.semconv.ServerAttributes; import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; import java.net.Socket; -import java.util.Objects; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; -import org.assertj.core.api.Condition; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; -import org.junit.platform.commons.util.StringUtils; import org.slf4j.LoggerFactory; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; @@ -119,7 +117,7 @@ void testPortOpen() { @Test @DisplayName("test create collection") - void testCreateCollection() throws InterruptedException { + void testCreateCollection() { String dbName = "test_db"; String collectionName = createCollectionName(); @@ -137,25 +135,17 @@ void testCreateCollection() throws InterruptedException { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, - "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}") - || Objects.equals( - str, - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\"}") - || Objects.equals( - str, - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") - || Objects.equals( - str, - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + asList( + "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\"}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); } @Test @@ -179,25 +169,17 @@ void testCreateCollectionNoDescription() throws InterruptedException { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, - "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}") - || Objects.equals( - str, - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\"}") - || Objects.equals( - str, - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") - || Objects.equals( - str, - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + asList( + "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\"}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); } @Test @@ -222,25 +204,17 @@ void testCreateCollectionCallingBuildTwice() throws InterruptedException { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, - "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}") - || Objects.equals( - str, - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\"}") - || Objects.equals( - str, - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") - || Objects.equals( - str, - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + asList( + "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\"}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); } @Test @@ -265,29 +239,18 @@ void testGetCollection() throws Exception { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, "{\"count\":\"" + collectionName + "\",\"query\":{}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\"}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + asList( + "{\"count\":\"" + collectionName + "\",\"query\":{}}", + "{\"count\":\"" + collectionName + "\",\"query\":{},\"$db\":\"?\"}", + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}", + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"count\":\"" + + collectionName + + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); } @Test @@ -314,22 +277,16 @@ void testInsert() throws Exception { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, - "{\"insert\":\"" - + collectionName - + "\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}") - || Objects.equals( - str, - "{\"insert\":\"" - + collectionName - + "\",\"ordered\":\"?\",\"$db\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}") - || Objects.equals( - str, - "{\"insert\":\"" - + collectionName - + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")), + asList( + "{\"insert\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}", + "{\"insert\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}", + "{\"insert\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")), span -> mongoSpan( trace, @@ -338,29 +295,18 @@ void testInsert() throws Exception { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, "{\"count\":\"" + collectionName + "\",\"query\":{}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\"}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + asList( + "{\"count\":\"" + collectionName + "\",\"query\":{}}", + "{\"count\":\"" + collectionName + "\",\"query\":{},\"$db\":\"?\"}", + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}", + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"count\":\"" + + collectionName + + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); } @Test @@ -387,22 +333,16 @@ void testUpdate() throws Exception { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, - "{\"update\":\"" - + collectionName - + "\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}") - || Objects.equals( - str, - "{\"update\":\"" - + collectionName - + "\",\"ordered\":\"?\",\"$db\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}") - || Objects.equals( - str, - "{\"update\":\"" - + collectionName - + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}")), + asList( + "{\"update\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}", + "{\"update\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}", + "{\"update\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}")), span -> mongoSpan( trace, @@ -411,29 +351,18 @@ void testUpdate() throws Exception { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, "{\"count\":\"" + collectionName + "\",\"query\":{}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\"}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + asList( + "{\"count\":\"" + collectionName + "\",\"query\":{}}", + "{\"count\":\"" + collectionName + "\",\"query\":{},\"$db\":\"?\"}", + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}", + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"count\":\"" + + collectionName + + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); } @Test @@ -460,22 +389,16 @@ void testDelete() throws Exception { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, - "{\"delete\":\"" - + collectionName - + "\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}") - || Objects.equals( - str, - "{\"delete\":\"" - + collectionName - + "\",\"ordered\":\"?\",\"$db\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}") - || Objects.equals( - str, - "{\"delete\":\"" - + collectionName - + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")), + asList( + "{\"delete\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}", + "{\"delete\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}", + "{\"delete\":\"" + + collectionName + + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")), span -> mongoSpan( trace, @@ -484,29 +407,18 @@ void testDelete() throws Exception { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, "{\"count\":\"" + collectionName + "\",\"query\":{}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\"}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") - || Objects.equals( - str, - "{\"count\":\"" - + collectionName - + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + asList( + "{\"count\":\"" + collectionName + "\",\"query\":{}}", + "{\"count\":\"" + collectionName + "\",\"query\":{},\"$db\":\"?\"}", + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}", + "{\"count\":\"" + + collectionName + + "\",\"query\":{},\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"count\":\"" + + collectionName + + "\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); } @Test @@ -531,27 +443,19 @@ void testCollectionNameForGetMoreCommand() { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, - "{\"find\":\"" - + collectionName - + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\"}") - || Objects.equals( - str, - "{\"find\":\"" - + collectionName - + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\"}") - || Objects.equals( - str, - "{\"find\":\"" - + collectionName - + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") - || Objects.equals( - str, - "{\"find\":\"" - + collectionName - + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")), + asList( + "{\"find\":\"" + + collectionName + + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\"}", + "{\"find\":\"" + + collectionName + + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\"}", + "{\"find\":\"" + + collectionName + + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"find\":\"" + + collectionName + + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")), span -> mongoSpan( trace, @@ -560,19 +464,11 @@ void testCollectionNameForGetMoreCommand() { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, - "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\"}") - || Objects.equals( - str, - "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\",\"$db\":\"?\"}") - || Objects.equals( - str, - "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}") - || Objects.equals( - str, - "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); + asList( + "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\"}", + "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\",\"$db\":\"?\"}", + "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"getMore\":\"?\",\"collection\":\"?\",\"batchSize\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); } @Test @@ -580,7 +476,7 @@ void testCollectionNameForGetMoreCommand() { void testError() { assertThatIllegalArgumentException().isThrownBy(() -> error("test_db", createCollectionName())); // Unfortunately not caught by our instrumentation. - testing().waitAndAssertTraces(); + assertThat(testing().spans().size()).isEqualTo(0); } @Test @@ -606,14 +502,11 @@ void testCreateCollectionWithAlreadyBuiltClientOptions() { collectionName, dbName, trace.getSpan(0), - str -> - Objects.equals( - str, - "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}") - || StringUtils.isNotBlank( - "{\"create\":\"" - + collectionName - + "\",\"capped\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}")))); + asList( + "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}")))); } protected String createCollectionName() { @@ -629,7 +522,7 @@ void mongoSpan( String collection, String dbName, Object parentSpan, - Function statementEval) { + List statements) { SpanDataAssert span = trace.element(index).hasName(operation + " " + dbName + "." + collection).hasKind(CLIENT); if (parentSpan == null) { @@ -643,10 +536,7 @@ void mongoSpan( equalTo(ServerAttributes.SERVER_PORT, port), satisfies( DbIncubatingAttributes.DB_STATEMENT, - val -> - val.is( - new Condition<>( - statement -> statementEval.apply(statement.replaceAll(" ", "")), ""))), + val -> val.matches(statement -> statements.contains(statement.replaceAll(" ", "")))), equalTo(DbIncubatingAttributes.DB_SYSTEM, "mongodb"), equalTo(DbIncubatingAttributes.DB_CONNECTION_STRING, "mongodb://localhost:" + port), equalTo(DbIncubatingAttributes.DB_NAME, dbName), From 3beaf3873f60501fc0a7fef86fcc5293820eb438 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Thu, 17 Oct 2024 00:13:34 +0800 Subject: [PATCH 10/13] 1. Removing Annotations for Simple Names @DisplayName. 2. Change the return type of the involved method from int to long. 3. Using isIn instead of containsAnyOf for correct assertions. 4. Directly throw InterruptedException without capturing it. 5. Latch calls await method with timeout. 6. Merge comment lines. 7. Use the get method to wait for the future to complete, just like the original Groovy code. 8. In the mongoSpan method parameters, use SpanDataAsset instead of trace and index. 9. In the mongoSpan method, optimizing assertion error prompts. Signed-off-by: xiepuhuan --- .../v3_1/MongoDbAttributesGetterTest.java | 4 +- .../mongo/v3_1/AbstractMongo31ClientTest.java | 20 +++-- .../mongo/v3_7/MongoClientTest.java | 20 +++-- .../mongo/v4_0/Mongo4ReactiveClientTest.java | 25 +++---- .../mongo/v4_0/MongoClientTest.java | 16 ++-- .../mongoasync/v3_3/MongoAsyncClientTest.java | 33 ++++---- .../testing/AbstractMongoClientTest.java | 75 ++++++++----------- 7 files changed, 88 insertions(+), 105 deletions(-) diff --git a/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java index b9f08adc0ab3..fd3ecd71819d 100644 --- a/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java +++ b/instrumentation/mongo/mongo-3.1/library/src/test/java/io/opentelemetry/instrumentation/mongo/v3_1/MongoDbAttributesGetterTest.java @@ -72,7 +72,7 @@ void shouldTruncateSimpleCommand() { .append("f2", new BsonString("c2"))); // This can vary because of different whitespace for different MongoDB versions - assertThat(normalized).containsAnyOf("{\"cmd\": \"c\", \"f1\": \"", "{\"cmd\": \"c\", \"f1\" "); + assertThat(normalized).isIn("{\"cmd\": \"c\", \"f1\": \"", "{\"cmd\": \"c\", \"f1\" "); } @Test @@ -89,7 +89,7 @@ void shouldTruncateArray() { // This can vary because of different whitespace for different MongoDB versions assertThat(normalized) - .containsAnyOf("{\"cmd\": \"c\", \"f1\": [\"?\", \"?", "{\"cmd\": \"c\", \"f1\": [\"?\","); + .isIn("{\"cmd\": \"c\", \"f1\": [\"?\", \"?", "{\"cmd\": \"c\", \"f1\": [\"?\","); } static String sanitizeStatementAcrossVersions( diff --git a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java index 1f05832a3226..21944f73425b 100644 --- a/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java +++ b/instrumentation/mongo/mongo-3.1/testing/src/main/java/io/opentelemetry/instrumentation/mongo/v3_1/AbstractMongo31ClientTest.java @@ -25,7 +25,6 @@ import org.bson.Document; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public abstract class AbstractMongo31ClientTest @@ -87,9 +86,9 @@ protected void createCollectionCallingBuildTwice(String dbName, String collectio } @Override - protected int getCollection(String dbName, String collectionName) { + protected long getCollection(String dbName, String collectionName) { MongoDatabase db = client.getDatabase(dbName); - return Math.toIntExact(db.getCollection(collectionName).count()); + return db.getCollection(collectionName).count(); } @Override @@ -108,9 +107,9 @@ protected MongoCollection setupInsert(String dbName, String collection } @Override - protected int insert(MongoCollection collection) { + protected long insert(MongoCollection collection) { collection.insertOne(new Document("password", "SECRET")); - return Math.toIntExact(collection.count()); + return collection.count(); } @Override @@ -131,13 +130,13 @@ protected MongoCollection setupUpdate(String dbName, String collection } @Override - protected int update(MongoCollection collection) { + protected long update(MongoCollection collection) { UpdateResult result = collection.updateOne( new BsonDocument("password", new BsonString("OLDPW")), new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))); collection.count(); - return Math.toIntExact(result.getModifiedCount()); + return result.getModifiedCount(); } @Override @@ -158,11 +157,11 @@ protected MongoCollection setupDelete(String dbName, String collection } @Override - protected int delete(MongoCollection collection) { + protected long delete(MongoCollection collection) { DeleteResult result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))); collection.count(); - return Math.toIntExact(result.getDeletedCount()); + return result.getDeletedCount(); } @Override @@ -208,7 +207,6 @@ protected void error(String dbName, String collectionName) { } @Test - @DisplayName("test client failure") void testClientFailure() { MongoClientOptions options = MongoClientOptions.builder().serverSelectionTimeout(10).build(); MongoClient client = new MongoClient(new ServerAddress(host, PortUtils.UNUSABLE_PORT), options); @@ -220,6 +218,6 @@ void testClientFailure() { db.createCollection(createCollectionName()); }); // Unfortunately not caught by our instrumentation. - assertThat(testing().spans().size()).isEqualTo(0); + assertThat(testing().spans()).isEmpty(); } } diff --git a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java index 998cc2089eb0..a8614bce27ef 100644 --- a/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java +++ b/instrumentation/mongo/mongo-3.7/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v3_7/MongoClientTest.java @@ -29,7 +29,6 @@ import org.bson.Document; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -108,9 +107,9 @@ protected void createCollectionCallingBuildTwice(String dbName, String collectio } @Override - protected int getCollection(String dbName, String collectionName) { + protected long getCollection(String dbName, String collectionName) { MongoDatabase db = client.getDatabase(dbName); - return Math.toIntExact(db.getCollection(collectionName).estimatedDocumentCount()); + return db.getCollection(collectionName).estimatedDocumentCount(); } @Override @@ -129,9 +128,9 @@ protected MongoCollection setupInsert(String dbName, String collection } @Override - protected int insert(MongoCollection collection) { + protected long insert(MongoCollection collection) { collection.insertOne(new Document("password", "SECRET")); - return Math.toIntExact(collection.estimatedDocumentCount()); + return collection.estimatedDocumentCount(); } @Override @@ -152,13 +151,13 @@ protected MongoCollection setupUpdate(String dbName, String collection } @Override - protected int update(MongoCollection collection) { + protected long update(MongoCollection collection) { UpdateResult result = collection.updateOne( new BsonDocument("password", new BsonString("OLDPW")), new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))); collection.estimatedDocumentCount(); - return Math.toIntExact(result.getModifiedCount()); + return result.getModifiedCount(); } @Override @@ -179,11 +178,11 @@ protected MongoCollection setupDelete(String dbName, String collection } @Override - protected int delete(MongoCollection collection) { + protected long delete(MongoCollection collection) { DeleteResult result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))); collection.estimatedDocumentCount(); - return Math.toIntExact(result.getDeletedCount()); + return result.getDeletedCount(); } @Override @@ -229,7 +228,6 @@ protected void error(String dbName, String collectionName) { } @Test - @DisplayName("test client failure") void testClientFailure() { MongoClient client = MongoClients.create("mongodb://" + host + ":" + UNUSABLE_PORT + "/?connectTimeoutMS=10"); @@ -241,6 +239,6 @@ void testClientFailure() { }) .isInstanceOf(MongoTimeoutException.class); // Unfortunately not caught by our instrumentation. - assertThat(testing().spans().size()).isEqualTo(0); + assertThat(testing().spans()).isEmpty(); } } diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java index f5c25f70d223..f5fb03e54294 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/Mongo4ReactiveClientTest.java @@ -62,16 +62,11 @@ protected InstrumentationExtension testing() { } @Override - public void createCollection(String dbName, String collectionName) { + public void createCollection(String dbName, String collectionName) throws InterruptedException { MongoDatabase db = client.getDatabase(dbName); CountDownLatch latch = new CountDownLatch(1); db.createCollection(collectionName).subscribe(toSubscriber(o -> latch.countDown())); - - try { - latch.await(30, TimeUnit.SECONDS); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + latch.await(30, TimeUnit.SECONDS); } @Override @@ -107,14 +102,14 @@ public void createCollectionCallingBuildTwice(String dbName, String collectionNa } @Override - public int getCollection(String dbName, String collectionName) + public long getCollection(String dbName, String collectionName) throws ExecutionException, InterruptedException, TimeoutException { MongoDatabase db = client.getDatabase(dbName); CompletableFuture count = new CompletableFuture<>(); db.getCollection(collectionName) .estimatedDocumentCount() .subscribe(toSubscriber(o -> count.complete(((Long) o)))); - return Math.toIntExact(count.get(30, TimeUnit.SECONDS)); + return count.get(30, TimeUnit.SECONDS); } @Override @@ -137,7 +132,7 @@ public MongoCollection setupInsert(String dbName, String collectionNam } @Override - public int insert(MongoCollection collection) throws Exception { + public long insert(MongoCollection collection) throws Exception { CompletableFuture count = new CompletableFuture<>(); collection .insertOne(new Document("password", "SECRET")) @@ -147,7 +142,7 @@ public int insert(MongoCollection collection) throws Exception { collection .estimatedDocumentCount() .subscribe(toSubscriber(c -> count.complete(((Long) c)))))); - return Math.toIntExact(count.get(30, TimeUnit.SECONDS)); + return count.get(30, TimeUnit.SECONDS); } @Override @@ -175,7 +170,7 @@ public MongoCollection setupUpdate(String dbName, String collectionNam } @Override - public int update(MongoCollection collection) throws Exception { + public long update(MongoCollection collection) throws Exception { CompletableFuture result = new CompletableFuture<>(); CompletableFuture count = new CompletableFuture<>(); collection @@ -190,7 +185,7 @@ public int update(MongoCollection collection) throws Exception { .estimatedDocumentCount() .subscribe(toSubscriber(o -> count.complete(((Long) o)))); })); - return Math.toIntExact(result.get(30, TimeUnit.SECONDS).getModifiedCount()); + return result.get(30, TimeUnit.SECONDS).getModifiedCount(); } @Override @@ -218,7 +213,7 @@ public MongoCollection setupDelete(String dbName, String collectionNam } @Override - public int delete(MongoCollection collection) + public long delete(MongoCollection collection) throws ExecutionException, InterruptedException, TimeoutException { CompletableFuture result = new CompletableFuture<>(); CompletableFuture count = new CompletableFuture<>(); @@ -232,7 +227,7 @@ public int delete(MongoCollection collection) .estimatedDocumentCount() .subscribe(toSubscriber(o -> count.complete(((Long) o)))); })); - return Math.toIntExact(result.get(30, TimeUnit.SECONDS).getDeletedCount()); + return result.get(30, TimeUnit.SECONDS).getDeletedCount(); } @Override diff --git a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java index 665df13340b3..864288e9ec6b 100644 --- a/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java +++ b/instrumentation/mongo/mongo-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongo/v4_0/MongoClientTest.java @@ -81,9 +81,9 @@ public void createCollectionCallingBuildTwice(String dbName, String collectionNa } @Override - public int getCollection(String dbName, String collectionName) { + public long getCollection(String dbName, String collectionName) { MongoDatabase db = client.getDatabase(dbName); - return Math.toIntExact(db.getCollection(collectionName).estimatedDocumentCount()); + return db.getCollection(collectionName).estimatedDocumentCount(); } @Override @@ -102,9 +102,9 @@ public MongoCollection setupInsert(String dbName, String collectionNam } @Override - public int insert(MongoCollection collection) { + public long insert(MongoCollection collection) { collection.insertOne(new Document("password", "SECRET")); - return Math.toIntExact(collection.estimatedDocumentCount()); + return collection.estimatedDocumentCount(); } @Override @@ -125,13 +125,13 @@ public MongoCollection setupUpdate(String dbName, String collectionNam } @Override - public int update(MongoCollection collection) { + public long update(MongoCollection collection) { UpdateResult result = collection.updateOne( new BsonDocument("password", new BsonString("OLDPW")), new BsonDocument("$set", new BsonDocument("password", new BsonString("NEWPW")))); collection.estimatedDocumentCount(); - return Math.toIntExact(result.getModifiedCount()); + return result.getModifiedCount(); } @Override @@ -152,11 +152,11 @@ public MongoCollection setupDelete(String dbName, String collectionNam } @Override - public int delete(MongoCollection collection) { + public long delete(MongoCollection collection) { DeleteResult result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))); collection.estimatedDocumentCount(); - return Math.toIntExact(result.getDeletedCount()); + return result.getDeletedCount(); } @Override diff --git a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java index b8cb064356c7..171c660e980f 100644 --- a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java +++ b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java @@ -20,6 +20,8 @@ import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import org.bson.BsonDocument; import org.bson.BsonString; @@ -97,11 +99,11 @@ public void createCollectionCallingBuildTwice(String dbName, String collectionNa } @Override - public int getCollection(String dbName, String collectionName) { + public long getCollection(String dbName, String collectionName) { MongoDatabase db = client.getDatabase(dbName); CompletableFuture count = new CompletableFuture<>(); db.getCollection(collectionName).count(toCallback(o -> count.complete(((Long) o)))); - return count.join().intValue(); + return count.join(); } @Override @@ -115,7 +117,7 @@ public MongoCollection setupInsert(String dbName, String collectionNam MongoDatabase db = client.getDatabase(dbName); CountDownLatch latch = new CountDownLatch(1); db.createCollection(collectionName, toCallback(result -> latch.countDown())); - latch.await(); + latch.await(30, TimeUnit.SECONDS); return db.getCollection(collectionName); }); ignoreTracesAndClear(1); @@ -123,12 +125,13 @@ public MongoCollection setupInsert(String dbName, String collectionNam } @Override - public int insert(MongoCollection collection) { + public long insert(MongoCollection collection) + throws ExecutionException, InterruptedException { CompletableFuture count = new CompletableFuture<>(); collection.insertOne( new Document("password", "SECRET"), toCallback(result -> collection.count(toCallback(o -> count.complete(((Long) o)))))); - return count.join().intValue(); + return count.get(); } @Override @@ -142,12 +145,12 @@ public MongoCollection setupUpdate(String dbName, String collectionNam MongoDatabase db = client.getDatabase(dbName); CountDownLatch latch1 = new CountDownLatch(1); db.createCollection(collectionName, toCallback(result -> latch1.countDown())); - latch1.await(); + latch1.await(30, TimeUnit.SECONDS); MongoCollection coll = db.getCollection(collectionName); CountDownLatch latch2 = new CountDownLatch(1); coll.insertOne( new Document("password", "OLDPW"), toCallback(result -> latch2.countDown())); - latch2.await(); + latch2.await(30, TimeUnit.SECONDS); return coll; }); ignoreTracesAndClear(1); @@ -155,7 +158,8 @@ public MongoCollection setupUpdate(String dbName, String collectionNam } @Override - public int update(MongoCollection collection) { + public long update(MongoCollection collection) + throws ExecutionException, InterruptedException { CompletableFuture result = new CompletableFuture<>(); CompletableFuture count = new CompletableFuture<>(); collection.updateOne( @@ -166,7 +170,7 @@ public int update(MongoCollection collection) { result.complete(((UpdateResult) res)); collection.count(toCallback(o -> count.complete(((Long) o)))); })); - return Math.toIntExact(result.join().getModifiedCount()); + return result.get().getModifiedCount(); } @Override @@ -180,12 +184,12 @@ public MongoCollection setupDelete(String dbName, String collectionNam MongoDatabase db = client.getDatabase(dbName); CountDownLatch latch1 = new CountDownLatch(1); db.createCollection(collectionName, toCallback(result -> latch1.countDown())); - latch1.await(); + latch1.await(30, TimeUnit.SECONDS); MongoCollection coll = db.getCollection(collectionName); CountDownLatch latch2 = new CountDownLatch(1); coll.insertOne( new Document("password", "SECRET"), toCallback(result -> latch2.countDown())); - latch2.await(); + latch2.await(30, TimeUnit.SECONDS); return coll; }); ignoreTracesAndClear(1); @@ -193,7 +197,8 @@ public MongoCollection setupDelete(String dbName, String collectionNam } @Override - public int delete(MongoCollection collection) { + public long delete(MongoCollection collection) + throws ExecutionException, InterruptedException { CompletableFuture result = new CompletableFuture<>(); CompletableFuture count = new CompletableFuture<>(); collection.deleteOne( @@ -203,7 +208,7 @@ public int delete(MongoCollection collection) { result.complete((DeleteResult) res); collection.count(toCallback(value -> count.complete(((Long) value)))); })); - return Math.toIntExact(result.join().getDeletedCount()); + return result.get().getDeletedCount(); } @Override @@ -226,7 +231,7 @@ public void error(String dbName, String collectionName) throws Throwable { MongoDatabase db = client.getDatabase(dbName); CountDownLatch latch = new CountDownLatch(1); db.createCollection(collectionName, toCallback(result -> latch.countDown())); - latch.await(); + latch.await(30, TimeUnit.SECONDS); return db.getCollection(collectionName); }); ignoreTracesAndClear(1); diff --git a/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java index 516c167f6256..50c85e199456 100644 --- a/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java +++ b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java @@ -17,7 +17,6 @@ import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; -import io.opentelemetry.sdk.testing.assertj.TraceAssert; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.semconv.ServerAttributes; import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; @@ -63,9 +62,9 @@ void cleanup() { protected abstract InstrumentationExtension testing(); // Different client versions have different APIs to do these operations. If adding a test for a - // new - // version, refer to existing ones on how to implement these operations. - protected abstract void createCollection(String dbName, String collectionName); + // new version, refer to existing ones on how to implement these operations. + protected abstract void createCollection(String dbName, String collectionName) + throws InterruptedException; protected abstract void createCollectionNoDescription(String dbName, String collectionName) throws InterruptedException; @@ -81,22 +80,22 @@ protected abstract void createCollectionWithAlreadyBuiltClientOptions( protected abstract void createCollectionCallingBuildTwice(String dbName, String collectionName) throws InterruptedException; - protected abstract int getCollection(String dbName, String collectionName) throws Exception; + protected abstract long getCollection(String dbName, String collectionName) throws Exception; protected abstract T setupInsert(String dbName, String collectionName) throws InterruptedException; - protected abstract int insert(T collection) throws Exception; + protected abstract long insert(T collection) throws Exception; protected abstract T setupUpdate(String dbName, String collectionName) throws InterruptedException; - protected abstract int update(T collection) throws Exception; + protected abstract long update(T collection) throws Exception; protected abstract T setupDelete(String dbName, String collectionName) throws InterruptedException; - protected abstract int delete(T collection) throws Exception; + protected abstract long delete(T collection) throws Exception; protected abstract T setupGetMore(String dbName, String collectionName); @@ -117,7 +116,7 @@ void testPortOpen() { @Test @DisplayName("test create collection") - void testCreateCollection() { + void testCreateCollection() throws InterruptedException { String dbName = "test_db"; String collectionName = createCollectionName(); @@ -129,8 +128,7 @@ void testCreateCollection() { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace, - 1, + trace.element(1), "create", collectionName, dbName, @@ -163,8 +161,7 @@ void testCreateCollectionNoDescription() throws InterruptedException { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace, - 1, + trace.element(1), "create", collectionName, dbName, @@ -198,8 +195,7 @@ void testCreateCollectionCallingBuildTwice() throws InterruptedException { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace, - 1, + trace.element(1), "create", collectionName, dbName, @@ -223,7 +219,7 @@ void testGetCollection() throws Exception { String dbName = "test_db"; String collectionName = createCollectionName(); - int count = testing().runWithSpan("parent", () -> getCollection(dbName, collectionName)); + long count = testing().runWithSpan("parent", () -> getCollection(dbName, collectionName)); assertThat(count).isEqualTo(0); testing() @@ -233,8 +229,7 @@ void testGetCollection() throws Exception { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace, - 1, + trace.element(1), "count", collectionName, dbName, @@ -260,7 +255,7 @@ void testInsert() throws Exception { String collectionName = createCollectionName(); T collection = setupInsert(dbName, collectionName); - int count = testing().runWithSpan("parent", () -> insert(collection)); + long count = testing().runWithSpan("parent", () -> insert(collection)); assertThat(count).isEqualTo(1); @@ -271,8 +266,7 @@ void testInsert() throws Exception { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace, - 1, + trace.element(1), "insert", collectionName, dbName, @@ -289,8 +283,7 @@ void testInsert() throws Exception { + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")), span -> mongoSpan( - trace, - 2, + trace.element(2), "count", collectionName, dbName, @@ -316,7 +309,7 @@ void testUpdate() throws Exception { String collectionName = createCollectionName(); T collection = setupUpdate(dbName, collectionName); - int modifiedCount = testing().runWithSpan("parent", () -> update(collection)); + long modifiedCount = testing().runWithSpan("parent", () -> update(collection)); assertThat(modifiedCount).isEqualTo(1); @@ -327,8 +320,7 @@ void testUpdate() throws Exception { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace, - 1, + trace.element(1), "update", collectionName, dbName, @@ -345,8 +337,7 @@ void testUpdate() throws Exception { + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}")), span -> mongoSpan( - trace, - 2, + trace.element(2), "count", collectionName, dbName, @@ -372,7 +363,7 @@ void testDelete() throws Exception { String collectionName = createCollectionName(); T collection = setupDelete(dbName, collectionName); - int deletedCount = testing().runWithSpan("parent", () -> delete(collection)); + long deletedCount = testing().runWithSpan("parent", () -> delete(collection)); assertThat(deletedCount).isEqualTo(1); @@ -383,8 +374,7 @@ void testDelete() throws Exception { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace, - 1, + trace.element(1), "delete", collectionName, dbName, @@ -401,8 +391,7 @@ void testDelete() throws Exception { + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")), span -> mongoSpan( - trace, - 2, + trace.element(2), "count", collectionName, dbName, @@ -437,8 +426,7 @@ void testCollectionNameForGetMoreCommand() { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace, - 1, + trace.element(1), "find", collectionName, dbName, @@ -458,8 +446,7 @@ void testCollectionNameForGetMoreCommand() { + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")), span -> mongoSpan( - trace, - 2, + trace.element(2), "getMore", collectionName, dbName, @@ -476,7 +463,7 @@ void testCollectionNameForGetMoreCommand() { void testError() { assertThatIllegalArgumentException().isThrownBy(() -> error("test_db", createCollectionName())); // Unfortunately not caught by our instrumentation. - assertThat(testing().spans().size()).isEqualTo(0); + assertThat(testing().spans()).isEmpty(); } @Test @@ -496,8 +483,7 @@ void testCreateCollectionWithAlreadyBuiltClientOptions() { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace, - 1, + trace.element(1), "create", collectionName, dbName, @@ -516,15 +502,14 @@ protected String createCollectionName() { @SuppressWarnings("deprecation") // TODO DbIncubatingAttributes.DB_CONNECTION_STRING deprecation void mongoSpan( - TraceAssert trace, - int index, + SpanDataAssert spanData, String operation, String collection, String dbName, Object parentSpan, List statements) { SpanDataAssert span = - trace.element(index).hasName(operation + " " + dbName + "." + collection).hasKind(CLIENT); + spanData.hasName(operation + " " + dbName + "." + collection).hasKind(CLIENT); if (parentSpan == null) { span.hasNoParent(); } else { @@ -536,7 +521,9 @@ void mongoSpan( equalTo(ServerAttributes.SERVER_PORT, port), satisfies( DbIncubatingAttributes.DB_STATEMENT, - val -> val.matches(statement -> statements.contains(statement.replaceAll(" ", "")))), + val -> + val.satisfies( + statement -> assertThat(statements).contains(statement.replaceAll(" ", "")))), equalTo(DbIncubatingAttributes.DB_SYSTEM, "mongodb"), equalTo(DbIncubatingAttributes.DB_CONNECTION_STRING, "mongodb://localhost:" + port), equalTo(DbIncubatingAttributes.DB_NAME, dbName), From 66f55ce6082df6525a2309cb71f022578057f5b1 Mon Sep 17 00:00:00 2001 From: xiepuhuan Date: Thu, 17 Oct 2024 01:21:05 +0800 Subject: [PATCH 11/13] Fix testLatestDeps --- .../mongo/testing/AbstractMongoClientTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java index 50c85e199456..66e46dbca62f 100644 --- a/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java +++ b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java @@ -492,7 +492,10 @@ void testCreateCollectionWithAlreadyBuiltClientOptions() { "{\"create\":\"" + collectionName + "\",\"capped\":\"?\"}", "{\"create\":\"" + collectionName - + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}")))); + + "\",\"capped\":\"?\",\"$db\":\"?\",\"$readPreference\":{\"mode\":\"?\"}}", + "{\"create\":\"" + + collectionName + + "\",\"capped\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")))); } protected String createCollectionName() { From a3be8d9d3498733ac96c0122bb7eb470071daead Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 17 Oct 2024 10:12:54 +0300 Subject: [PATCH 12/13] change get back to join --- .../mongoasync/v3_3/MongoAsyncClientTest.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java index 171c660e980f..80b0807f9402 100644 --- a/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java +++ b/instrumentation/mongo/mongo-async-3.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mongoasync/v3_3/MongoAsyncClientTest.java @@ -20,7 +20,6 @@ import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import org.bson.BsonDocument; @@ -125,13 +124,12 @@ public MongoCollection setupInsert(String dbName, String collectionNam } @Override - public long insert(MongoCollection collection) - throws ExecutionException, InterruptedException { + public long insert(MongoCollection collection) { CompletableFuture count = new CompletableFuture<>(); collection.insertOne( new Document("password", "SECRET"), toCallback(result -> collection.count(toCallback(o -> count.complete(((Long) o)))))); - return count.get(); + return count.join(); } @Override @@ -158,8 +156,7 @@ public MongoCollection setupUpdate(String dbName, String collectionNam } @Override - public long update(MongoCollection collection) - throws ExecutionException, InterruptedException { + public long update(MongoCollection collection) { CompletableFuture result = new CompletableFuture<>(); CompletableFuture count = new CompletableFuture<>(); collection.updateOne( @@ -170,7 +167,7 @@ public long update(MongoCollection collection) result.complete(((UpdateResult) res)); collection.count(toCallback(o -> count.complete(((Long) o)))); })); - return result.get().getModifiedCount(); + return result.join().getModifiedCount(); } @Override @@ -197,8 +194,7 @@ public MongoCollection setupDelete(String dbName, String collectionNam } @Override - public long delete(MongoCollection collection) - throws ExecutionException, InterruptedException { + public long delete(MongoCollection collection) { CompletableFuture result = new CompletableFuture<>(); CompletableFuture count = new CompletableFuture<>(); collection.deleteOne( @@ -208,7 +204,7 @@ public long delete(MongoCollection collection) result.complete((DeleteResult) res); collection.count(toCallback(value -> count.complete(((Long) value)))); })); - return result.get().getDeletedCount(); + return result.join().getDeletedCount(); } @Override From f9f8003aad1b25e47843c52d477d36be61bb0617 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 17 Oct 2024 10:13:12 +0300 Subject: [PATCH 13/13] simplify --- .../testing/AbstractMongoClientTest.java | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java index 66e46dbca62f..bda0b04ae63c 100644 --- a/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java +++ b/instrumentation/mongo/mongo-common/testing/src/main/java/io/opentelemetry/instrumentation/mongo/testing/AbstractMongoClientTest.java @@ -128,7 +128,7 @@ void testCreateCollection() throws InterruptedException { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace.element(1), + span, "create", collectionName, dbName, @@ -161,7 +161,7 @@ void testCreateCollectionNoDescription() throws InterruptedException { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace.element(1), + span, "create", collectionName, dbName, @@ -195,7 +195,7 @@ void testCreateCollectionCallingBuildTwice() throws InterruptedException { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace.element(1), + span, "create", collectionName, dbName, @@ -229,7 +229,7 @@ void testGetCollection() throws Exception { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace.element(1), + span, "count", collectionName, dbName, @@ -266,7 +266,7 @@ void testInsert() throws Exception { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace.element(1), + span, "insert", collectionName, dbName, @@ -283,7 +283,7 @@ void testInsert() throws Exception { + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")), span -> mongoSpan( - trace.element(2), + span, "count", collectionName, dbName, @@ -320,7 +320,7 @@ void testUpdate() throws Exception { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace.element(1), + span, "update", collectionName, dbName, @@ -337,7 +337,7 @@ void testUpdate() throws Exception { + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"$set\":{\"password\":\"?\"}}}]}")), span -> mongoSpan( - trace.element(2), + span, "count", collectionName, dbName, @@ -374,7 +374,7 @@ void testDelete() throws Exception { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace.element(1), + span, "delete", collectionName, dbName, @@ -391,7 +391,7 @@ void testDelete() throws Exception { + "\",\"ordered\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"},\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")), span -> mongoSpan( - trace.element(2), + span, "count", collectionName, dbName, @@ -426,7 +426,7 @@ void testCollectionNameForGetMoreCommand() { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace.element(1), + span, "find", collectionName, dbName, @@ -446,7 +446,7 @@ void testCollectionNameForGetMoreCommand() { + "\",\"filter\":{\"_id\":{\"$gte\":\"?\"}},\"batchSize\":\"?\",\"$db\":\"?\",\"lsid\":{\"id\":\"?\"}}")), span -> mongoSpan( - trace.element(2), + span, "getMore", collectionName, dbName, @@ -483,7 +483,7 @@ void testCreateCollectionWithAlreadyBuiltClientOptions() { span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(), span -> mongoSpan( - trace.element(1), + span, "create", collectionName, dbName, @@ -505,14 +505,13 @@ protected String createCollectionName() { @SuppressWarnings("deprecation") // TODO DbIncubatingAttributes.DB_CONNECTION_STRING deprecation void mongoSpan( - SpanDataAssert spanData, + SpanDataAssert span, String operation, String collection, String dbName, Object parentSpan, List statements) { - SpanDataAssert span = - spanData.hasName(operation + " " + dbName + "." + collection).hasKind(CLIENT); + span.hasName(operation + " " + dbName + "." + collection).hasKind(CLIENT); if (parentSpan == null) { span.hasNoParent(); } else {