11import static datadog.trace.agent.test.utils.TraceUtils.basicSpan
2+ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan
23
34import com.mongodb.ConnectionString
45import com.mongodb.client.MongoClient
56import com.mongodb.client.MongoClients
67import com.mongodb.MongoClientSettings
8+ import com.mongodb.client.MongoCollection
9+ import com.mongodb.client.MongoDatabase
710import com.mongodb.event.CommandListener
811import com.mongodb.event.CommandStartedEvent
12+ import com.mongodb.internal.build.MongoDriverVersion
913import datadog.trace.api.config.TraceInstrumentationConfig
14+ import datadog.trace.core.DDSpan
1015import org.bson.BsonDocument
16+ import org.bson.BsonString
17+ import org.bson.Document
18+ import org.spockframework.util.VersionNumber
1119import spock.lang.Shared
1220import static datadog.trace.api.Config.DBM_PROPAGATION_MODE_FULL
1321
@@ -43,6 +51,16 @@ abstract class DefaultServerConnection40InstrumentationTest extends MongoBaseTes
4351 commandListener. commands. clear()
4452 client = null
4553 }
54+
55+ @Shared
56+ String query = {
57+ def version = VersionNumber . parse(MongoDriverVersion . VERSION )
58+ if (version. major == 4 && version. minor < 3 ) {
59+ // query is returned for versions < 4.3
60+ return ' ,"query":{}'
61+ }
62+ return ' '
63+ }. call()
4664}
4765
4866abstract class DefaultServerConnection40InstrumentationEnabledTest extends DefaultServerConnection40InstrumentationTest {
@@ -85,6 +103,104 @@ abstract class DefaultServerConnection40InstrumentationEnabledTest extends Defau
85103 commentStr. contains(" ddh='" )
86104 commentStr. contains(" traceparent='" )
87105 }
106+
107+ def " test insert comment injection" () {
108+ setup :
109+ String collectionName = randomCollectionName()
110+ DDSpan setupSpan = null
111+ MongoCollection<Document > collection = runUnderTrace(" setup" ) {
112+ setupSpan = activeSpan() as DDSpan
113+ MongoDatabase db = client. getDatabase(databaseName)
114+ db. createCollection(collectionName)
115+ return db. getCollection(collectionName)
116+ }
117+ TEST_WRITER . waitUntilReported(setupSpan)
118+ TEST_WRITER . clear()
119+
120+ when :
121+ collection. insertOne(new Document (" password" , " SECRET" ))
122+ def estimatedCount = collection. estimatedDocumentCount()
123+ TEST_WRITER . waitForTraces(2 )
124+
125+ then :
126+ estimatedCount == 1
127+ assertTraces(2 ) {
128+ trace(1 ) {
129+ mongoSpan(it, 0 , " insert" , " {\" insert\" :\" $collectionName \" ,\" ordered\" :true,\" comment\" :\" ?\" ,\" documents\" :[]}" , false , " some-description" , null , true )
130+ }
131+ trace(1 ) {
132+ mongoSpan(it, 0 , " count" , " {\" count\" :\" $collectionName \" $query ,\" comment\" :\" ?\" }" , false , " some-description" , null , true )
133+ }
134+ }
135+ }
136+
137+ def " test update comment injection" () {
138+ setup :
139+ String collectionName = randomCollectionName()
140+ DDSpan setupSpan = null
141+ MongoCollection<Document > collection = runUnderTrace(" setup" ) {
142+ setupSpan = activeSpan() as DDSpan
143+ MongoDatabase db = client. getDatabase(databaseName)
144+ db. createCollection(collectionName)
145+ def coll = db. getCollection(collectionName)
146+ coll. insertOne(new Document (" password" , " OLDPW" ))
147+ return coll
148+ }
149+ TEST_WRITER . waitUntilReported(setupSpan)
150+ TEST_WRITER . clear()
151+
152+ when :
153+ def result = collection. updateOne(
154+ new BsonDocument (" password" , new BsonString (" OLDPW" )),
155+ new BsonDocument (' $set' , new BsonDocument (" password" , new BsonString (" NEWPW" ))))
156+ def estimatedCount = collection. estimatedDocumentCount()
157+ TEST_WRITER . waitForTraces(2 )
158+
159+ then :
160+ result. modifiedCount == 1
161+ estimatedCount == 1
162+ assertTraces(2 ) {
163+ trace(1 ) {
164+ mongoSpan(it, 0 , " update" , " {\" update\" :\" $collectionName \" ,\" ordered\" :true,\" comment\" :\" ?\" ,\" updates\" :[]}" , false , " some-description" , null , true )
165+ }
166+ trace(1 ) {
167+ mongoSpan(it, 0 , " count" , " {\" count\" :\" $collectionName \" $query ,\" comment\" :\" ?\" }" , false , " some-description" , null , true )
168+ }
169+ }
170+ }
171+
172+ def " test delete comment injection" () {
173+ setup :
174+ String collectionName = randomCollectionName()
175+ DDSpan setupSpan = null
176+ MongoCollection<Document > collection = runUnderTrace(" setup" ) {
177+ setupSpan = activeSpan() as DDSpan
178+ MongoDatabase db = client. getDatabase(databaseName)
179+ db. createCollection(collectionName)
180+ def coll = db. getCollection(collectionName)
181+ coll. insertOne(new Document (" password" , " SECRET" ))
182+ return coll
183+ }
184+ TEST_WRITER . waitUntilReported(setupSpan)
185+ TEST_WRITER . clear()
186+
187+ when :
188+ def result = collection. deleteOne(new BsonDocument (" password" , new BsonString (" SECRET" )))
189+ def estimatedCount = collection. estimatedDocumentCount()
190+ TEST_WRITER . waitForTraces(2 )
191+
192+ then :
193+ result. deletedCount == 1
194+ estimatedCount == 0
195+ assertTraces(2 ) {
196+ trace(1 ) {
197+ mongoSpan(it, 0 , " delete" , " {\" delete\" :\" $collectionName \" ,\" ordered\" :true,\" comment\" :\" ?\" ,\" deletes\" :[]}" , false , " some-description" , null , true )
198+ }
199+ trace(1 ) {
200+ mongoSpan(it, 0 , " count" , " {\" count\" :\" $collectionName \" $query ,\" comment\" :\" ?\" }" , false , " some-description" , null , true )
201+ }
202+ }
203+ }
88204}
89205
90206abstract class DefaultServerConnection40InstrumentationDisabledTest extends DefaultServerConnection40InstrumentationTest {
@@ -110,6 +226,104 @@ abstract class DefaultServerConnection40InstrumentationDisabledTest extends Defa
110226 createCommand != null
111227 ! createCommand. containsKey(" comment" )
112228 }
229+
230+ def " test insert comment not injected when disabled" () {
231+ setup :
232+ String collectionName = randomCollectionName()
233+ DDSpan setupSpan = null
234+ MongoCollection<Document > collection = runUnderTrace(" setup" ) {
235+ setupSpan = activeSpan() as DDSpan
236+ MongoDatabase db = client. getDatabase(databaseName)
237+ db. createCollection(collectionName)
238+ return db. getCollection(collectionName)
239+ }
240+ TEST_WRITER . waitUntilReported(setupSpan)
241+ TEST_WRITER . clear()
242+
243+ when :
244+ collection. insertOne(new Document (" password" , " SECRET" ))
245+ def estimatedCount = collection. estimatedDocumentCount()
246+ TEST_WRITER . waitForTraces(2 )
247+
248+ then :
249+ estimatedCount == 1
250+ assertTraces(2 ) {
251+ trace(1 ) {
252+ mongoSpan(it, 0 , " insert" , " {\" insert\" :\" $collectionName \" ,\" ordered\" :true,\" documents\" :[]}" )
253+ }
254+ trace(1 ) {
255+ mongoSpan(it, 0 , " count" , " {\" count\" :\" $collectionName \" $query }" )
256+ }
257+ }
258+ }
259+
260+ def " test update comment not injected when disabled" () {
261+ setup :
262+ String collectionName = randomCollectionName()
263+ DDSpan setupSpan = null
264+ MongoCollection<Document > collection = runUnderTrace(" setup" ) {
265+ setupSpan = activeSpan() as DDSpan
266+ MongoDatabase db = client. getDatabase(databaseName)
267+ db. createCollection(collectionName)
268+ def coll = db. getCollection(collectionName)
269+ coll. insertOne(new Document (" password" , " OLDPW" ))
270+ return coll
271+ }
272+ TEST_WRITER . waitUntilReported(setupSpan)
273+ TEST_WRITER . clear()
274+
275+ when :
276+ def result = collection. updateOne(
277+ new BsonDocument (" password" , new BsonString (" OLDPW" )),
278+ new BsonDocument (' $set' , new BsonDocument (" password" , new BsonString (" NEWPW" ))))
279+ def estimatedCount = collection. estimatedDocumentCount()
280+ TEST_WRITER . waitForTraces(2 )
281+
282+ then :
283+ result. modifiedCount == 1
284+ estimatedCount == 1
285+ assertTraces(2 ) {
286+ trace(1 ) {
287+ mongoSpan(it, 0 , " update" , " {\" update\" :\" $collectionName \" ,\" ordered\" :true,\" updates\" :[]}" )
288+ }
289+ trace(1 ) {
290+ mongoSpan(it, 0 , " count" , " {\" count\" :\" $collectionName \" $query }" )
291+ }
292+ }
293+ }
294+
295+ def " test delete comment not injected when disabled" () {
296+ setup :
297+ String collectionName = randomCollectionName()
298+ DDSpan setupSpan = null
299+ MongoCollection<Document > collection = runUnderTrace(" setup" ) {
300+ setupSpan = activeSpan() as DDSpan
301+ MongoDatabase db = client. getDatabase(databaseName)
302+ db. createCollection(collectionName)
303+ def coll = db. getCollection(collectionName)
304+ coll. insertOne(new Document (" password" , " SECRET" ))
305+ return coll
306+ }
307+ TEST_WRITER . waitUntilReported(setupSpan)
308+ TEST_WRITER . clear()
309+
310+ when :
311+ def result = collection. deleteOne(new BsonDocument (" password" , new BsonString (" SECRET" )))
312+ def estimatedCount = collection. estimatedDocumentCount()
313+ TEST_WRITER . waitForTraces(2 )
314+
315+ then :
316+ result. deletedCount == 1
317+ estimatedCount == 0
318+ assertTraces(2 ) {
319+ trace(1 ) {
320+ mongoSpan(it, 0 , " delete" , " {\" delete\" :\" $collectionName \" ,\" ordered\" :true,\" deletes\" :[]}" )
321+ }
322+ trace(1 ) {
323+ mongoSpan(it, 0 , " count" , " {\" count\" :\" $collectionName \" $query }" )
324+ }
325+ }
326+ }
113327}
114328
115329// Test class with DBM propagation enabled by default
0 commit comments