dd-trace 5.101.0 → 5.102.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/package.json +9 -7
  2. package/packages/datadog-instrumentations/src/aerospike.js +2 -2
  3. package/packages/datadog-instrumentations/src/ai.js +8 -8
  4. package/packages/datadog-instrumentations/src/amqplib.js +6 -7
  5. package/packages/datadog-instrumentations/src/anthropic.js +10 -10
  6. package/packages/datadog-instrumentations/src/apollo-server-core.js +3 -3
  7. package/packages/datadog-instrumentations/src/apollo-server.js +5 -5
  8. package/packages/datadog-instrumentations/src/avsc.js +6 -6
  9. package/packages/datadog-instrumentations/src/aws-sdk.js +151 -67
  10. package/packages/datadog-instrumentations/src/azure-durable-functions.js +8 -8
  11. package/packages/datadog-instrumentations/src/bluebird.js +2 -2
  12. package/packages/datadog-instrumentations/src/body-parser.js +2 -2
  13. package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
  14. package/packages/datadog-instrumentations/src/child_process.js +12 -12
  15. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +9 -9
  16. package/packages/datadog-instrumentations/src/connect.js +7 -7
  17. package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
  18. package/packages/datadog-instrumentations/src/cookie.js +2 -2
  19. package/packages/datadog-instrumentations/src/couchbase.js +16 -30
  20. package/packages/datadog-instrumentations/src/crypto.js +4 -4
  21. package/packages/datadog-instrumentations/src/cucumber.js +77 -16
  22. package/packages/datadog-instrumentations/src/dns.js +0 -3
  23. package/packages/datadog-instrumentations/src/elasticsearch.js +8 -11
  24. package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +6 -6
  25. package/packages/datadog-instrumentations/src/express-session.js +4 -4
  26. package/packages/datadog-instrumentations/src/express.js +10 -11
  27. package/packages/datadog-instrumentations/src/fastify.js +2 -2
  28. package/packages/datadog-instrumentations/src/fs.js +14 -14
  29. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +5 -7
  30. package/packages/datadog-instrumentations/src/google-genai.js +4 -4
  31. package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
  32. package/packages/datadog-instrumentations/src/hapi.js +2 -2
  33. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +8 -8
  34. package/packages/datadog-instrumentations/src/helpers/promise.js +2 -2
  35. package/packages/datadog-instrumentations/src/hono.js +2 -2
  36. package/packages/datadog-instrumentations/src/http/client.js +6 -6
  37. package/packages/datadog-instrumentations/src/http/server.js +9 -9
  38. package/packages/datadog-instrumentations/src/jest.js +31 -31
  39. package/packages/datadog-instrumentations/src/kafkajs.js +9 -9
  40. package/packages/datadog-instrumentations/src/knex.js +17 -17
  41. package/packages/datadog-instrumentations/src/koa.js +12 -12
  42. package/packages/datadog-instrumentations/src/ldapjs.js +5 -5
  43. package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
  44. package/packages/datadog-instrumentations/src/limitd-client.js +4 -4
  45. package/packages/datadog-instrumentations/src/lodash.js +4 -4
  46. package/packages/datadog-instrumentations/src/mariadb.js +13 -13
  47. package/packages/datadog-instrumentations/src/memcached.js +2 -2
  48. package/packages/datadog-instrumentations/src/microgateway-core.js +2 -2
  49. package/packages/datadog-instrumentations/src/mocha/common.js +3 -3
  50. package/packages/datadog-instrumentations/src/mocha/main.js +12 -10
  51. package/packages/datadog-instrumentations/src/mocha/utils.js +133 -16
  52. package/packages/datadog-instrumentations/src/mocha/worker.js +7 -5
  53. package/packages/datadog-instrumentations/src/mongodb-core.js +9 -22
  54. package/packages/datadog-instrumentations/src/mongodb.js +5 -5
  55. package/packages/datadog-instrumentations/src/mongoose.js +21 -21
  56. package/packages/datadog-instrumentations/src/mquery.js +5 -5
  57. package/packages/datadog-instrumentations/src/multer.js +4 -4
  58. package/packages/datadog-instrumentations/src/mysql.js +16 -16
  59. package/packages/datadog-instrumentations/src/mysql2.js +4 -4
  60. package/packages/datadog-instrumentations/src/net.js +14 -8
  61. package/packages/datadog-instrumentations/src/nyc.js +5 -5
  62. package/packages/datadog-instrumentations/src/openai.js +19 -19
  63. package/packages/datadog-instrumentations/src/oracledb.js +6 -6
  64. package/packages/datadog-instrumentations/src/passport-utils.js +5 -5
  65. package/packages/datadog-instrumentations/src/pg.js +15 -15
  66. package/packages/datadog-instrumentations/src/pino.js +6 -10
  67. package/packages/datadog-instrumentations/src/playwright.js +20 -15
  68. package/packages/datadog-instrumentations/src/protobufjs.js +16 -16
  69. package/packages/datadog-instrumentations/src/redis.js +1 -2
  70. package/packages/datadog-instrumentations/src/restify.js +2 -2
  71. package/packages/datadog-instrumentations/src/router.js +12 -12
  72. package/packages/datadog-instrumentations/src/stripe.js +12 -12
  73. package/packages/datadog-instrumentations/src/vitest.js +107 -26
  74. package/packages/datadog-instrumentations/src/winston.js +4 -4
  75. package/packages/datadog-instrumentations/src/ws.js +7 -7
  76. package/packages/datadog-plugin-aws-sdk/src/base.js +52 -4
  77. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +19 -12
  78. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +45 -35
  79. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +33 -22
  80. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +12 -13
  81. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +73 -54
  82. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +19 -17
  83. package/packages/datadog-plugin-aws-sdk/src/util.js +22 -0
  84. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -6
  85. package/packages/datadog-plugin-cucumber/src/index.js +4 -0
  86. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +1 -4
  87. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -5
  88. package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +3 -1
  89. package/packages/datadog-plugin-http/src/client.js +1 -5
  90. package/packages/datadog-plugin-jest/src/util.js +1 -2
  91. package/packages/datadog-plugin-mocha/src/index.js +4 -0
  92. package/packages/datadog-plugin-mongodb-core/src/index.js +2 -1
  93. package/packages/datadog-plugin-openai/src/tracing.js +12 -23
  94. package/packages/datadog-plugin-playwright/src/index.js +1 -1
  95. package/packages/datadog-plugin-vitest/src/index.js +8 -1
  96. package/packages/datadog-shimmer/src/shimmer.js +7 -1
  97. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
  98. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +81 -81
  99. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
  100. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
  101. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -2
  102. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
  103. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
  104. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
  105. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +83 -48
  106. package/packages/dd-trace/src/appsec/index.js +21 -24
  107. package/packages/dd-trace/src/appsec/reporter.js +3 -1
  108. package/packages/dd-trace/src/appsec/rule_manager.js +4 -2
  109. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +31 -16
  110. package/packages/dd-trace/src/config/git_properties.js +2 -2
  111. package/packages/dd-trace/src/datastreams/index.js +2 -1
  112. package/packages/dd-trace/src/datastreams/processor.js +1 -2
  113. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +1 -0
  114. package/packages/dd-trace/src/encode/0.4.js +757 -232
  115. package/packages/dd-trace/src/encode/0.5.js +13 -7
  116. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -2
  117. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +6 -3
  118. package/packages/dd-trace/src/llmobs/sdk.js +24 -26
  119. package/packages/dd-trace/src/llmobs/span_processor.js +25 -5
  120. package/packages/dd-trace/src/llmobs/util.js +1 -0
  121. package/packages/dd-trace/src/msgpack/chunk.js +6 -3
  122. package/packages/dd-trace/src/openfeature/noop.js +40 -36
  123. package/packages/dd-trace/src/openfeature/writers/exposures.js +33 -52
  124. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +1 -2
  125. package/packages/dd-trace/src/opentelemetry/tracer.js +0 -22
  126. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -11
  127. package/packages/dd-trace/src/plugins/util/ci.js +1 -1
  128. package/packages/dd-trace/src/plugins/util/git-cache.js +3 -5
  129. package/packages/dd-trace/src/plugins/util/test.js +19 -7
  130. package/packages/dd-trace/src/plugins/util/url.js +1 -3
  131. package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -1
  132. package/packages/dd-trace/src/plugins/util/web.js +5 -7
  133. package/packages/dd-trace/src/profiling/profilers/events.js +3 -23
  134. package/packages/dd-trace/src/profiling/profilers/wall.js +4 -5
  135. package/packages/dd-trace/src/runtime_metrics/index.js +2 -2
  136. package/packages/dd-trace/src/scope.js +3 -10
  137. package/packages/dd-trace/src/serverless.js +1 -4
  138. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +7 -1
  139. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +4 -0
  140. package/packages/dd-trace/src/tracer.js +7 -7
