Cleanup mongodb tests (#2732)
* Cleanup mongodb tests * Drift * Cleanup * Timeout * Cleanup
This commit is contained in:
parent
d8f6018ba6
commit
826d8ac781
|
@ -17,135 +17,63 @@ import org.bson.BsonString
|
|||
import org.bson.Document
|
||||
import spock.lang.Shared
|
||||
|
||||
class MongoClientTest extends MongoBaseTest {
|
||||
class MongoClientTest extends AbstractMongoClientTest {
|
||||
|
||||
@Shared
|
||||
MongoClient client
|
||||
|
||||
def setup() throws Exception {
|
||||
def setupSpec() throws Exception {
|
||||
client = new MongoClient(new ServerAddress("localhost", port),
|
||||
MongoClientOptions.builder()
|
||||
.description("some-description")
|
||||
.build())
|
||||
}
|
||||
|
||||
def cleanup() throws Exception {
|
||||
def cleanupSpec() throws Exception {
|
||||
client?.close()
|
||||
client = null
|
||||
}
|
||||
|
||||
def "test create collection"() {
|
||||
setup:
|
||||
@Override
|
||||
void createCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
// 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.
|
||||
def "test create collection with already built ClientOptions"() {
|
||||
setup:
|
||||
@Override
|
||||
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||
MongoDatabase db = new MongoClient("localhost", port).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("localhost", port), newClientOptions).getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test create collection no description"() {
|
||||
setup:
|
||||
MongoDatabase db = new MongoClient("localhost", port).getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test get collection"() {
|
||||
setup:
|
||||
@Override
|
||||
int getCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
|
||||
when:
|
||||
int count = db.getCollection(collectionName).count()
|
||||
|
||||
then:
|
||||
count == 0
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return db.getCollection(collectionName).count()
|
||||
}
|
||||
|
||||
def "test insert"() {
|
||||
setup:
|
||||
@Override
|
||||
int insert(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
return db.getCollection(collectionName)
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
collection.insertOne(new Document("password", "SECRET"))
|
||||
|
||||
then:
|
||||
collection.count() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "insert", collectionName, dbName, "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return collection.count()
|
||||
}
|
||||
|
||||
def "test update"() {
|
||||
setup:
|
||||
@Override
|
||||
int update(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
|
@ -154,31 +82,15 @@ class MongoClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = collection.updateOne(
|
||||
new BsonDocument("password", new BsonString("OLDPW")),
|
||||
new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))))
|
||||
|
||||
then:
|
||||
result.modifiedCount == 1
|
||||
collection.count() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "update", collectionName, dbName, "{\"update\":\"$collectionName\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}")
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
collection.count()
|
||||
return result.modifiedCount
|
||||
}
|
||||
|
||||
def "test delete"() {
|
||||
setup:
|
||||
@Override
|
||||
int delete(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
|
@ -187,29 +99,13 @@ class MongoClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")))
|
||||
|
||||
then:
|
||||
result.deletedCount == 1
|
||||
collection.count() == 0
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "delete", collectionName, dbName, "{\"delete\":\"$collectionName\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
collection.count()
|
||||
return result.deletedCount
|
||||
}
|
||||
|
||||
def "test collection name for getMore command"() {
|
||||
setup:
|
||||
@Override
|
||||
void getMore(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def coll = db.getCollection(collectionName)
|
||||
|
@ -217,46 +113,19 @@ class MongoClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
collection.find().filter(new Document("_id", new Document('$gte', 0)))
|
||||
.batchSize(2).into(new ArrayList())
|
||||
|
||||
then:
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "find", collectionName, dbName, '{"find":"testCollection","filter":{"_id":{"$gte":"?"}},"batchSize":"?"}')
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "getMore", collectionName, dbName, '{"getMore":"?","collection":"?","batchSize":"?"}')
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test error"() {
|
||||
setup:
|
||||
@Override
|
||||
void error(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
return db.getCollection(collectionName)
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
collection.updateOne(new BsonDocument(), new BsonDocument())
|
||||
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
// Unfortunately not caught by our instrumentation.
|
||||
assertTraces(0) {}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test client failure"() {
|
||||
|
@ -275,6 +144,6 @@ class MongoClientTest extends MongoBaseTest {
|
|||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
collectionName = createCollectionName()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ import org.bson.BsonString
|
|||
import org.bson.Document
|
||||
import spock.lang.Shared
|
||||
|
||||
class MongoClientTest extends MongoBaseTest {
|
||||
class MongoClientTest extends AbstractMongoClientTest {
|
||||
|
||||
@Shared
|
||||
MongoClient client
|
||||
|
||||
def setup() throws Exception {
|
||||
def setupSpec() throws Exception {
|
||||
client = MongoClients.create(MongoClientSettings.builder()
|
||||
.applyToClusterSettings({ builder ->
|
||||
builder.hosts(Arrays.asList(
|
||||
|
@ -33,35 +33,25 @@ class MongoClientTest extends MongoBaseTest {
|
|||
.build())
|
||||
}
|
||||
|
||||
def cleanup() throws Exception {
|
||||
def cleanupSpec() throws Exception {
|
||||
client?.close()
|
||||
client = null
|
||||
}
|
||||
|
||||
def "test create collection"() {
|
||||
setup:
|
||||
@Override
|
||||
void createCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
// Tests the fix for https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/457
|
||||
// TracingCommandListener might get added multiple times if ClientSettings are built using existing ClientSettings or when calling a build method twice.
|
||||
// This test asserts that duplicate traces are not created in those cases.
|
||||
def "test create collection with already built ClientSettings"() {
|
||||
setup:
|
||||
@Override
|
||||
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||
MongoDatabase db = MongoClients.create("mongodb://localhost:${port}").getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
}
|
||||
|
||||
@Override
|
||||
void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) {
|
||||
def clientSettings = MongoClientSettings.builder()
|
||||
.applyToClusterSettings({ builder ->
|
||||
builder.hosts(Arrays.asList(
|
||||
|
@ -71,91 +61,29 @@ class MongoClientTest extends MongoBaseTest {
|
|||
.build()
|
||||
def newClientSettings = MongoClientSettings.builder(clientSettings).build()
|
||||
MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test create collection no description"() {
|
||||
setup:
|
||||
MongoDatabase db = MongoClients.create("mongodb://localhost:" + port).getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test get collection"() {
|
||||
setup:
|
||||
@Override
|
||||
int getCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
|
||||
when:
|
||||
int count = db.getCollection(collectionName).count()
|
||||
|
||||
then:
|
||||
count == 0
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return db.getCollection(collectionName).count()
|
||||
}
|
||||
|
||||
def "test insert"() {
|
||||
setup:
|
||||
@Override
|
||||
int insert(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
return db.getCollection(collectionName)
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
collection.insertOne(new Document("password", "SECRET"))
|
||||
|
||||
then:
|
||||
collection.count() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "insert", collectionName, dbName, "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return collection.count()
|
||||
}
|
||||
|
||||
def "test update"() {
|
||||
setup:
|
||||
@Override
|
||||
int update(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
|
@ -164,31 +92,15 @@ class MongoClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = collection.updateOne(
|
||||
new BsonDocument("password", new BsonString("OLDPW")),
|
||||
new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))))
|
||||
|
||||
then:
|
||||
result.modifiedCount == 1
|
||||
collection.count() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "update", collectionName, dbName, "{\"update\":\"$collectionName\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}")
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
collection.count()
|
||||
return result.modifiedCount
|
||||
}
|
||||
|
||||
def "test delete"() {
|
||||
setup:
|
||||
@Override
|
||||
int delete(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
|
@ -197,29 +109,13 @@ class MongoClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")))
|
||||
|
||||
then:
|
||||
result.deletedCount == 1
|
||||
collection.count() == 0
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "delete", collectionName, dbName, "{\"delete\":\"$collectionName\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
collection.count()
|
||||
return result.deletedCount
|
||||
}
|
||||
|
||||
def "test collection name for getMore command"() {
|
||||
setup:
|
||||
@Override
|
||||
void getMore(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def coll = db.getCollection(collectionName)
|
||||
|
@ -227,46 +123,19 @@ class MongoClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
collection.find().filter(new Document("_id", new Document('$gte', 0)))
|
||||
.batchSize(2).into(new ArrayList())
|
||||
|
||||
then:
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "find", collectionName, dbName, '{"find":"testCollection","filter":{"_id":{"$gte":"?"}},"batchSize":"?"}')
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "getMore", collectionName, dbName, '{"getMore":"?","collection":"?","batchSize":"?"}')
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test error"() {
|
||||
setup:
|
||||
@Override
|
||||
void error(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
return db.getCollection(collectionName)
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
collection.updateOne(new BsonDocument(), new BsonDocument())
|
||||
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
// Unfortunately not caught by our instrumentation.
|
||||
assertTraces(0) {}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test client failure"() {
|
||||
|
@ -284,6 +153,6 @@ class MongoClientTest extends MongoBaseTest {
|
|||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
collectionName = createCollectionName()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT
|
||||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
||||
|
||||
import com.mongodb.client.result.DeleteResult
|
||||
|
@ -12,105 +11,57 @@ 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.test.asserts.TraceAssert
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import org.bson.BsonDocument
|
||||
import org.bson.BsonString
|
||||
import org.bson.Document
|
||||
import org.junit.AssumptionViolatedException
|
||||
import org.reactivestreams.Subscriber
|
||||
import org.reactivestreams.Subscription
|
||||
import spock.lang.Shared
|
||||
|
||||
class Mongo4ReactiveClientTest extends MongoBaseTest {
|
||||
class Mongo4ReactiveClientTest extends AbstractMongoClientTest {
|
||||
|
||||
@Shared
|
||||
MongoClient client
|
||||
|
||||
def setup() throws Exception {
|
||||
def setupSpec() throws Exception {
|
||||
client = MongoClients.create("mongodb://localhost:$port")
|
||||
}
|
||||
|
||||
def cleanup() throws Exception {
|
||||
def cleanupSpec() throws Exception {
|
||||
client?.close()
|
||||
client = null
|
||||
}
|
||||
|
||||
def "test create collection"() {
|
||||
setup:
|
||||
@Override
|
||||
void createCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName).subscribe(toSubscriber {})
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
|
||||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test create collection no description"() {
|
||||
setup:
|
||||
MongoDatabase db = MongoClients.create("mongodb://localhost:$port").getDatabase(dbName)
|
||||
|
||||
when:
|
||||
@Override
|
||||
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||
MongoDatabase db = MongoClients.create("mongodb://localhost:${port}").getDatabase(dbName)
|
||||
db.createCollection(collectionName).subscribe(toSubscriber {})
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, {
|
||||
assert it.replaceAll(" ", "") == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
|
||||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test get collection"() {
|
||||
setup:
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
@Override
|
||||
void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) {
|
||||
throw new AssumptionViolatedException("not tested on 4.0")
|
||||
}
|
||||
|
||||
when:
|
||||
def count = new CompletableFuture()
|
||||
@Override
|
||||
int getCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def count = new CompletableFuture<Integer>()
|
||||
db.getCollection(collectionName).estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
||||
|
||||
then:
|
||||
count.get() == 0
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return count.join()
|
||||
}
|
||||
|
||||
def "test insert"() {
|
||||
setup:
|
||||
@Override
|
||||
int insert(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def latch1 = new CountDownLatch(1)
|
||||
|
@ -120,39 +71,15 @@ class Mongo4ReactiveClientTest extends MongoBaseTest {
|
|||
return db.getCollection(collectionName)
|
||||
}
|
||||
ignoreTracesAndClear(2)
|
||||
|
||||
when:
|
||||
def count = new CompletableFuture()
|
||||
def count = new CompletableFuture<Integer>()
|
||||
collection.insertOne(new Document("password", "SECRET")).subscribe(toSubscriber {
|
||||
collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
||||
})
|
||||
|
||||
then:
|
||||
count.get() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "insert", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}" ||
|
||||
it == "{\"insert\": \"$collectionName\", \"ordered\": \"?\", \"\$db\": \"?\", \"documents\": [{\"_id\": \"?\", \"password\": \"?\"}]}"
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return count.join()
|
||||
}
|
||||
|
||||
def "test update"() {
|
||||
setup:
|
||||
@Override
|
||||
int update(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def latch1 = new CountDownLatch(1)
|
||||
|
@ -165,8 +92,6 @@ class Mongo4ReactiveClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = new CompletableFuture<UpdateResult>()
|
||||
def count = new CompletableFuture()
|
||||
collection.updateOne(
|
||||
|
@ -175,34 +100,11 @@ class Mongo4ReactiveClientTest extends MongoBaseTest {
|
|||
result.complete(it)
|
||||
collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
||||
})
|
||||
|
||||
then:
|
||||
result.get().modifiedCount == 1
|
||||
count.get() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "update", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"update\":\"$collectionName\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}" ||
|
||||
it == "{\"update\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"updates\": [{\"q\": {\"password\": \"?\"}, \"u\": {\"\$set\": {\"password\": \"?\"}}}]}"
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return result.join().modifiedCount
|
||||
}
|
||||
|
||||
def "test delete"() {
|
||||
setup:
|
||||
@Override
|
||||
int delete(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def latch1 = new CountDownLatch(1)
|
||||
|
@ -215,38 +117,37 @@ class Mongo4ReactiveClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = new CompletableFuture<DeleteResult>()
|
||||
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.join().deletedCount
|
||||
}
|
||||
|
||||
then:
|
||||
result.get().deletedCount == 1
|
||||
count.get() == 0
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "delete", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"delete\":\"$collectionName\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}" ||
|
||||
it == "{\"delete\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"deletes\": [{\"q\": {\"password\": \"?\"}, \"limit\": \"?\"}]}"
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
@Override
|
||||
void getMore(String dbName, String collectionName) {
|
||||
throw new AssumptionViolatedException("not tested on reactive")
|
||||
}
|
||||
|
||||
@Override
|
||||
void error(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def latch = new CountDownLatch(1)
|
||||
db.createCollection(collectionName).subscribe(toSubscriber {
|
||||
latch.countDown()
|
||||
})
|
||||
latch.await()
|
||||
return db.getCollection(collectionName)
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
ignoreTracesAndClear(1)
|
||||
def result = new CompletableFuture<Throwable>()
|
||||
collection.updateOne(new BsonDocument(), new BsonDocument()).subscribe(toSubscriber {
|
||||
result.complete(it)
|
||||
})
|
||||
throw result.join()
|
||||
}
|
||||
|
||||
def Subscriber<?> toSubscriber(Closure closure) {
|
||||
|
@ -273,30 +174,4 @@ class Mongo4ReactiveClientTest extends MongoBaseTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
def mongoSpan(TraceAssert trace, int index,
|
||||
String operation, String collection,
|
||||
String dbName, Closure<Boolean> statementEval,
|
||||
Object parentSpan = null, Throwable exception = null) {
|
||||
trace.span(index) {
|
||||
name { operation + " " + dbName + "." + collection }
|
||||
kind CLIENT
|
||||
if (parentSpan == null) {
|
||||
hasNoParent()
|
||||
} else {
|
||||
childOf((SpanData) parentSpan)
|
||||
}
|
||||
attributes {
|
||||
"$SemanticAttributes.NET_PEER_NAME.key" "localhost"
|
||||
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
|
||||
"$SemanticAttributes.NET_PEER_PORT.key" port
|
||||
"$SemanticAttributes.DB_CONNECTION_STRING.key" "mongodb://localhost:" + port
|
||||
"$SemanticAttributes.DB_STATEMENT.key" statementEval
|
||||
"$SemanticAttributes.DB_SYSTEM.key" "mongodb"
|
||||
"$SemanticAttributes.DB_NAME.key" dbName
|
||||
"$SemanticAttributes.DB_OPERATION.key" operation
|
||||
"$SemanticAttributes.DB_MONGODB_COLLECTION.key" collection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import static io.opentelemetry.instrumentation.test.utils.PortUtils.UNUSABLE_PORT
|
||||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
||||
|
||||
import com.mongodb.MongoTimeoutException
|
||||
import com.mongodb.client.MongoClient
|
||||
import com.mongodb.client.MongoClients
|
||||
import com.mongodb.client.MongoCollection
|
||||
|
@ -14,110 +12,60 @@ import com.mongodb.client.MongoDatabase
|
|||
import org.bson.BsonDocument
|
||||
import org.bson.BsonString
|
||||
import org.bson.Document
|
||||
import org.junit.AssumptionViolatedException
|
||||
import spock.lang.Shared
|
||||
|
||||
class MongoClientTest extends MongoBaseTest {
|
||||
class MongoClientTest extends AbstractMongoClientTest {
|
||||
|
||||
@Shared
|
||||
MongoClient client
|
||||
|
||||
def setup() throws Exception {
|
||||
def setupSpec() throws Exception {
|
||||
client = MongoClients.create("mongodb://localhost:$port")
|
||||
}
|
||||
|
||||
def cleanup() throws Exception {
|
||||
def cleanupSpec() throws Exception {
|
||||
client?.close()
|
||||
client = null
|
||||
}
|
||||
|
||||
def "test create collection"() {
|
||||
setup:
|
||||
@Override
|
||||
void createCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test create collection no description"() {
|
||||
setup:
|
||||
MongoDatabase db = MongoClients.create("mongodb://localhost:$port").getDatabase(dbName)
|
||||
|
||||
when:
|
||||
@Override
|
||||
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||
MongoDatabase db = MongoClients.create("mongodb://localhost:${port}").getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, "{\"create\":\"$collectionName\",\"capped\":\"?\"}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test get collection"() {
|
||||
setup:
|
||||
@Override
|
||||
void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) {
|
||||
throw new AssumptionViolatedException("not tested on 4.0")
|
||||
}
|
||||
|
||||
@Override
|
||||
int getCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
|
||||
when:
|
||||
int count = db.getCollection(collectionName).estimatedDocumentCount()
|
||||
|
||||
then:
|
||||
count == 0
|
||||
assertTraces(1) {
|
||||
trace(0,1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return db.getCollection(collectionName).estimatedDocumentCount()
|
||||
}
|
||||
|
||||
def "test insert"() {
|
||||
setup:
|
||||
@Override
|
||||
int insert(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
return db.getCollection(collectionName)
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
collection.insertOne(new Document("password", "SECRET"))
|
||||
|
||||
then:
|
||||
collection.estimatedDocumentCount() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "insert", collectionName, dbName, "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}")
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return collection.estimatedDocumentCount()
|
||||
}
|
||||
|
||||
def "test update"() {
|
||||
setup:
|
||||
@Override
|
||||
int update(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
|
@ -126,31 +74,15 @@ class MongoClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = collection.updateOne(
|
||||
new BsonDocument("password", new BsonString("OLDPW")),
|
||||
new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))))
|
||||
|
||||
then:
|
||||
result.modifiedCount == 1
|
||||
collection.estimatedDocumentCount() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "update", collectionName, dbName, "{\"update\":\"$collectionName\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}")
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
collection.estimatedDocumentCount()
|
||||
return result.modifiedCount
|
||||
}
|
||||
|
||||
def "test delete"() {
|
||||
setup:
|
||||
@Override
|
||||
int delete(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
|
@ -159,65 +91,32 @@ class MongoClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")))
|
||||
|
||||
then:
|
||||
result.deletedCount == 1
|
||||
collection.estimatedDocumentCount() == 0
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "delete", collectionName, dbName, "{\"delete\":\"$collectionName\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}")
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName, "{\"count\":\"$collectionName\",\"query\":{}}")
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
collection.estimatedDocumentCount()
|
||||
return result.deletedCount
|
||||
}
|
||||
|
||||
def "test error"() {
|
||||
setup:
|
||||
@Override
|
||||
void getMore(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("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)
|
||||
collection.find().filter(new Document("_id", new Document('$gte', 0)))
|
||||
.batchSize(2).into(new ArrayList())
|
||||
}
|
||||
|
||||
@Override
|
||||
void error(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
db.createCollection(collectionName)
|
||||
return db.getCollection(collectionName)
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
collection.updateOne(new BsonDocument(), new BsonDocument())
|
||||
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
// Unfortunately not caught by our instrumentation.
|
||||
assertTraces(0) {}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test client failure"() {
|
||||
setup:
|
||||
def client = MongoClients.create("mongodb://localhost:$UNUSABLE_PORT/?serverselectiontimeoutms=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 = "testCollection"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT
|
||||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
||||
|
||||
import com.mongodb.ConnectionString
|
||||
|
@ -16,22 +15,20 @@ 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.test.asserts.TraceAssert
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import org.bson.BsonDocument
|
||||
import org.bson.BsonString
|
||||
import org.bson.Document
|
||||
import org.junit.AssumptionViolatedException
|
||||
import spock.lang.Shared
|
||||
|
||||
class MongoAsyncClientTest extends MongoBaseTest {
|
||||
class MongoAsyncClientTest extends AbstractMongoClientTest {
|
||||
|
||||
@Shared
|
||||
MongoClient client
|
||||
|
||||
def setup() throws Exception {
|
||||
def setupSpec() throws Exception {
|
||||
client = MongoClients.create(
|
||||
MongoClientSettings.builder()
|
||||
.clusterSettings(
|
||||
|
@ -42,112 +39,41 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
|||
.build())
|
||||
}
|
||||
|
||||
def cleanup() throws Exception {
|
||||
def cleanupSpec() throws Exception {
|
||||
client?.close()
|
||||
client = null
|
||||
}
|
||||
|
||||
def "test create collection"() {
|
||||
setup:
|
||||
@Override
|
||||
void createCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName, toCallback {})
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
|
||||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
// Tests the fix for https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/457
|
||||
// TracingCommandListener might get added multiple times if ClientSettings are built using existing ClientSettings or when calling a build method twice.
|
||||
// This test asserts that duplicate traces are not created in those cases.
|
||||
def "test create collection with already built ClientSettings"() {
|
||||
setup:
|
||||
@Override
|
||||
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||
MongoDatabase db = MongoClients.create("mongodb://localhost:$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)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName, toCallback {})
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
|
||||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test create collection no description"() {
|
||||
setup:
|
||||
MongoDatabase db = MongoClients.create("mongodb://localhost:$port").getDatabase(dbName)
|
||||
|
||||
when:
|
||||
db.createCollection(collectionName, toCallback {})
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
|
||||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
}
|
||||
|
||||
def "test get collection"() {
|
||||
setup:
|
||||
@Override
|
||||
int getCollection(String dbName, String collectionName) {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
|
||||
when:
|
||||
def count = new CompletableFuture()
|
||||
def count = new CompletableFuture<Integer>()
|
||||
db.getCollection(collectionName).count toCallback { count.complete(it) }
|
||||
|
||||
then:
|
||||
count.get() == 0
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return count.join()
|
||||
}
|
||||
|
||||
def "test insert"() {
|
||||
setup:
|
||||
@Override
|
||||
int insert(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def latch1 = new CountDownLatch(1)
|
||||
|
@ -156,39 +82,15 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
|||
return db.getCollection(collectionName)
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def count = new CompletableFuture()
|
||||
def count = new CompletableFuture<Integer>()
|
||||
collection.insertOne(new Document("password", "SECRET"), toCallback {
|
||||
collection.count toCallback { count.complete(it) }
|
||||
})
|
||||
|
||||
then:
|
||||
count.get() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "insert", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}" ||
|
||||
it == "{\"insert\": \"$collectionName\", \"ordered\": \"?\", \"\$db\": \"?\", \"documents\": [{\"_id\": \"?\", \"password\": \"?\"}]}"
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return count.get()
|
||||
}
|
||||
|
||||
def "test update"() {
|
||||
setup:
|
||||
@Override
|
||||
int update(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def latch1 = new CountDownLatch(1)
|
||||
|
@ -201,8 +103,6 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = new CompletableFuture<UpdateResult>()
|
||||
def count = new CompletableFuture()
|
||||
collection.updateOne(
|
||||
|
@ -211,34 +111,11 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
|||
result.complete(it)
|
||||
collection.count toCallback { count.complete(it) }
|
||||
})
|
||||
|
||||
then:
|
||||
result.get().modifiedCount == 1
|
||||
count.get() == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "update", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"update\":\"$collectionName\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}" ||
|
||||
it == "{\"update\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"updates\": [{\"q\": {\"password\": \"?\"}, \"u\": {\"\$set\": {\"password\": \"?\"}}}]}"
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
return result.get().modifiedCount
|
||||
}
|
||||
|
||||
def "test delete"() {
|
||||
setup:
|
||||
@Override
|
||||
int delete(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def latch1 = new CountDownLatch(1)
|
||||
|
@ -251,38 +128,37 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
|||
return coll
|
||||
}
|
||||
ignoreTracesAndClear(1)
|
||||
|
||||
when:
|
||||
def result = new CompletableFuture<DeleteResult>()
|
||||
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
|
||||
}
|
||||
|
||||
then:
|
||||
result.get().deletedCount == 1
|
||||
count.get() == 0
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "delete", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"delete\":\"$collectionName\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}" ||
|
||||
it == "{\"delete\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"deletes\": [{\"q\": {\"password\": \"?\"}, \"limit\": \"?\"}]}"
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
@Override
|
||||
void getMore(String dbName, String collectionName) {
|
||||
throw new AssumptionViolatedException("not tested on async")
|
||||
}
|
||||
|
||||
@Override
|
||||
void error(String dbName, String collectionName) {
|
||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||
MongoDatabase db = client.getDatabase(dbName)
|
||||
def latch = new CountDownLatch(1)
|
||||
db.createCollection(collectionName, toCallback {
|
||||
latch.countDown()
|
||||
})
|
||||
latch.await()
|
||||
return db.getCollection(collectionName)
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = "testCollection"
|
||||
ignoreTracesAndClear(1)
|
||||
def result = new CompletableFuture<Throwable>()
|
||||
collection.updateOne(new BsonDocument(), new BsonDocument(), toCallback {
|
||||
result.complete(it)
|
||||
})
|
||||
throw result.join()
|
||||
}
|
||||
|
||||
SingleResultCallback toCallback(Closure closure) {
|
||||
|
@ -297,30 +173,4 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
def mongoSpan(TraceAssert trace, int index,
|
||||
String operation, String collection,
|
||||
String dbName, Closure<Boolean> statementEval,
|
||||
Object parentSpan = null, Throwable exception = null) {
|
||||
trace.span(index) {
|
||||
name { operation + " " + dbName + "." + collection }
|
||||
kind CLIENT
|
||||
if (parentSpan == null) {
|
||||
hasNoParent()
|
||||
} else {
|
||||
childOf((SpanData) parentSpan)
|
||||
}
|
||||
attributes {
|
||||
"$SemanticAttributes.NET_PEER_NAME.key" "localhost"
|
||||
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
|
||||
"$SemanticAttributes.NET_PEER_PORT.key" port
|
||||
"$SemanticAttributes.DB_CONNECTION_STRING.key" "mongodb://localhost:" + port
|
||||
"$SemanticAttributes.DB_STATEMENT.key" statementEval
|
||||
"$SemanticAttributes.DB_SYSTEM.key" "mongodb"
|
||||
"$SemanticAttributes.DB_NAME.key" dbName
|
||||
"$SemanticAttributes.DB_OPERATION.key" operation
|
||||
"$SemanticAttributes.DB_MONGODB_COLLECTION.key" collection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ apply from: "$rootDir/gradle/java.gradle"
|
|||
|
||||
dependencies {
|
||||
api project(':testing-common')
|
||||
api group: 'de.flapdoodle.embed', name: 'de.flapdoodle.embed.mongo', version: '1.50.5'
|
||||
api group: 'org.testcontainers', name: 'mongodb', version: versions.testcontainers
|
||||
|
||||
implementation deps.groovy
|
||||
implementation deps.opentelemetryApi
|
||||
|
|
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.testcontainers.containers.GenericContainer
|
||||
import org.testcontainers.containers.output.Slf4jLogConsumer
|
||||
import spock.lang.Shared
|
||||
|
||||
abstract class AbstractMongoClientTest extends AgentInstrumentationSpecification {
|
||||
|
||||
@Shared
|
||||
GenericContainer mongodb
|
||||
|
||||
@Shared
|
||||
int port
|
||||
|
||||
def setupSpec() {
|
||||
mongodb = new GenericContainer("mongo:3.2")
|
||||
.withExposedPorts(27017)
|
||||
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("mongodb")))
|
||||
mongodb.start()
|
||||
|
||||
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 int getCollection(String dbName, String collectionName)
|
||||
|
||||
abstract int insert(String dbName, String collectionName)
|
||||
|
||||
abstract int update(String dbName, String collectionName)
|
||||
|
||||
abstract int delete(String dbName, String collectionName)
|
||||
|
||||
abstract void getMore(String dbName, String collectionName)
|
||||
|
||||
abstract void error(String dbName, String collectionName)
|
||||
|
||||
def "test port open"() {
|
||||
when:
|
||||
new Socket("localhost", port)
|
||||
|
||||
then:
|
||||
noExceptionThrown()
|
||||
}
|
||||
|
||||
def "test create collection"() {
|
||||
when:
|
||||
createCollection(dbName, collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName) {
|
||||
assert it == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
|
||||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = createCollectionName()
|
||||
}
|
||||
|
||||
def "test create collection no description"() {
|
||||
when:
|
||||
createCollectionNoDescription(dbName, collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName, {
|
||||
assert it == "{\"create\":\"$collectionName\",\"capped\":\"?\"}" ||
|
||||
it == "{\"create\": \"$collectionName\", \"capped\": \"?\", \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = createCollectionName()
|
||||
}
|
||||
|
||||
def "test get collection"() {
|
||||
when:
|
||||
def count = getCollection(dbName, collectionName)
|
||||
|
||||
then:
|
||||
count == 0
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = createCollectionName()
|
||||
}
|
||||
|
||||
def "test insert"() {
|
||||
when:
|
||||
def count = insert(dbName, collectionName)
|
||||
|
||||
then:
|
||||
count == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "insert", collectionName, dbName) {
|
||||
assert it == "{\"insert\":\"$collectionName\",\"ordered\":\"?\",\"documents\":[{\"_id\":\"?\",\"password\":\"?\"}]}" ||
|
||||
it == "{\"insert\": \"$collectionName\", \"ordered\": \"?\", \"\$db\": \"?\", \"documents\": [{\"_id\": \"?\", \"password\": \"?\"}]}"
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = createCollectionName()
|
||||
}
|
||||
|
||||
def "test update"() {
|
||||
when:
|
||||
int modifiedCount = update(dbName, collectionName)
|
||||
|
||||
then:
|
||||
modifiedCount == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "update", collectionName, dbName) {
|
||||
assert it == "{\"update\":\"$collectionName\",\"ordered\":\"?\",\"updates\":[{\"q\":{\"password\":\"?\"},\"u\":{\"\$set\":{\"password\":\"?\"}}}]}" ||
|
||||
it == "{\"update\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"updates\": [{\"q\": {\"password\": \"?\"}, \"u\": {\"\$set\": {\"password\": \"?\"}}}]}"
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = createCollectionName()
|
||||
}
|
||||
|
||||
def "test delete"() {
|
||||
when:
|
||||
int deletedCount = delete(dbName, collectionName)
|
||||
|
||||
then:
|
||||
deletedCount == 1
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "delete", collectionName, dbName) {
|
||||
assert it == "{\"delete\":\"$collectionName\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}" ||
|
||||
it == "{\"delete\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"deletes\": [{\"q\": {\"password\": \"?\"}, \"limit\": \"?\"}]}"
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
||||
assert it == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = createCollectionName()
|
||||
}
|
||||
|
||||
def "test collection name for getMore command"() {
|
||||
when:
|
||||
getMore(dbName, collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(2) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "find", collectionName, dbName) {
|
||||
assert it == '{"find":"' + collectionName + '","filter":{"_id":{"$gte":"?"}},"batchSize":"?"}'
|
||||
true
|
||||
}
|
||||
}
|
||||
trace(1, 1) {
|
||||
mongoSpan(it, 0, "getMore", collectionName, dbName) {
|
||||
assert it == '{"getMore":"?","collection":"?","batchSize":"?"}'
|
||||
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:
|
||||
createCollectionWithAlreadyBuiltClientOptions(dbName, collectionName)
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
mongoSpan(it, 0, "create", collectionName, dbName) {
|
||||
assert it == "{\"create\":\"$collectionName\",\"capped\":\"?\"}"
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
dbName = "test_db"
|
||||
collectionName = createCollectionName()
|
||||
}
|
||||
|
||||
private static final AtomicInteger collectionIndex = new AtomicInteger()
|
||||
|
||||
def createCollectionName() {
|
||||
return "testCollection-${collectionIndex.getAndIncrement()}"
|
||||
}
|
||||
|
||||
def mongoSpan(TraceAssert trace, int index,
|
||||
String operation, String collection,
|
||||
String dbName, Closure<Boolean> statementEval,
|
||||
Object parentSpan = null, Throwable exception = null) {
|
||||
trace.span(index) {
|
||||
name { operation + " " + dbName + "." + collection }
|
||||
kind CLIENT
|
||||
if (parentSpan == null) {
|
||||
hasNoParent()
|
||||
} else {
|
||||
childOf((SpanData) parentSpan)
|
||||
}
|
||||
attributes {
|
||||
"$SemanticAttributes.NET_PEER_NAME.key" "localhost"
|
||||
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
|
||||
"$SemanticAttributes.NET_PEER_PORT.key" port
|
||||
"$SemanticAttributes.DB_STATEMENT.key" {
|
||||
statementEval.call(it.replaceAll(" ", ""))
|
||||
}
|
||||
"$SemanticAttributes.DB_SYSTEM.key" "mongodb"
|
||||
"$SemanticAttributes.DB_CONNECTION_STRING.key" "mongodb://localhost:" + port
|
||||
"$SemanticAttributes.DB_NAME.key" dbName
|
||||
"$SemanticAttributes.DB_OPERATION.key" operation
|
||||
"$SemanticAttributes.DB_MONGODB_COLLECTION.key" collection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT
|
||||
|
||||
import de.flapdoodle.embed.mongo.MongodExecutable
|
||||
import de.flapdoodle.embed.mongo.MongodProcess
|
||||
import de.flapdoodle.embed.mongo.MongodStarter
|
||||
import de.flapdoodle.embed.mongo.config.IMongodConfig
|
||||
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder
|
||||
import de.flapdoodle.embed.mongo.config.Net
|
||||
import de.flapdoodle.embed.mongo.distribution.Version
|
||||
import de.flapdoodle.embed.process.runtime.Network
|
||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
|
||||
import io.opentelemetry.instrumentation.test.utils.PortUtils
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import spock.lang.Shared
|
||||
|
||||
/**
|
||||
* Testing needs to be in a centralized project.
|
||||
* If tests in multiple different projects are using embedded mongo,
|
||||
* they downloader is at risk of a race condition.
|
||||
*/
|
||||
class MongoBaseTest extends AgentInstrumentationSpecification {
|
||||
// https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo#executable-collision
|
||||
private static final MongodStarter STARTER = MongodStarter.getDefaultInstance()
|
||||
|
||||
@Shared
|
||||
int port = PortUtils.findOpenPort()
|
||||
@Shared
|
||||
MongodExecutable mongodExe
|
||||
@Shared
|
||||
MongodProcess mongod
|
||||
|
||||
def setup() throws Exception {
|
||||
IMongodConfig mongodConfig =
|
||||
new MongodConfigBuilder()
|
||||
.version(Version.Main.PRODUCTION)
|
||||
.net(new Net("localhost", port, Network.localhostIsIPv6()))
|
||||
.build()
|
||||
|
||||
// using a system-wide file lock to prevent other modules that may be running in parallel
|
||||
// from clobbering each other while downloading and extracting mongodb
|
||||
def lockFile = new File(System.getProperty("java.io.tmpdir"), "prepare-embedded-mongo.lock")
|
||||
def channel = new RandomAccessFile(lockFile, "rw").getChannel()
|
||||
def lock = channel.lock()
|
||||
try {
|
||||
mongodExe = STARTER.prepare(mongodConfig)
|
||||
} finally {
|
||||
lock.release()
|
||||
channel.close()
|
||||
}
|
||||
mongod = mongodExe.start()
|
||||
}
|
||||
|
||||
def cleanup() throws Exception {
|
||||
mongod?.stop()
|
||||
mongod = null
|
||||
mongodExe?.stop()
|
||||
mongodExe = null
|
||||
}
|
||||
|
||||
def "test port open"() {
|
||||
when:
|
||||
new Socket("localhost", port)
|
||||
|
||||
then:
|
||||
noExceptionThrown()
|
||||
}
|
||||
|
||||
def mongoSpan(TraceAssert trace, int index,
|
||||
String operation, String collection,
|
||||
String dbName, String statement,
|
||||
Object parentSpan = null, Throwable exception = null) {
|
||||
trace.span(index) {
|
||||
name { operation + " " + dbName + "." + collection }
|
||||
kind CLIENT
|
||||
if (parentSpan == null) {
|
||||
hasNoParent()
|
||||
} else {
|
||||
childOf((SpanData) parentSpan)
|
||||
}
|
||||
attributes {
|
||||
"$SemanticAttributes.NET_PEER_NAME.key" "localhost"
|
||||
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
|
||||
"$SemanticAttributes.NET_PEER_PORT.key" port
|
||||
"$SemanticAttributes.DB_STATEMENT.key" {
|
||||
it.replace(" ", "") == statement
|
||||
}
|
||||
"$SemanticAttributes.DB_SYSTEM.key" "mongodb"
|
||||
"$SemanticAttributes.DB_CONNECTION_STRING.key" "mongodb://localhost:" + port
|
||||
"$SemanticAttributes.DB_NAME.key" dbName
|
||||
"$SemanticAttributes.DB_OPERATION.key" operation
|
||||
"$SemanticAttributes.DB_MONGODB_COLLECTION.key" collection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue