Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion integration-tests/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,8 @@ async function spawnPluginIntegrationTestProc (cwd, serverFile, agentPort, stdio
env = { ...process.env, ...env, ...additionalEnvArgs }
return spawnProc(path.join(cwd, serverFile), {
cwd,
env
env,
execArgv: additionalEnvArgs.execArgv
}, stdioHandler)
}

Expand Down
6 changes: 5 additions & 1 deletion packages/datadog-instrumentations/src/aws-sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
const { channel, addHook } = require('./helpers/instrument')
const shimmer = require('../../datadog-shimmer')

const patchedClientConfigProtocols = new WeakSet()

function wrapRequest (send) {
return function wrappedRequest (cb) {
if (!this.service) return send.apply(this, arguments)
Expand Down Expand Up @@ -67,12 +69,14 @@ function wrapSmithySend (send) {

if (typeof command.deserialize === 'function') {
shimmer.wrap(command, 'deserialize', deserialize => wrapDeserialize(deserialize, channelSuffix))
} else if (this.config?.protocol?.deserializeResponse) {
} else if (this.config?.protocol?.deserializeResponse && !patchedClientConfigProtocols.has(this.config.protocol)) {
shimmer.wrap(
this.config.protocol,
'deserializeResponse',
deserializeResponse => wrapDeserialize(deserializeResponse, channelSuffix, 2)
)

patchedClientConfigProtocols.add(this.config.protocol)
}

const ctx = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'dd-trace/init.js'
import {
SQSClient,
CreateQueueCommand,
ReceiveMessageCommand,
} from '@aws-sdk/client-sqs'

const client = new SQSClient({ endpoint: 'http://127.0.0.1:4566', region: 'us-east-1' })

// Create queue first
const createRes = await client.send(new CreateQueueCommand({ QueueName: 'test-queue' }))
const queueUrl = createRes.QueueUrl

// Send many receive message commands to trigger recursion
for (let i = 0; i < 500; i++) {
client.send(new ReceiveMessageCommand({ QueueUrl: queueUrl, MessageAttributeNames: ['.*'] }))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict'

const {
FakeAgent,
sandboxCwd,
useSandbox,
checkSpansForServiceName,
spawnPluginIntegrationTestProc
} = require('../../../../integration-tests/helpers')
const { withVersions } = require('../../../dd-trace/test/setup/mocha')

const assert = require('node:assert')

describe('recursion regression test', () => {
let agent
let proc

withVersions('aws-sdk', ['@aws-sdk/smithy-client'], version => {
useSandbox([`'@aws-sdk/client-sqs'@${version}'`], false, [
'./packages/datadog-plugin-aws-sdk/test/integration-test/*'])

beforeEach(async () => {
agent = await new FakeAgent().start()
})

afterEach(async () => {
proc && proc.kill()
await agent.stop()
})

it('does not cause a recursion error when many commands are sent', async () => {
const res = agent.assertMessageReceived(({ headers, payload }) => {
assert.equal(headers.host, `127.0.0.1:${agent.port}`)
assert.ok(Array.isArray(payload))
assert.strictEqual(checkSpansForServiceName(payload, 'aws.request'), true)
})

proc = await spawnPluginIntegrationTestProc(sandboxCwd(), 'recursion.mjs', agent.port, undefined,
{
AWS_SECRET_ACCESS_KEY: '0000000000/00000000000000000000000000000',
AWS_ACCESS_KEY_ID: '00000000000000000000',
execArgv: ['--stack-size=128']
}
)

await res
}).timeout(20000)
})
})