@@ -1,11 +1,15 @@
1
1
  'use strict'
2
2
 
3
+ const { performance } = require('node:perf_hooks')
4
+
3
5
  // Capture real timers at module load time, before any test can install fake timers.
4
6
  const realSetTimeout = setTimeout
5
7
 
6
8
  const {
7
9
  getTestSuitePath,
8
10
  DYNAMIC_NAME_RE,
11
+ getEfdRetryCount,
12
+ getMaxEfdRetryCount,
9
13
  recordAttemptToFixExecution,
10
14
  logAttemptToFixTestExecution,
11
15
  } = require('../../../dd-trace/src/plugins/util/test')
@@ -35,6 +39,8 @@ const newTestsWithDynamicNames = new Set()
35
39
  const testsAttemptToFix = new Set()
36
40
  const testsQuarantined = new Set()
37
41
  const testsStatuses = new Map()
42
+ const efdRetryCountByTestFullName = new Map()
43
+ const efdSlowAbortedTests = new Set()
38
44
  const attemptToFixExecutions = new Map()
39
45
  const loggedAttemptToFixTests = new Set()
40
46
 
@@ -70,11 +76,82 @@ function isNewTest (test, knownTests) {
70
76
  return !testsForSuite.includes(testName)
71
77
  }
72
78
 
