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 org.bson.Document
|
||||||
import spock.lang.Shared
|
import spock.lang.Shared
|
||||||
|
|
||||||
class MongoClientTest extends MongoBaseTest {
|
class MongoClientTest extends AbstractMongoClientTest {
|
||||||
|
|
||||||
@Shared
|
@Shared
|
||||||
MongoClient client
|
MongoClient client
|
||||||
|
|
||||||
def setup() throws Exception {
|
def setupSpec() throws Exception {
|
||||||
client = new MongoClient(new ServerAddress("localhost", port),
|
client = new MongoClient(new ServerAddress("localhost", port),
|
||||||
MongoClientOptions.builder()
|
MongoClientOptions.builder()
|
||||||
.description("some-description")
|
.description("some-description")
|
||||||
.build())
|
.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() throws Exception {
|
def cleanupSpec() throws Exception {
|
||||||
client?.close()
|
client?.close()
|
||||||
client = null
|
client = null
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test create collection"() {
|
@Override
|
||||||
setup:
|
void createCollection(String dbName, String collectionName) {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName)
|
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
|
@Override
|
||||||
// TracingCommandListener might get added multiple times if clientOptions are built using existing clientOptions or when calling a build method twice.
|
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||||
// This test asserts that duplicate traces are not created in those cases.
|
MongoDatabase db = new MongoClient("localhost", port).getDatabase(dbName)
|
||||||
def "test create collection with already built ClientOptions"() {
|
db.createCollection(collectionName)
|
||||||
setup:
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) {
|
||||||
def clientOptions = client.mongoClientOptions
|
def clientOptions = client.mongoClientOptions
|
||||||
def newClientOptions = MongoClientOptions.builder(clientOptions).build()
|
def newClientOptions = MongoClientOptions.builder(clientOptions).build()
|
||||||
MongoDatabase db = new MongoClient(new ServerAddress("localhost", port), newClientOptions).getDatabase(dbName)
|
MongoDatabase db = new MongoClient(new ServerAddress("localhost", port), newClientOptions).getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName)
|
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"() {
|
@Override
|
||||||
setup:
|
int getCollection(String dbName, String collectionName) {
|
||||||
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:
|
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
|
return db.getCollection(collectionName).count()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test insert"() {
|
@Override
|
||||||
setup:
|
int insert(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
return db.getCollection(collectionName)
|
return db.getCollection(collectionName)
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
collection.insertOne(new Document("password", "SECRET"))
|
collection.insertOne(new Document("password", "SECRET"))
|
||||||
|
return collection.count()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test update"() {
|
@Override
|
||||||
setup:
|
int update(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
|
@ -154,31 +82,15 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = collection.updateOne(
|
def result = collection.updateOne(
|
||||||
new BsonDocument("password", new BsonString("OLDPW")),
|
new BsonDocument("password", new BsonString("OLDPW")),
|
||||||
new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))))
|
new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))))
|
||||||
|
collection.count()
|
||||||
then:
|
return result.modifiedCount
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test delete"() {
|
@Override
|
||||||
setup:
|
int delete(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
|
@ -187,29 +99,13 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")))
|
def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")))
|
||||||
|
collection.count()
|
||||||
then:
|
return result.deletedCount
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test collection name for getMore command"() {
|
@Override
|
||||||
setup:
|
void getMore(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
def coll = db.getCollection(collectionName)
|
def coll = db.getCollection(collectionName)
|
||||||
|
@ -217,46 +113,19 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
collection.find().filter(new Document("_id", new Document('$gte', 0)))
|
collection.find().filter(new Document("_id", new Document('$gte', 0)))
|
||||||
.batchSize(2).into(new ArrayList())
|
.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"() {
|
@Override
|
||||||
setup:
|
void error(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
return db.getCollection(collectionName)
|
return db.getCollection(collectionName)
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
collection.updateOne(new BsonDocument(), new BsonDocument())
|
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"() {
|
def "test client failure"() {
|
||||||
|
@ -275,6 +144,6 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
|
|
||||||
where:
|
where:
|
||||||
dbName = "test_db"
|
dbName = "test_db"
|
||||||
collectionName = "testCollection"
|
collectionName = createCollectionName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,12 @@ import org.bson.BsonString
|
||||||
import org.bson.Document
|
import org.bson.Document
|
||||||
import spock.lang.Shared
|
import spock.lang.Shared
|
||||||
|
|
||||||
class MongoClientTest extends MongoBaseTest {
|
class MongoClientTest extends AbstractMongoClientTest {
|
||||||
|
|
||||||
@Shared
|
@Shared
|
||||||
MongoClient client
|
MongoClient client
|
||||||
|
|
||||||
def setup() throws Exception {
|
def setupSpec() throws Exception {
|
||||||
client = MongoClients.create(MongoClientSettings.builder()
|
client = MongoClients.create(MongoClientSettings.builder()
|
||||||
.applyToClusterSettings({ builder ->
|
.applyToClusterSettings({ builder ->
|
||||||
builder.hosts(Arrays.asList(
|
builder.hosts(Arrays.asList(
|
||||||
|
@ -33,35 +33,25 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
.build())
|
.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() throws Exception {
|
def cleanupSpec() throws Exception {
|
||||||
client?.close()
|
client?.close()
|
||||||
client = null
|
client = null
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test create collection"() {
|
@Override
|
||||||
setup:
|
void createCollection(String dbName, String collectionName) {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName)
|
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
|
@Override
|
||||||
// TracingCommandListener might get added multiple times if ClientSettings are built using existing ClientSettings or when calling a build method twice.
|
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||||
// This test asserts that duplicate traces are not created in those cases.
|
MongoDatabase db = MongoClients.create("mongodb://localhost:${port}").getDatabase(dbName)
|
||||||
def "test create collection with already built ClientSettings"() {
|
db.createCollection(collectionName)
|
||||||
setup:
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) {
|
||||||
def clientSettings = MongoClientSettings.builder()
|
def clientSettings = MongoClientSettings.builder()
|
||||||
.applyToClusterSettings({ builder ->
|
.applyToClusterSettings({ builder ->
|
||||||
builder.hosts(Arrays.asList(
|
builder.hosts(Arrays.asList(
|
||||||
|
@ -71,91 +61,29 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
.build()
|
.build()
|
||||||
def newClientSettings = MongoClientSettings.builder(clientSettings).build()
|
def newClientSettings = MongoClientSettings.builder(clientSettings).build()
|
||||||
MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName)
|
MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName)
|
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"() {
|
@Override
|
||||||
setup:
|
int getCollection(String dbName, String collectionName) {
|
||||||
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:
|
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
|
return db.getCollection(collectionName).count()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test insert"() {
|
@Override
|
||||||
setup:
|
int insert(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
return db.getCollection(collectionName)
|
return db.getCollection(collectionName)
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
collection.insertOne(new Document("password", "SECRET"))
|
collection.insertOne(new Document("password", "SECRET"))
|
||||||
|
return collection.count()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test update"() {
|
@Override
|
||||||
setup:
|
int update(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
|
@ -164,31 +92,15 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = collection.updateOne(
|
def result = collection.updateOne(
|
||||||
new BsonDocument("password", new BsonString("OLDPW")),
|
new BsonDocument("password", new BsonString("OLDPW")),
|
||||||
new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))))
|
new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))))
|
||||||
|
collection.count()
|
||||||
then:
|
return result.modifiedCount
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test delete"() {
|
@Override
|
||||||
setup:
|
int delete(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
|
@ -197,29 +109,13 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")))
|
def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")))
|
||||||
|
collection.count()
|
||||||
then:
|
return result.deletedCount
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test collection name for getMore command"() {
|
@Override
|
||||||
setup:
|
void getMore(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
def coll = db.getCollection(collectionName)
|
def coll = db.getCollection(collectionName)
|
||||||
|
@ -227,46 +123,19 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
collection.find().filter(new Document("_id", new Document('$gte', 0)))
|
collection.find().filter(new Document("_id", new Document('$gte', 0)))
|
||||||
.batchSize(2).into(new ArrayList())
|
.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"() {
|
@Override
|
||||||
setup:
|
void error(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
return db.getCollection(collectionName)
|
return db.getCollection(collectionName)
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
collection.updateOne(new BsonDocument(), new BsonDocument())
|
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"() {
|
def "test client failure"() {
|
||||||
|
@ -284,6 +153,6 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
|
|
||||||
where:
|
where:
|
||||||
dbName = "test_db"
|
dbName = "test_db"
|
||||||
collectionName = "testCollection"
|
collectionName = createCollectionName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT
|
|
||||||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
||||||
|
|
||||||
import com.mongodb.client.result.DeleteResult
|
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.MongoClients
|
||||||
import com.mongodb.reactivestreams.client.MongoCollection
|
import com.mongodb.reactivestreams.client.MongoCollection
|
||||||
import com.mongodb.reactivestreams.client.MongoDatabase
|
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.CompletableFuture
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import org.bson.BsonDocument
|
import org.bson.BsonDocument
|
||||||
import org.bson.BsonString
|
import org.bson.BsonString
|
||||||
import org.bson.Document
|
import org.bson.Document
|
||||||
|
import org.junit.AssumptionViolatedException
|
||||||
import org.reactivestreams.Subscriber
|
import org.reactivestreams.Subscriber
|
||||||
import org.reactivestreams.Subscription
|
import org.reactivestreams.Subscription
|
||||||
import spock.lang.Shared
|
import spock.lang.Shared
|
||||||
|
|
||||||
class Mongo4ReactiveClientTest extends MongoBaseTest {
|
class Mongo4ReactiveClientTest extends AbstractMongoClientTest {
|
||||||
|
|
||||||
@Shared
|
@Shared
|
||||||
MongoClient client
|
MongoClient client
|
||||||
|
|
||||||
def setup() throws Exception {
|
def setupSpec() throws Exception {
|
||||||
client = MongoClients.create("mongodb://localhost:$port")
|
client = MongoClients.create("mongodb://localhost:$port")
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() throws Exception {
|
def cleanupSpec() throws Exception {
|
||||||
client?.close()
|
client?.close()
|
||||||
client = null
|
client = null
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test create collection"() {
|
@Override
|
||||||
setup:
|
void createCollection(String dbName, String collectionName) {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName).subscribe(toSubscriber {})
|
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"() {
|
@Override
|
||||||
setup:
|
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||||
MongoDatabase db = MongoClients.create("mongodb://localhost:$port").getDatabase(dbName)
|
MongoDatabase db = MongoClients.create("mongodb://localhost:${port}").getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName).subscribe(toSubscriber {})
|
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"() {
|
@Override
|
||||||
setup:
|
void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
throw new AssumptionViolatedException("not tested on 4.0")
|
||||||
|
}
|
||||||
|
|
||||||
when:
|
@Override
|
||||||
def count = new CompletableFuture()
|
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) })
|
db.getCollection(collectionName).estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
||||||
|
return count.join()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test insert"() {
|
@Override
|
||||||
setup:
|
int insert(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
def latch1 = new CountDownLatch(1)
|
def latch1 = new CountDownLatch(1)
|
||||||
|
@ -120,39 +71,15 @@ class Mongo4ReactiveClientTest extends MongoBaseTest {
|
||||||
return db.getCollection(collectionName)
|
return db.getCollection(collectionName)
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(2)
|
ignoreTracesAndClear(2)
|
||||||
|
def count = new CompletableFuture<Integer>()
|
||||||
when:
|
|
||||||
def count = new CompletableFuture()
|
|
||||||
collection.insertOne(new Document("password", "SECRET")).subscribe(toSubscriber {
|
collection.insertOne(new Document("password", "SECRET")).subscribe(toSubscriber {
|
||||||
collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
||||||
})
|
})
|
||||||
|
return count.join()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test update"() {
|
@Override
|
||||||
setup:
|
int update(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
def latch1 = new CountDownLatch(1)
|
def latch1 = new CountDownLatch(1)
|
||||||
|
@ -165,8 +92,6 @@ class Mongo4ReactiveClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = new CompletableFuture<UpdateResult>()
|
def result = new CompletableFuture<UpdateResult>()
|
||||||
def count = new CompletableFuture()
|
def count = new CompletableFuture()
|
||||||
collection.updateOne(
|
collection.updateOne(
|
||||||
|
@ -175,34 +100,11 @@ class Mongo4ReactiveClientTest extends MongoBaseTest {
|
||||||
result.complete(it)
|
result.complete(it)
|
||||||
collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
||||||
})
|
})
|
||||||
|
return result.join().modifiedCount
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test delete"() {
|
@Override
|
||||||
setup:
|
int delete(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
def latch1 = new CountDownLatch(1)
|
def latch1 = new CountDownLatch(1)
|
||||||
|
@ -215,38 +117,37 @@ class Mongo4ReactiveClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = new CompletableFuture<DeleteResult>()
|
def result = new CompletableFuture<DeleteResult>()
|
||||||
def count = new CompletableFuture()
|
def count = new CompletableFuture()
|
||||||
collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))).subscribe(toSubscriber {
|
collection.deleteOne(new BsonDocument("password", new BsonString("SECRET"))).subscribe(toSubscriber {
|
||||||
result.complete(it)
|
result.complete(it)
|
||||||
collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
collection.estimatedDocumentCount().subscribe(toSubscriber { count.complete(it) })
|
||||||
})
|
})
|
||||||
|
return result.join().deletedCount
|
||||||
|
}
|
||||||
|
|
||||||
then:
|
@Override
|
||||||
result.get().deletedCount == 1
|
void getMore(String dbName, String collectionName) {
|
||||||
count.get() == 0
|
throw new AssumptionViolatedException("not tested on reactive")
|
||||||
assertTraces(2) {
|
}
|
||||||
trace(0, 1) {
|
|
||||||
mongoSpan(it, 0, "delete", collectionName, dbName) {
|
@Override
|
||||||
assert it.replaceAll(" ", "") == "{\"delete\":\"$collectionName\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}" ||
|
void error(String dbName, String collectionName) {
|
||||||
it == "{\"delete\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"deletes\": [{\"q\": {\"password\": \"?\"}, \"limit\": \"?\"}]}"
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
true
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
}
|
def latch = new CountDownLatch(1)
|
||||||
}
|
db.createCollection(collectionName).subscribe(toSubscriber {
|
||||||
trace(1, 1) {
|
latch.countDown()
|
||||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
})
|
||||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
latch.await()
|
||||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
return db.getCollection(collectionName)
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ignoreTracesAndClear(1)
|
||||||
where:
|
def result = new CompletableFuture<Throwable>()
|
||||||
dbName = "test_db"
|
collection.updateOne(new BsonDocument(), new BsonDocument()).subscribe(toSubscriber {
|
||||||
collectionName = "testCollection"
|
result.complete(it)
|
||||||
|
})
|
||||||
|
throw result.join()
|
||||||
}
|
}
|
||||||
|
|
||||||
def Subscriber<?> toSubscriber(Closure closure) {
|
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
|
* 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 static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
||||||
|
|
||||||
import com.mongodb.MongoTimeoutException
|
|
||||||
import com.mongodb.client.MongoClient
|
import com.mongodb.client.MongoClient
|
||||||
import com.mongodb.client.MongoClients
|
import com.mongodb.client.MongoClients
|
||||||
import com.mongodb.client.MongoCollection
|
import com.mongodb.client.MongoCollection
|
||||||
|
@ -14,110 +12,60 @@ import com.mongodb.client.MongoDatabase
|
||||||
import org.bson.BsonDocument
|
import org.bson.BsonDocument
|
||||||
import org.bson.BsonString
|
import org.bson.BsonString
|
||||||
import org.bson.Document
|
import org.bson.Document
|
||||||
|
import org.junit.AssumptionViolatedException
|
||||||
import spock.lang.Shared
|
import spock.lang.Shared
|
||||||
|
|
||||||
class MongoClientTest extends MongoBaseTest {
|
class MongoClientTest extends AbstractMongoClientTest {
|
||||||
|
|
||||||
@Shared
|
@Shared
|
||||||
MongoClient client
|
MongoClient client
|
||||||
|
|
||||||
def setup() throws Exception {
|
def setupSpec() throws Exception {
|
||||||
client = MongoClients.create("mongodb://localhost:$port")
|
client = MongoClients.create("mongodb://localhost:$port")
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() throws Exception {
|
def cleanupSpec() throws Exception {
|
||||||
client?.close()
|
client?.close()
|
||||||
client = null
|
client = null
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test create collection"() {
|
@Override
|
||||||
setup:
|
void createCollection(String dbName, String collectionName) {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName)
|
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"() {
|
@Override
|
||||||
setup:
|
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||||
MongoDatabase db = MongoClients.create("mongodb://localhost:$port").getDatabase(dbName)
|
MongoDatabase db = MongoClients.create("mongodb://localhost:${port}").getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName)
|
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"() {
|
@Override
|
||||||
setup:
|
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)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
|
return db.getCollection(collectionName).estimatedDocumentCount()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test insert"() {
|
@Override
|
||||||
setup:
|
int insert(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
return db.getCollection(collectionName)
|
return db.getCollection(collectionName)
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
collection.insertOne(new Document("password", "SECRET"))
|
collection.insertOne(new Document("password", "SECRET"))
|
||||||
|
return collection.estimatedDocumentCount()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test update"() {
|
@Override
|
||||||
setup:
|
int update(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
|
@ -126,31 +74,15 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = collection.updateOne(
|
def result = collection.updateOne(
|
||||||
new BsonDocument("password", new BsonString("OLDPW")),
|
new BsonDocument("password", new BsonString("OLDPW")),
|
||||||
new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))))
|
new BsonDocument('$set', new BsonDocument("password", new BsonString("NEWPW"))))
|
||||||
|
collection.estimatedDocumentCount()
|
||||||
then:
|
return result.modifiedCount
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test delete"() {
|
@Override
|
||||||
setup:
|
int delete(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
|
@ -159,65 +91,32 @@ class MongoClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")))
|
def result = collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")))
|
||||||
|
collection.estimatedDocumentCount()
|
||||||
then:
|
return result.deletedCount
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test error"() {
|
@Override
|
||||||
setup:
|
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") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
db.createCollection(collectionName)
|
db.createCollection(collectionName)
|
||||||
return db.getCollection(collectionName)
|
return db.getCollection(collectionName)
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
collection.updateOne(new BsonDocument(), new BsonDocument())
|
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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT
|
|
||||||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
||||||
|
|
||||||
import com.mongodb.ConnectionString
|
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.DeleteResult
|
||||||
import com.mongodb.client.result.UpdateResult
|
import com.mongodb.client.result.UpdateResult
|
||||||
import com.mongodb.connection.ClusterSettings
|
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.CompletableFuture
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import org.bson.BsonDocument
|
import org.bson.BsonDocument
|
||||||
import org.bson.BsonString
|
import org.bson.BsonString
|
||||||
import org.bson.Document
|
import org.bson.Document
|
||||||
|
import org.junit.AssumptionViolatedException
|
||||||
import spock.lang.Shared
|
import spock.lang.Shared
|
||||||
|
|
||||||
class MongoAsyncClientTest extends MongoBaseTest {
|
class MongoAsyncClientTest extends AbstractMongoClientTest {
|
||||||
|
|
||||||
@Shared
|
@Shared
|
||||||
MongoClient client
|
MongoClient client
|
||||||
|
|
||||||
def setup() throws Exception {
|
def setupSpec() throws Exception {
|
||||||
client = MongoClients.create(
|
client = MongoClients.create(
|
||||||
MongoClientSettings.builder()
|
MongoClientSettings.builder()
|
||||||
.clusterSettings(
|
.clusterSettings(
|
||||||
|
@ -42,112 +39,41 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
||||||
.build())
|
.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() throws Exception {
|
def cleanupSpec() throws Exception {
|
||||||
client?.close()
|
client?.close()
|
||||||
client = null
|
client = null
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test create collection"() {
|
@Override
|
||||||
setup:
|
void createCollection(String dbName, String collectionName) {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName, toCallback {})
|
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
|
@Override
|
||||||
// TracingCommandListener might get added multiple times if ClientSettings are built using existing ClientSettings or when calling a build method twice.
|
void createCollectionNoDescription(String dbName, String collectionName) {
|
||||||
// This test asserts that duplicate traces are not created in those cases.
|
MongoDatabase db = MongoClients.create("mongodb://localhost:$port").getDatabase(dbName)
|
||||||
def "test create collection with already built ClientSettings"() {
|
db.createCollection(collectionName, toCallback {})
|
||||||
setup:
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) {
|
||||||
def clientSettings = client.settings
|
def clientSettings = client.settings
|
||||||
def newClientSettings = MongoClientSettings.builder(clientSettings).build()
|
def newClientSettings = MongoClientSettings.builder(clientSettings).build()
|
||||||
MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName)
|
MongoDatabase db = MongoClients.create(newClientSettings).getDatabase(dbName)
|
||||||
|
|
||||||
when:
|
|
||||||
db.createCollection(collectionName, toCallback {})
|
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"() {
|
@Override
|
||||||
setup:
|
int getCollection(String dbName, String collectionName) {
|
||||||
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:
|
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
|
def count = new CompletableFuture<Integer>()
|
||||||
when:
|
|
||||||
def count = new CompletableFuture()
|
|
||||||
db.getCollection(collectionName).count toCallback { count.complete(it) }
|
db.getCollection(collectionName).count toCallback { count.complete(it) }
|
||||||
|
return count.join()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test insert"() {
|
@Override
|
||||||
setup:
|
int insert(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
def latch1 = new CountDownLatch(1)
|
def latch1 = new CountDownLatch(1)
|
||||||
|
@ -156,39 +82,15 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
||||||
return db.getCollection(collectionName)
|
return db.getCollection(collectionName)
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
def count = new CompletableFuture<Integer>()
|
||||||
when:
|
|
||||||
def count = new CompletableFuture()
|
|
||||||
collection.insertOne(new Document("password", "SECRET"), toCallback {
|
collection.insertOne(new Document("password", "SECRET"), toCallback {
|
||||||
collection.count toCallback { count.complete(it) }
|
collection.count toCallback { count.complete(it) }
|
||||||
})
|
})
|
||||||
|
return count.get()
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test update"() {
|
@Override
|
||||||
setup:
|
int update(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
def latch1 = new CountDownLatch(1)
|
def latch1 = new CountDownLatch(1)
|
||||||
|
@ -201,8 +103,6 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = new CompletableFuture<UpdateResult>()
|
def result = new CompletableFuture<UpdateResult>()
|
||||||
def count = new CompletableFuture()
|
def count = new CompletableFuture()
|
||||||
collection.updateOne(
|
collection.updateOne(
|
||||||
|
@ -211,34 +111,11 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
||||||
result.complete(it)
|
result.complete(it)
|
||||||
collection.count toCallback { count.complete(it) }
|
collection.count toCallback { count.complete(it) }
|
||||||
})
|
})
|
||||||
|
return result.get().modifiedCount
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test delete"() {
|
@Override
|
||||||
setup:
|
int delete(String dbName, String collectionName) {
|
||||||
MongoCollection<Document> collection = runUnderTrace("setup") {
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
MongoDatabase db = client.getDatabase(dbName)
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
def latch1 = new CountDownLatch(1)
|
def latch1 = new CountDownLatch(1)
|
||||||
|
@ -251,38 +128,37 @@ class MongoAsyncClientTest extends MongoBaseTest {
|
||||||
return coll
|
return coll
|
||||||
}
|
}
|
||||||
ignoreTracesAndClear(1)
|
ignoreTracesAndClear(1)
|
||||||
|
|
||||||
when:
|
|
||||||
def result = new CompletableFuture<DeleteResult>()
|
def result = new CompletableFuture<DeleteResult>()
|
||||||
def count = new CompletableFuture()
|
def count = new CompletableFuture()
|
||||||
collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")), toCallback {
|
collection.deleteOne(new BsonDocument("password", new BsonString("SECRET")), toCallback {
|
||||||
result.complete(it)
|
result.complete(it)
|
||||||
collection.count toCallback { count.complete(it) }
|
collection.count toCallback { count.complete(it) }
|
||||||
})
|
})
|
||||||
|
return result.get().deletedCount
|
||||||
|
}
|
||||||
|
|
||||||
then:
|
@Override
|
||||||
result.get().deletedCount == 1
|
void getMore(String dbName, String collectionName) {
|
||||||
count.get() == 0
|
throw new AssumptionViolatedException("not tested on async")
|
||||||
assertTraces(2) {
|
}
|
||||||
trace(0, 1) {
|
|
||||||
mongoSpan(it, 0, "delete", collectionName, dbName) {
|
@Override
|
||||||
assert it.replaceAll(" ", "") == "{\"delete\":\"$collectionName\",\"ordered\":\"?\",\"deletes\":[{\"q\":{\"password\":\"?\"},\"limit\":\"?\"}]}" ||
|
void error(String dbName, String collectionName) {
|
||||||
it == "{\"delete\": \"?\", \"ordered\": \"?\", \"\$db\": \"?\", \"deletes\": [{\"q\": {\"password\": \"?\"}, \"limit\": \"?\"}]}"
|
MongoCollection<Document> collection = runUnderTrace("setup") {
|
||||||
true
|
MongoDatabase db = client.getDatabase(dbName)
|
||||||
}
|
def latch = new CountDownLatch(1)
|
||||||
}
|
db.createCollection(collectionName, toCallback {
|
||||||
trace(1, 1) {
|
latch.countDown()
|
||||||
mongoSpan(it, 0, "count", collectionName, dbName) {
|
})
|
||||||
assert it.replaceAll(" ", "") == "{\"count\":\"$collectionName\",\"query\":{}}" ||
|
latch.await()
|
||||||
it == "{\"count\": \"$collectionName\", \"query\": {}, \"\$db\": \"?\", \"\$readPreference\": {\"mode\": \"?\"}}"
|
return db.getCollection(collectionName)
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ignoreTracesAndClear(1)
|
||||||
where:
|
def result = new CompletableFuture<Throwable>()
|
||||||
dbName = "test_db"
|
collection.updateOne(new BsonDocument(), new BsonDocument(), toCallback {
|
||||||
collectionName = "testCollection"
|
result.complete(it)
|
||||||
|
})
|
||||||
|
throw result.join()
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleResultCallback toCallback(Closure closure) {
|
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 {
|
dependencies {
|
||||||
api project(':testing-common')
|
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.groovy
|
||||||
implementation deps.opentelemetryApi
|
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