Skip to content

Commit 48e9f2d

Browse files
committed
test: cover uncovered diff lines from the unicorn v65 rewrite
The unicorn autofix touched branches no existing spec exercised: 1. ws: a connection carrying x-forwarded-proto now asserts the server span's http.url resolves to wss, reaching getRequestProtocol's proxy arm (and the getSegment call inside it). 2. oracledb: a callback-form pool.getConnection pins the callback path, which only the promise form covered before. 3. ai-sdk: generateObject/generateText driven by messages (no top-level prompt) reach the `messages.findLast(...)` arm that prompt short-circuits. The ai-sdk cases need a VCR cassette recorded against a real OPENAI_API_KEY before they pass in replay-only CI.
1 parent 2e26796 commit 48e9f2d

3 files changed

Lines changed: 108 additions & 0 deletions

File tree

packages/datadog-plugin-oracledb/test/index.spec.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,31 @@ describe('Plugin', () => {
256256
assert.strictEqual(tracer.scope().active(), null)
257257
})
258258

259+
it('should instrument pool.getConnection with a callback', async () => {
260+
const callbackConnection = await new Promise((resolve, reject) => {
261+
pool.getConnection((error, conn) => error ? reject(error) : resolve(conn))
262+
})
263+
264+
try {
265+
await Promise.all([
266+
agent.assertFirstTraceSpan({
267+
name: expectedSchema.outbound.opName,
268+
service: expectedSchema.outbound.serviceName,
269+
resource: dbQuery,
270+
type: 'sql',
271+
meta: {
272+
'span.kind': 'client',
273+
component: 'oracledb',
274+
'db.instance': dbInstance,
275+
},
276+
}),
277+
callbackConnection.execute(dbQuery),
278+
])
279+
} finally {
280+
await callbackConnection.close()
281+
}
282+
})
283+
259284
it('should instrument errors', async () => {
260285
try {
261286
await connection.execute('invalid')

packages/datadog-plugin-ws/test/index.spec.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,20 @@ describe('Plugin', () => {
248248
client.on('error', done)
249249
})
250250

251+
it('should derive the wss protocol from the x-forwarded-proto header', () => {
252+
wsServer.on('connection', (ws) => {
253+
ws.send('echo')
254+
})
255+
256+
connectClient(`/${route}?active=true`, { headers: { 'x-forwarded-proto': 'https' } })
257+
258+
return agent.assertSomeTraces(traces => {
259+
const span = findSpan(traces, s => s.name === 'web.request' && s.type === 'websocket')
260+
assert.ok(span, 'Should have a web.request websocket span')
261+
assert.match(span.meta['http.url'], /^wss:\/\//)
262+
})
263+
})
264+
251265
it('should instrument message sending once per message', () => {
252266
wsServer.on('connection', ws => {
253267
connectionReceived = true

packages/dd-trace/test/llmobs/plugins/ai/index.spec.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,75 @@ describe('Plugin', () => {
225225
})
226226
})
227227

228+
it('creates a span for generateText from messages without a prompt', async () => {
229+
const options = {
230+
model: openai('gpt-4o-mini'),
231+
messages: [
232+
{ role: 'user', content: 'Hello, OpenAI!' },
233+
{ role: 'assistant', content: 'Hi! How can I help?' },
234+
{ role: 'user', content: 'What is the capital of France?' },
235+
],
236+
experimental_telemetry: {
237+
metadata: MOCK_TELEMETRY_METADATA,
238+
},
239+
}
240+
if (semifies(realVersion, '>=5.0.0')) {
241+
options.maxOutputTokens = 100
242+
} else {
243+
options.maxTokens = 100
244+
}
245+
246+
await ai.generateText(options)
247+
248+
const { apmSpans, llmobsSpans } = await getEvents()
249+
250+
assertLlmObsSpanEvent(llmobsSpans[0], {
251+
span: apmSpans[0],
252+
name: 'generateText',
253+
spanKind: 'workflow',
254+
inputValue: 'What is the capital of France?',
255+
outputValue: MOCK_STRING,
256+
tags: { ml_app: 'test', integration: 'ai' },
257+
})
258+
})
259+
260+
it('creates a span for generateObject from messages without a prompt', async () => {
261+
const schema = ai.jsonSchema({
262+
type: 'object',
263+
properties: {
264+
name: { type: 'string' },
265+
age: { type: 'number' },
266+
height: { type: 'string' },
267+
},
268+
required: ['name', 'age', 'height'],
269+
additionalProperties: false,
270+
})
271+
272+
await ai.generateObject({
273+
model: openai('gpt-4o-mini'),
274+
schema,
275+
messages: [
276+
{ role: 'user', content: 'Invent a character' },
277+
{ role: 'assistant', content: 'Sure, here is one.' },
278+
{ role: 'user', content: 'Invent a character for a video game' },
279+
],
280+
experimental_telemetry: {
281+
metadata: MOCK_TELEMETRY_METADATA,
282+
},
283+
})
284+
285+
const { apmSpans, llmobsSpans } = await getEvents()
286+
287+
assertLlmObsSpanEvent(llmobsSpans[0], {
288+
span: apmSpans[0],
289+
name: 'generateObject',
290+
spanKind: 'workflow',
291+
inputValue: 'Invent a character for a video game',
292+
outputValue: MOCK_STRING,
293+
tags: { ml_app: 'test', integration: 'ai' },
294+
})
295+
})
296+
228297
it('creates a span for embed', async () => {
229298
await ai.embed({
230299
model: openai.embedding('text-embedding-ada-002'),

0 commit comments

Comments
 (0)