73
- function retryTest (test, numRetries, tags) {
79
+ function setEfdRetryCountForTest (test, duration, slowTestRetries) {
80
+ const testName = getTestFullName(test)
81
+ if (efdRetryCountByTestFullName.has(testName)) {
82
+ return
83
+ }
84
+ const retryCount = getEfdRetryCount(duration, slowTestRetries || {})
85
+ efdRetryCountByTestFullName.set(testName, retryCount)
86
+ if (retryCount === 0) {
87
+ efdSlowAbortedTests.add(testName)
88
+ }
89
+ }
90
+
91
+ function wrapOriginalEfdTest (test, slowTestRetries) {
92
+ if (test._ddEfdDurationWrapped || typeof test.fn !== 'function') {
93
+ return
94
+ }
95
+ test._ddEfdDurationWrapped = true
96
+ const originalFn = test.fn
97
+ test.fn = shimmer.wrapFunction(originalFn, originalFn => function () {
98
+ const start = performance.now()
99
+ const recordDuration = () => {
100
+ setEfdRetryCountForTest(test, performance.now() - start, slowTestRetries)
101
+ }
102
+
103
+ if (originalFn.length > 0) {
104
+ const args = Array.prototype.slice.call(arguments)
105
+ args[0] = shimmer.wrapFunction(args[0], done => function (...args) {
106
+ recordDuration()
107
+ return done.apply(this, args)
108
+ })
109
+ return originalFn.apply(this, args)
110
+ }
111
+
112
+ try {
113
+ const result = originalFn.apply(this, arguments)
114
+ if (result?.then) {
115
+ return result.then(value => {
116
+ recordDuration()
117
+ return value
118
+ }, error => {
119
+ recordDuration()
120
+ throw error
121
+ })
122
+ }
123
+ recordDuration()
124
+ return result
125
+ } catch (error) {
126
+ recordDuration()
127
+ throw error
128
+ }
129
+ })
130
+ }
131
+
132
+ function retryTest (test, numRetries, tags, slowTestRetries) {
74
133
  const suite = test.parent
134
+ const isEfdRetry = tags.includes('_ddIsEfdRetry')
135
+ if (isEfdRetry) {
136
+ wrapOriginalEfdTest(test, slowTestRetries)
137
+ }
75
138
  for (let retryIndex = 0; retryIndex < numRetries; retryIndex++) {
76
139
  const clonedTest = test.clone()
77
140
  suite.addTest(clonedTest)
141
+ if (isEfdRetry) {
142
+ clonedTest._ddEfdRetryIndex = retryIndex + 1
143
+ const originalFn = clonedTest.fn
144
+ if (typeof originalFn === 'function') {
145
+ clonedTest.fn = shimmer.wrapFunction(originalFn, originalFn => function (...args) {
146
+ const efdRetryCount = efdRetryCountByTestFullName.get(getTestFullName(clonedTest))
147
+ if (efdRetryCount !== undefined && clonedTest._ddEfdRetryIndex > efdRetryCount) {
148
+ clonedTest._ddShouldSkipEfdRetry = true
149
+ this.skip()
150
+ }
151
+ return originalFn.apply(this, args)
152
+ })
153
+ }
154
+ }
78
155
  for (const tag of tags) {
79
156
  if (tag) {
80
157
  clonedTest[tag] = true
@@ -83,6 +160,14 @@ function retryTest (test, numRetries, tags) {
83
160
  }
84
161
  }
85
162
 
163
+ function getConfiguredEfdRetryCount (config) {
164
+ const { earlyFlakeDetectionSlowTestRetries } = config
165
+ if (!earlyFlakeDetectionSlowTestRetries || !Object.keys(earlyFlakeDetectionSlowTestRetries).length) {
166
+ return config.earlyFlakeDetectionNumRetries
167
+ }
168
+ return getMaxEfdRetryCount(earlyFlakeDetectionSlowTestRetries)
169
+ }
170
+
86
171
  function getSuitesByTestFile (root) {
87
172
  const suitesByTestFile = {}
88
173
  function getSuites (suite) {
@@ -137,8 +222,7 @@ function getTestToContextKey (test) {
137
222
  if (!wrappedFunctions.has(test.fn)) {
138
223
  return test.fn
139
224
  }
140
- const originalFn = originalFns.get(test.fn)
141
- return originalFn
225
+ return originalFns.get(test.fn)
142
226
  }
143
227
 
144
228
  function getTestContext (test) {
@@ -147,9 +231,9 @@ function getTestContext (test) {
147
231
  }
148
232
 
149
233
  function runnableWrapper (RunnablePackage, libraryConfig) {
150
- shimmer.wrap(RunnablePackage.prototype, 'run', run => function () {
234
+ shimmer.wrap(RunnablePackage.prototype, 'run', run => function (...args) {
151
235
  if (!testFinishCh.hasSubscribers) {
152
- return run.apply(this, arguments)
236
+ return run.apply(this, args)
153
237
  }
154
238
  if (libraryConfig?.isFlakyTestRetriesEnabled) {
155
239
  this.retries(libraryConfig?.flakyTestRetriesCount)
@@ -175,8 +259,8 @@ function runnableWrapper (RunnablePackage, libraryConfig) {
175
259
 
176
260
  if (ctx) {
177
261
  // we bind the test fn to the correct context
178
- const newFn = shimmer.wrapFunction(this.fn, originalFn => function () {
179
- return testFnCh.runStores(ctx, () => originalFn.apply(this, arguments))
262
+ const newFn = shimmer.wrapFunction(this.fn, originalFn => function (...args) {
263
+ return testFnCh.runStores(ctx, () => originalFn.apply(this, args))
180
264
  })
181
265
 
182
266
  // we store the original function, not to lose it
@@ -187,7 +271,7 @@ function runnableWrapper (RunnablePackage, libraryConfig) {
187
271
  }
188
272
  }
189
273
 
190
- return run.apply(this, arguments)
274
+ return run.apply(this, args)
191
275
  })
192
276
  return RunnablePackage
193
277
  }
@@ -215,6 +299,17 @@ function getOnTestHandler (isMain) {
215
299
  _ddIsModified: isModified,
216
300
  } = test
217
301
 
302
+ test._ddStartTime = performance.now()
303
+
304
+ if (isEfdRetry) {
305
+ const efdRetryCount = efdRetryCountByTestFullName.get(getTestFullName(test))
306
+ if (efdRetryCount !== undefined && test._ddEfdRetryIndex > efdRetryCount) {
307
+ test.pending = true
308
+ test._ddShouldSkipEfdRetry = true
309
+ return
310
+ }
311
+ }
312
+
218
313
  const testInfo = {
219
314
  testName: test.fullTitle(),
220
315
  testSuiteAbsolutePath,
@@ -273,6 +368,7 @@ function getFinalStatus ({
273
368
  isAttemptToFix,
274
369
  isLastAttemptToFix,
275
370
  attemptToFixPassed,
371
+ hasPassedAnyEfdAttempt,
276
372
  isQuarantined,
277
373
  isDisabled,
278
374
  }) {
@@ -301,7 +397,7 @@ function getFinalStatus ({
301
397
  return hasFailedAllRetries ? 'fail' : 'pass'
302
398
  }
303
399
  if (isEfdRetry && isLastEfdRetry) {
304
- return hasFailedAllRetries ? 'fail' : 'pass'
400
+ return hasPassedAnyEfdAttempt ? 'pass' : 'fail'
305
401
  }
306
402
  if (isAttemptToFix && isLastAttemptToFix) {
307
403
  return attemptToFixPassed ? 'pass' : 'fail'
@@ -314,6 +410,15 @@ function getTestFinishInfo (test, status, config, error) {
314
410
  let attemptToFixFailed = false
315
411
 
316
412
  const testName = getTestFullName(test)
413
+ if (
414
+ config.isEarlyFlakeDetectionEnabled &&
415
+ (test._ddIsNew || test._ddIsModified) &&
416
+ !test._ddIsEfdRetry &&
417
+ !efdRetryCountByTestFullName.has(testName)
418
+ ) {
419
+ const duration = test.duration > 0 ? test.duration : performance.now() - test._ddStartTime
420
+ setEfdRetryCountForTest(test, duration, config.earlyFlakeDetectionSlowTestRetries)
421
+ }
317
422
 
318
423
  if (testsStatuses.get(testName)) {
319
424
  testsStatuses.get(testName).push(status)
@@ -323,12 +428,14 @@ function getTestFinishInfo (test, status, config, error) {
323
428
  const testStatuses = testsStatuses.get(testName)
324
429
 
325
430
  const isLastAttempt = testStatuses.length === config.testManagementAttemptToFixRetries + 1
326
- const isLastEfdRetry = testStatuses.length === config.earlyFlakeDetectionNumRetries + 1
431
+ const efdRetryCount = efdRetryCountByTestFullName.get(testName) ?? getConfiguredEfdRetryCount(config)
432
+ const isLastEfdRetry = testStatuses.length === efdRetryCount + 1
327
433
  const isLastAtrAttempt = getIsLastRetry(test) || (config.isFlakyTestRetriesEnabled && status === 'pass')
328
434
 
329
435
  // Needed for the getFinalStatus call. This is because EFD does NOT tag as
330
436
  // EFD retry the first run of the test. It only tags as retries the clones
331
- const isEfdRetry = test._ddIsEfdRetry || (test._ddIsNew && config.isEarlyFlakeDetectionEnabled)
437
+ const isEfdRetry =
438
+ test._ddIsEfdRetry || ((test._ddIsNew || test._ddIsModified) && config.isEarlyFlakeDetectionEnabled)
332
439
 
333
440
  if (test._ddIsAttemptToFix && isLastAttempt) {
334
441
  if (testStatuses.includes('fail')) {
@@ -341,7 +448,7 @@ function getTestFinishInfo (test, status, config, error) {
341
448
  }
342
449
  }
343
450
 
344
- if (test._ddIsEfdRetry && isLastEfdRetry &&
451
+ if (test._ddIsEfdRetry && efdRetryCount > 0 && isLastEfdRetry &&
345
452
  testStatuses.every(status => status === 'fail')) {
346
453
  hasFailedAllRetries = true
347
454
  }
@@ -370,6 +477,7 @@ function getTestFinishInfo (test, status, config, error) {
370
477
  isAttemptToFix: _ddIsAttemptToFix,
371
478
  isLastAttemptToFix: isLastAttempt,
372
479
  attemptToFixPassed,
480
+ hasPassedAnyEfdAttempt: testStatuses.includes('pass'),
373
481
  isQuarantined: _ddIsQuarantined,
374
482
  isDisabled: _ddIsDisabled,
375
483
  })
@@ -391,11 +499,15 @@ function getTestFinishInfo (test, status, config, error) {
391
499
  isAttemptToFixRetry,
392
500
  isAtrRetry,
393
501
  finalStatus,
502
+ earlyFlakeAbortReason: efdSlowAbortedTests.has(testName) ? 'slow' : undefined,
394
503
  }
395
504
  }
396
505
 
397
506
  function getOnTestEndHandler (config) {
398
507
  return async function (test) {
508
+ if (test._ddShouldSkipEfdRetry) {
509
+ return
510
+ }
399
511
  const ctx = getTestContext(test)
400
512
  const status = getTestStatus(test)
401
513
 
@@ -518,6 +630,9 @@ function getOnTestRetryHandler (config) {
518
630
 
519
631
  function getOnPendingHandler () {
520
632
  return function (test) {
633
+ if (test._ddShouldSkipEfdRetry) {
634
+ return
635
+ }
521
636
  const testStartLine = testToStartLine.get(test)
522
637
  const {
523
638
  file: testSuiteAbsolutePath,
@@ -587,8 +702,9 @@ function getRunTestsWrapper (runTests, config) {
587
702
  if (!test.isPending() && !test._ddIsAttemptToFix && config.isEarlyFlakeDetectionEnabled) {
588
703
  retryTest(
589
704
  test,
590
- config.earlyFlakeDetectionNumRetries,
591
- ['_ddIsModified', '_ddIsEfdRetry']
705
+ getConfiguredEfdRetryCount(config),
706
+ ['_ddIsModified', '_ddIsEfdRetry'],
707
+ config.earlyFlakeDetectionSlowTestRetries
592
708
  )
593
709
  }
594
710
  }
@@ -606,8 +722,9 @@ function getRunTestsWrapper (runTests, config) {
606
722
  if (config.isEarlyFlakeDetectionEnabled && !test._ddIsAttemptToFix && !test._ddIsModified) {
607
723
  retryTest(
608
724
  test,
609
- config.earlyFlakeDetectionNumRetries,
610
- ['_ddIsNew', '_ddIsEfdRetry']
725
+ getConfiguredEfdRetryCount(config),
726
+ ['_ddIsNew', '_ddIsEfdRetry'],
727
+ config.earlyFlakeDetectionSlowTestRetries
611
728
  )
612
729
  }
613
730
  }
@@ -27,15 +27,17 @@ addHook({
27
27
  versions: ['>=8.0.0'],
28
28
  file: 'lib/mocha.js',
29
29
  }, (Mocha) => {
30
- shimmer.wrap(Mocha.prototype, 'run', run => function () {
30
+ shimmer.wrap(Mocha.prototype, 'run', run => function (...args) {
31
31
  if (this.options._ddIsKnownTestsEnabled) {
32
32
  config.isKnownTestsEnabled = true
33
33
  config.isEarlyFlakeDetectionEnabled = this.options._ddIsEfdEnabled
34
34
  config.knownTests = this.options._ddKnownTests
35
35
  config.earlyFlakeDetectionNumRetries = this.options._ddEfdNumRetries
36
+ config.earlyFlakeDetectionSlowTestRetries = this.options._ddEfdSlowTestRetries ?? {}
36
37
  delete this.options._ddIsEfdEnabled
37
38
  delete this.options._ddKnownTests
38
39
  delete this.options._ddEfdNumRetries
40
+ delete this.options._ddEfdSlowTestRetries
39
41
  delete this.options._ddIsKnownTestsEnabled
40
42
  }
41
43
  if (this.options._ddIsImpactedTestsEnabled) {
@@ -58,7 +60,7 @@ addHook({
58
60
  delete this.options._ddIsFlakyTestRetriesEnabled
59
61
  delete this.options._ddFlakyTestRetriesCount
60
62
  }
61
- return run.apply(this, arguments)
63
+ return run.apply(this, args)
62
64
  })
63
65
 
64
66
  return Mocha
@@ -72,9 +74,9 @@ addHook({
72
74
  }, function (Runner) {
73
75
  shimmer.wrap(Runner.prototype, 'runTests', runTests => getRunTestsWrapper(runTests, config))
74
76
 
75
- shimmer.wrap(Runner.prototype, 'run', run => function () {
77
+ shimmer.wrap(Runner.prototype, 'run', run => function (...args) {
76
78
  if (!workerFinishCh.hasSubscribers) {
77
- return run.apply(this, arguments)
79
+ return run.apply(this, args)
78
80
  }
79
81
  // We flush when the worker ends with its test file (a mocha instance in a worker runs a single test file)
80
82
  this.once('end', () => {
@@ -93,7 +95,7 @@ addHook({
93
95
 
94
96
  this.on('pending', getOnPendingHandler())
95
97
 
96
- return run.apply(this, arguments)
98
+ return run.apply(this, args)
97
99
  })
98
100
  return Runner
99
101
  })
@@ -22,26 +22,22 @@ addHook({ name: 'mongodb-core', versions: ['2 - 3.1.9'] }, Server => {
22
22
  shimmer.wrap(cursorProto, '_getmore', _getmore => wrapCursor(_getmore, 'getMore', 'getMore'))
23
23
  shimmer.wrap(cursorProto, '_find', _find => wrapQuery(_find, '_find'))
24
24
  shimmer.wrap(cursorProto, 'kill', kill => wrapCursor(kill, 'killCursors', 'killCursors'))
25
- return Server
26
25
  })
27
26
 
28
27
  addHook({ name: 'mongodb', versions: ['>=4 <4.6.0'], file: 'lib/cmap/connection.js' }, Connection => {
29
28
  const proto = Connection.Connection.prototype
30
29
  shimmer.wrap(proto, 'command', command => wrapConnectionCommand(command, 'command'))
31
30
  shimmer.wrap(proto, 'query', query => wrapConnectionCommand(query, 'query'))
32
- return Connection
33
31
  })
34
32
 
35
33
  addHook({ name: 'mongodb', versions: ['>=4.6.0 <6.4.0'], file: 'lib/cmap/connection.js' }, Connection => {
36
34
  const proto = Connection.Connection.prototype
37
35
  shimmer.wrap(proto, 'command', command => wrapConnectionCommand(command, 'command'))
38
- return Connection
39
36
  })
40
37
 
41
38
  addHook({ name: 'mongodb', versions: ['>=6.4.0'], file: 'lib/cmap/connection.js' }, Connection => {
42
39
  const proto = Connection.Connection.prototype
43
40
  shimmer.wrap(proto, 'command', command => wrapConnectionCommand(command, 'command', undefined, instrumentPromise))
44
- return Connection
45
41
  })
46
42
 
47
43
  addHook({ name: 'mongodb', versions: ['>=3.3 <4'], file: 'lib/core/wireprotocol/index.js' }, wp => wrapWp(wp))
@@ -50,12 +46,10 @@ addHook({ name: 'mongodb-core', versions: ['>=3.2'], file: 'lib/wireprotocol/ind
50
46
 
51
47
  addHook({ name: 'mongodb-core', versions: ['~3.1.10'], file: 'lib/wireprotocol/3_2_support.js' }, WireProtocol => {
52
48
  shimmer.wrap(WireProtocol.prototype, 'command', command => wrapUnifiedCommand(command, 'command'))
53
- return WireProtocol
54
49
  })
55
50
 
56
51
  addHook({ name: 'mongodb-core', versions: ['~3.1.10'], file: 'lib/wireprotocol/2_6_support.js' }, WireProtocol => {
57
52
  shimmer.wrap(WireProtocol.prototype, 'command', command => wrapUnifiedCommand(command, 'command'))
58
- return WireProtocol
59
53
  })
60
54
 
61
55
  addHook({ name: 'mongodb', versions: ['>=3.5.4 <4.11.0'], file: 'lib/utils.js' }, util => {
@@ -71,7 +65,6 @@ addHook({ name: 'mongodb', versions: ['>=3.5.4 <4.11.0'], file: 'lib/utils.js' }
71
65
 
72
66
  return maybePromise.apply(this, arguments)
73
67
  })
74
- return util
75
68
  })
76
69
 
77
70
  function wrapWp (wp) {
@@ -86,17 +79,16 @@ function wrapWp (wp) {
86
79
  }
87
80
 
88
81
  function wrapUnifiedCommand (command, operation, name) {
89
- const wrapped = function (server, ns, ops) {
82
+ return function (server, ns, ops) {
90
83
  if (!startCh.hasSubscribers) {
91
84
  return command.apply(this, arguments)
92
85
  }
93
86
  return instrument(operation, command, this, arguments, server, ns, ops, { name })
94
87
  }
95
- return wrapped
96
88
  }
97
89
 
98
90
  function wrapConnectionCommand (command, operation, name, instrumentFn = instrument) {
99
- const wrapped = function (ns, ops) {
91
+ return function (ns, ops) {
100
92
  if (!startCh.hasSubscribers) {
101
93
  return command.apply(this, arguments)
102
94
  }
@@ -109,43 +101,38 @@ function wrapConnectionCommand (command, operation, name, instrumentFn = instrum
109
101
  ns = `${ns.db}.${ns.collection}`
110
102
  return instrumentFn(operation, command, this, arguments, topology, ns, ops, { name })
111
103
  }
112
- return wrapped
113
104
  }
114
105
 
115
106
  function wrapQuery (query, operation, name) {
116
- const wrapped = function () {
107
+ return function (...args) {
117
108
  if (!startCh.hasSubscribers) {
118
- return query.apply(this, arguments)
109
+ return query.apply(this, args)
119
110
  }
120
111
  const pool = this.server.s.pool
121
112
  const ns = this.ns
122
113
  const ops = this.cmd
123
- return instrument(operation, query, this, arguments, pool, ns, ops)
114
+ return instrument(operation, query, this, args, pool, ns, ops)
124
115
  }
125
-
126
- return wrapped
127
116
  }
128
117
 
129
118
  function wrapCursor (cursor, operation, name) {
130
- const wrapped = function () {
119
+ return function (...args) {
131
120
  if (!startCh.hasSubscribers) {
132
- return cursor.apply(this, arguments)
121
+ return cursor.apply(this, args)
133
122
  }
134
123
  const pool = this.server.s.pool
135
124
  const ns = this.ns
136
- return instrument(operation, cursor, this, arguments, pool, ns, {}, { name })
125
+ return instrument(operation, cursor, this, args, pool, ns, {}, { name })
137
126
  }
138
- return wrapped
139
127
  }
140
128
 
141
129
  function wrapCommand (command, operation, name) {
142
- const wrapped = function (ns, ops) {
130
+ return function (ns, ops) {
143
131
  if (!startCh.hasSubscribers) {
144
132
  return command.apply(this, arguments)
145
133
  }
146
134
  return instrument(operation, command, this, arguments, this, ns, ops, { name })
147
135
  }
148
- return wrapped
149
136
  }
150
137
 
151
138
  function instrument (operation, command, instance, args, server, ns, ops, options = {}) {
@@ -35,22 +35,22 @@ addHook({ name: 'mongodb', versions: ['>=3.3 <5', '5', '>=6'] }, mongodb => {
35
35
  const useTwoArguments = collectionMethodsWithTwoFilters.includes(methodName)
36
36
 
37
37
  shimmer.wrap(mongodb.Collection.prototype, methodName, method => {
38
- return function () {
38
+ return function (...args) {
39
39
  if (!startCh.hasSubscribers) {
40
- return method.apply(this, arguments)
40
+ return method.apply(this, args)
41
41
  }
42
42
 
43
43
  const ctx = {
44
- filters: [arguments[0]],
44
+ filters: [args[0]],
45
45
  methodName,
46
46
  }
47
47
 
48
48
  if (useTwoArguments) {
49
- ctx.filters.push(arguments[1])
49
+ ctx.filters.push(args[1])
50
50
  }
51
51
 
52
52
  return startCh.runStores(ctx, () => {
53
- return method.apply(this, arguments)
53
+ return method.apply(this, args)
54
54
  })
55
55
  }
56
56
  })
@@ -66,14 +66,14 @@ addHook({
66
66
  if (!(methodName in Model)) continue
67
67
 
68
68
  shimmer.wrap(Model, methodName, method => {
69
- return function wrappedModelMethod () {
69
+ return function wrappedModelMethod (...args) {
70
70
  if (!startCh.hasSubscribers) {
71
- return method.apply(this, arguments)
71
+ return method.apply(this, args)
72
72
  }
73
73
 
74
- const filters = [arguments[0]]
74
+ const filters = [args[0]]
75
75
  if (useTwoArguments) {
76
- filters.push(arguments[1])
76
+ filters.push(args[1])
77
77
  }
78
78
 
79
79
  let callbackWrapped = false
@@ -84,10 +84,10 @@ addHook({
84
84
  if (typeof args[lastArgumentIndex] === 'function') {
85
85
  // is a callback, wrap it to execute finish()
86
86
  shimmer.wrap(args, lastArgumentIndex, originalCb => {
87
- return function () {
87
+ return function (...args) {
88
88
  finishCh.publish(ctx)
89
89
 
90
- return originalCb.apply(this, arguments)
90
+ return originalCb.apply(this, args)
91
91
  }
92
92
  })
93
93
 
@@ -101,19 +101,19 @@ addHook({
101
101
  }
102
102
 
103
103
  return startCh.runStores(ctx, () => {
104
- wrapCallbackIfExist(arguments, ctx)
104
+ wrapCallbackIfExist(args, ctx)
105
105
 
106
- const res = method.apply(this, arguments)
106
+ const res = method.apply(this, args)
107
107
 
108
108
  // if it is not callback, wrap exec method and its then
109
109
  if (!callbackWrapped) {
110
110
  shimmer.wrap(res, 'exec', originalExec => {
111
- return function wrappedExec () {
111
+ return function wrappedExec (...args) {
112
112
  if (!callbackWrapped) {
113
- wrapCallbackIfExist(arguments, ctx)
113
+ wrapCallbackIfExist(args, ctx)
114
114
  }
115
115
 
116
- const execResult = originalExec.apply(this, arguments)
116
+ const execResult = originalExec.apply(this, args)
117
117
 
118
118
  if (callbackWrapped || typeof execResult?.then !== 'function') {
119
119
  return execResult
@@ -121,27 +121,27 @@ addHook({
121
121
 
122
122
  // wrap them method, wrap resolve and reject methods
123
123
  shimmer.wrap(execResult, 'then', originalThen => {
124
- return function wrappedThen () {
125
- const resolve = arguments[0]
126
- const reject = arguments[1]
124
+ return function wrappedThen (...args) {
125
+ const resolve = args[0]
126
+ const reject = args[1]
127
127
 
128
- arguments[0] = shimmer.wrapFunction(resolve, resolve => function wrappedResolve () {
128
+ args[0] = shimmer.wrapFunction(resolve, resolve => function wrappedResolve (...args) {
129
129
  finishCh.publish(ctx)
130
130
 
131
131
  if (resolve) {
132
- return resolve.apply(this, arguments)
132
+ return resolve.apply(this, args)
133
133
  }
134
134
  })
135
135
 
136
- arguments[1] = shimmer.wrapFunction(reject, reject => function wrappedReject () {
136
+ args[1] = shimmer.wrapFunction(reject, reject => function wrappedReject (...args) {
137
137
  finishCh.publish(ctx)
138
138
 
139
139
  if (reject) {
140
- return reject.apply(this, arguments)
140
+ return reject.apply(this, args)
141
141
  }
142
142
  })
143
143
 
144
- return originalThen.apply(this, arguments)
144
+ return originalThen.apply(this, args)
145
145
  }
146
146
  })
147
147
 
@@ -165,8 +165,8 @@ addHook({
165
165
  versions: ['6', '>=7'],
166
166
  file: 'lib/helpers/query/sanitizeFilter.js',
167
167
  }, sanitizeFilter => {
168
- return shimmer.wrapFunction(sanitizeFilter, sanitizeFilter => function wrappedSanitizeFilter () {
169
- const sanitizedObject = sanitizeFilter.apply(this, arguments)
168
+ return shimmer.wrapFunction(sanitizeFilter, sanitizeFilter => function wrappedSanitizeFilter (...args) {
169
+ const sanitizedObject = sanitizeFilter.apply(this, args)
170
170
 
171
171
  if (sanitizeFilterFinishCh.hasSubscribers) {
172
172
  sanitizeFilterFinishCh.publish({
@@ -42,22 +42,22 @@ addHook({
42
42
  if (!(methodName in Query.prototype)) continue
43
43
 
44
44
  shimmer.wrap(Query.prototype, methodName, method => {
45
- return function () {
45
+ return function (...args) {
46
46
  if (prepareCh.hasSubscribers) {
47
- const filters = getFilters(arguments, methodName)
47
+ const filters = getFilters(args, methodName)
48
48
  if (filters?.length) {
49
49
  prepareCh.publish({ filters })
50
50
  }
51
51
  }
52
52
 
53
- return method.apply(this, arguments)
53
+ return method.apply(this, args)
54
54
  }
55
55
  })
56
56
  }
57
57
 
58
58
  shimmer.wrap(Query.prototype, 'exec', originalExec => {
59
- return function wrappedExec () {
60
- return tracingCh.tracePromise(originalExec, {}, this, arguments)
59
+ return function wrappedExec (...args) {
60
+ return tracingCh.tracePromise(originalExec, {}, this, args)
61
61
  }
62
62
  })
63
63
 
@@ -6,7 +6,7 @@ const { channel, addHook, AsyncResource } = require('./helpers/instrument')
6
6
  const multerReadCh = channel('datadog:multer:read:finish')
7
7
 
8
8
  function publishRequestBodyAndNext (req, res, next) {
9
- return shimmer.wrapFunction(next, next => function () {
9
+ return shimmer.wrapFunction(next, next => function (...args) {
10
10
  if (multerReadCh.hasSubscribers && req) {
11
11
  const abortController = new AbortController()
12
12
  const body = req.body
@@ -16,7 +16,7 @@ function publishRequestBodyAndNext (req, res, next) {
16
16
  if (abortController.signal.aborted) return
17
17
  }
18
18
 
19
- return next.apply(this, arguments)
19
+ return next.apply(this, args)
20
20
  })
21
21
  }
22
22
 
@@ -25,8 +25,8 @@ addHook({
25
25
  file: 'lib/make-middleware.js',
26
26
  versions: ['^1.4.4-lts.1'],
27
27
  }, makeMiddleware => {
28
- return shimmer.wrapFunction(makeMiddleware, makeMiddleware => function () {
29
- const middleware = makeMiddleware.apply(this, arguments)
28
+ return shimmer.wrapFunction(makeMiddleware, makeMiddleware => function (...args) {
29
+ const middleware = makeMiddleware.apply(this, args)
30
30
 
31
31
  return shimmer.wrapFunction(middleware, middleware => function wrapMulterMiddleware (req, res, next) {
32
32
  const nextResource = new AsyncResource('bound-anonymous-fn')