Skip to content

Commit ce891eb

Browse files
committed
test: bind peer service checks to their operation spans
Delayed setup traces can carry the same peer-service tags as the operation under test, allowing the shared matcher to pass without observing that operation. Run each generator under a unique parent and match its child span instead. Generator throws and invalid return values can bypass assertion cleanup. Keep the whole operation inside the cleanup boundary so the original failure is not replaced by a leaked-expectation teardown error.
1 parent 75d7079 commit ce891eb

1 file changed

Lines changed: 35 additions & 24 deletions

File tree

packages/dd-trace/test/setup/mocha.js

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -208,37 +208,48 @@ function withPeerService (tracer, pluginName, spanGenerationFn, service, service
208208

209209
it('should compute peer service', async () => {
210210
const { expectSomeSpan } = require('../plugins/helpers')
211-
const traceAssertion = expectSomeSpan(getAgent(), {
212-
meta: {
213-
'peer.service': typeof service === 'function' ? service() : service,
214-
'_dd.peer.service.source': serviceSource,
215-
},
216-
})
217-
const useCallback = spanGenerationFn.length === 1
218-
const spanGenerationPromise = useCallback
219-
? new Promise(/** @type {() => void} */ (resolve, reject) => {
220-
const result = spanGenerationFn((err) => err ? reject(err) : resolve())
221-
// Some callback based methods are a mixture of callback and promise,
222-
// depending on the module version. Await the promises as well.
223-
if (util.types.isPromise(result)) {
224-
result.then?.(resolve, reject)
225-
}
211+
const currentTracer = global._ddtrace
212+
const parentSpan = currentTracer.startSpan('peer-service.test')
213+
let traceAssertion
214+
215+
try {
216+
traceAssertion = expectSomeSpan(getAgent(), {
217+
parent_id: BigInt(parentSpan.context().toSpanId()),
218+
meta: {
219+
'peer.service': typeof service === 'function' ? service() : service,
220+
'_dd.peer.service.source': serviceSource,
221+
},
222+
})
223+
const useCallback = spanGenerationFn.length === 1
224+
const spanGenerationPromise = currentTracer.scope().activate(parentSpan, () => {
225+
return useCallback
226+
? new Promise(/** @type {() => void} */ (resolve, reject) => {
227+
const result = spanGenerationFn((error) => error ? reject(error) : resolve())
228+
// Some callback based methods are a mixture of callback and promise,
229+
// depending on the module version. Await the promises as well.
230+
if (util.types.isPromise(result)) {
231+
result.then?.(resolve, reject)
232+
}
233+
})
234+
: spanGenerationFn()
226235
})
227-
: spanGenerationFn()
228236

229-
assert.strictEqual(
230-
typeof spanGenerationPromise?.then, 'function',
231-
'spanGenerationFn should return a promise in case no callback is defined. Received: ' +
232-
util.inspect(spanGenerationPromise, { depth: 1 }),
233-
)
237+
assert.strictEqual(
238+
typeof spanGenerationPromise?.then, 'function',
239+
'spanGenerationFn should return a promise in case no callback is defined. Received: ' +
240+
util.inspect(spanGenerationPromise, { depth: 1 }),
241+
)
234242

235-
try {
236243
await Promise.all([
237244
traceAssertion,
238-
spanGenerationPromise,
245+
(async () => {
246+
await spanGenerationPromise
247+
parentSpan.finish()
248+
})(),
239249
])
240250
} finally {
241-
traceAssertion.cancel()
251+
parentSpan.finish()
252+
traceAssertion?.cancel()
242253
}
243254
})
244255
})

0 commit comments

Comments
 (0)