dd-trace 5.51.0 → 5.53.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 (98) hide show
  1. package/LICENSE-3rdparty.csv +0 -6
  2. package/README.md +5 -0
  3. package/index.d.ts +88 -6
  4. package/package.json +3 -9
  5. package/packages/datadog-instrumentations/src/amqplib.js +8 -5
  6. package/packages/datadog-instrumentations/src/child_process.js +2 -1
  7. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +406 -0
  8. package/packages/datadog-instrumentations/src/couchbase.js +2 -1
  9. package/packages/datadog-instrumentations/src/cucumber.js +43 -45
  10. package/packages/datadog-instrumentations/src/dns.js +16 -14
  11. package/packages/datadog-instrumentations/src/express.js +2 -6
  12. package/packages/datadog-instrumentations/src/fs.js +43 -51
  13. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  14. package/packages/datadog-instrumentations/src/helpers/register.js +17 -12
  15. package/packages/datadog-instrumentations/src/http/client.js +2 -1
  16. package/packages/datadog-instrumentations/src/iovalkey.js +51 -0
  17. package/packages/datadog-instrumentations/src/jest.js +53 -40
  18. package/packages/datadog-instrumentations/src/kafkajs.js +21 -8
  19. package/packages/datadog-instrumentations/src/mocha/main.js +33 -46
  20. package/packages/datadog-instrumentations/src/mocha/utils.js +76 -74
  21. package/packages/datadog-instrumentations/src/mysql2.js +3 -1
  22. package/packages/datadog-instrumentations/src/net.js +27 -29
  23. package/packages/datadog-instrumentations/src/next.js +6 -14
  24. package/packages/datadog-instrumentations/src/pg.js +15 -7
  25. package/packages/datadog-instrumentations/src/playwright.js +64 -67
  26. package/packages/datadog-instrumentations/src/url.js +9 -17
  27. package/packages/datadog-instrumentations/src/vitest.js +66 -72
  28. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/batch-consumer.js +11 -0
  29. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/consumer.js +11 -0
  30. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +19 -0
  31. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/producer.js +11 -0
  32. package/packages/datadog-plugin-cucumber/src/index.js +32 -18
  33. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +3 -0
  34. package/packages/datadog-plugin-dns/src/lookup.js +10 -5
  35. package/packages/datadog-plugin-dns/src/lookup_service.js +6 -2
  36. package/packages/datadog-plugin-dns/src/resolve.js +5 -2
  37. package/packages/datadog-plugin-dns/src/reverse.js +6 -2
  38. package/packages/datadog-plugin-fs/src/index.js +9 -2
  39. package/packages/datadog-plugin-iovalkey/src/index.js +18 -0
  40. package/packages/datadog-plugin-jest/src/index.js +17 -8
  41. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -1
  42. package/packages/datadog-plugin-kafkajs/src/consumer.js +12 -21
  43. package/packages/datadog-plugin-kafkajs/src/producer.js +12 -5
  44. package/packages/datadog-plugin-kafkajs/src/utils.js +27 -0
  45. package/packages/datadog-plugin-langchain/src/index.js +0 -1
  46. package/packages/datadog-plugin-mocha/src/index.js +58 -35
  47. package/packages/datadog-plugin-net/src/ipc.js +6 -4
  48. package/packages/datadog-plugin-net/src/tcp.js +15 -9
  49. package/packages/datadog-plugin-pg/src/index.js +5 -1
  50. package/packages/datadog-plugin-playwright/src/index.js +29 -20
  51. package/packages/datadog-plugin-redis/src/index.js +8 -3
  52. package/packages/datadog-plugin-vitest/src/index.js +67 -44
  53. package/packages/datadog-shimmer/src/shimmer.js +164 -33
  54. package/packages/dd-trace/src/appsec/api_security_sampler.js +20 -12
  55. package/packages/dd-trace/src/appsec/graphql.js +2 -2
  56. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +14 -9
  57. package/packages/dd-trace/src/appsec/index.js +15 -12
  58. package/packages/dd-trace/src/appsec/rasp/index.js +4 -2
  59. package/packages/dd-trace/src/appsec/rasp/utils.js +11 -6
  60. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -2
  61. package/packages/dd-trace/src/appsec/telemetry/index.js +1 -2
  62. package/packages/dd-trace/src/appsec/telemetry/rasp.js +0 -9
  63. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +6 -6
  64. package/packages/dd-trace/src/baggage.js +36 -0
  65. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
  66. package/packages/dd-trace/src/config.js +14 -2
  67. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +61 -7
  68. package/packages/dd-trace/src/debugger/devtools_client/index.js +10 -26
  69. package/packages/dd-trace/src/debugger/devtools_client/send.js +8 -7
  70. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +15 -7
  71. package/packages/dd-trace/src/debugger/devtools_client/state.js +22 -2
  72. package/packages/dd-trace/src/dogstatsd.js +2 -0
  73. package/packages/dd-trace/src/exporters/common/docker.js +13 -31
  74. package/packages/dd-trace/src/guardrails/telemetry.js +2 -5
  75. package/packages/dd-trace/src/llmobs/tagger.js +3 -3
  76. package/packages/dd-trace/src/llmobs/writers/base.js +33 -12
  77. package/packages/dd-trace/src/noop/proxy.js +5 -0
  78. package/packages/dd-trace/src/opentelemetry/context_manager.js +2 -0
  79. package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -9
  80. package/packages/dd-trace/src/plugin_manager.js +2 -0
  81. package/packages/dd-trace/src/plugins/index.js +4 -0
  82. package/packages/dd-trace/src/plugins/log_plugin.js +9 -20
  83. package/packages/dd-trace/src/plugins/outbound.js +11 -3
  84. package/packages/dd-trace/src/plugins/tracing.js +8 -4
  85. package/packages/dd-trace/src/plugins/util/test.js +1 -1
  86. package/packages/dd-trace/src/profiling/exporter_cli.js +1 -1
  87. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +1 -1
  88. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +1 -1
  89. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +2 -2
  90. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +1 -1
  91. package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +15 -14
  92. package/packages/dd-trace/src/proxy.js +12 -4
  93. package/packages/dd-trace/src/serverless.js +0 -48
  94. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +8 -0
  95. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +8 -0
  96. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
  97. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
  98. package/packages/dd-trace/src/standalone/product.js +3 -5
@@ -109,12 +109,9 @@ class MochaPlugin extends CiPlugin {
109
109
  this.telemetry.distribution(TELEMETRY_CODE_COVERAGE_NUM_FILES, {}, relativeCoverageFiles.length)
110
110
  })
111
111
 
112
- this.addSub('ci:mocha:test-suite:start', ({
113
- testSuiteAbsolutePath,
114
- isUnskippable,
115
- isForcedToRun,
116
- itrCorrelationId
117
- }) => {
112
+ this.addBind('ci:mocha:test-suite:start', (ctx) => {
113
+ const { testSuiteAbsolutePath, isUnskippable, isForcedToRun, itrCorrelationId } = ctx
114
+
118
115
  // If the test module span is undefined, the plugin has not been initialized correctly and we bail out
119
116
  if (!this.testModuleSpan) {
120
117
  return
@@ -164,38 +161,51 @@ class MochaPlugin extends CiPlugin {
164
161
  testSuiteSpan.setTag(ITR_CORRELATION_ID, itrCorrelationId)
165
162
  }
166
163
  const store = storage('legacy').getStore()
167
- this.enter(testSuiteSpan, store)
164
+ ctx.parentStore = store
165
+ ctx.currentStore = { ...store, testSuiteSpan }
168
166
  this._testSuites.set(testSuite, testSuiteSpan)
169
167
  })
170
168
 
171
- this.addSub('ci:mocha:test-suite:finish', (status) => {
172
- const store = storage('legacy').getStore()
173
- if (store && store.span) {
174
- const span = store.span
169
+ this.addSub('ci:mocha:test-suite:finish', ({ testSuiteSpan, status }) => {
170
+ if (testSuiteSpan) {
175
171
  // the test status of the suite may have been set in ci:mocha:test-suite:error already
176
- if (!span.context()._tags[TEST_STATUS]) {
177
- span.setTag(TEST_STATUS, status)
172
+ if (!testSuiteSpan.context()._tags[TEST_STATUS]) {
173
+ testSuiteSpan.setTag(TEST_STATUS, status)
178
174
  }
179
- span.finish()
175
+ testSuiteSpan.finish()
180
176
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
181
177
  }
182
178
  })
183
179
 
184
- this.addSub('ci:mocha:test-suite:error', (err) => {
185
- const store = storage('legacy').getStore()
186
- if (store && store.span) {
187
- const span = store.span
188
- span.setTag('error', err)
189
- span.setTag(TEST_STATUS, 'fail')
180
+ this.addBind('ci:mocha:test-suite:error', (ctx) => {
181
+ const { error } = ctx
182
+ const testSuiteSpan = ctx.currentStore?.testSuiteSpan
183
+
184
+ if (testSuiteSpan) {
185
+ testSuiteSpan.setTag('error', error)
186
+ testSuiteSpan.setTag(TEST_STATUS, 'fail')
187
+
188
+ ctx.parentStore = ctx.currentStore
189
+ ctx.currentStore = { ...ctx.currentStore, testSuiteSpan }
190
190
  }
191
+
192
+ return ctx.currentStore
191
193
  })
192
194
 
193
- this.addSub('ci:mocha:test:start', (testInfo) => {
195
+ this.addBind('ci:mocha:test:fn', (ctx) => {
196
+ return ctx.currentStore
197
+ })
198
+
199
+ this.addBind('ci:mocha:test:start', (ctx) => {
194
200
  const store = storage('legacy').getStore()
195
- const span = this.startTestSpan(testInfo)
201
+ const span = this.startTestSpan(ctx)
202
+
203
+ ctx.parentStore = store
204
+ ctx.currentStore = { ...store, span }
196
205
 
197
- this.enter(span, store)
198
206
  this.activeTestSpan = span
207
+
208
+ return ctx.currentStore
199
209
  })
200
210
 
201
211
  this.addSub('ci:mocha:worker:finish', () => {
@@ -203,17 +213,16 @@ class MochaPlugin extends CiPlugin {
203
213
  })
204
214
 
205
215
  this.addSub('ci:mocha:test:finish', ({
216
+ span,
206
217
  status,
207
218
  hasBeenRetried,
208
219
  isLastRetry,
209
220
  hasFailedAllRetries,
210
221
  attemptToFixPassed,
222
+ attemptToFixFailed,
211
223
  isAttemptToFixRetry,
212
224
  isAtrRetry
213
225
  }) => {
214
- const store = storage('legacy').getStore()
215
- const span = store?.span
216
-
217
226
  if (span) {
218
227
  span.setTag(TEST_STATUS, status)
219
228
  if (hasBeenRetried) {
@@ -229,6 +238,8 @@ class MochaPlugin extends CiPlugin {
229
238
  }
230
239
  if (attemptToFixPassed) {
231
240
  span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'true')
241
+ } else if (attemptToFixFailed) {
242
+ span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'false')
232
243
  }
233
244
  if (isAttemptToFixRetry) {
234
245
  span.setTag(TEST_IS_RETRY, 'true')
@@ -257,19 +268,26 @@ class MochaPlugin extends CiPlugin {
257
268
  }
258
269
  })
259
270
 
260
- this.addSub('ci:mocha:test:skip', (testInfo) => {
271
+ this.addBind('ci:mocha:test:skip', (ctx) => {
261
272
  const store = storage('legacy').getStore()
262
273
  // skipped through it.skip, so the span is not created yet
263
274
  // for this test
264
275
  if (!store) {
265
- const testSpan = this.startTestSpan(testInfo)
266
- this.enter(testSpan, store)
276
+ const span = this.startTestSpan(ctx)
277
+
278
+ ctx.parentStore = store
279
+ ctx.currentStore = { ...store, span }
280
+
281
+ this.activeTestSpan = span
267
282
  }
283
+
284
+ return ctx.currentStore
268
285
  })
269
286
 
270
- this.addSub('ci:mocha:test:error', (err) => {
271
- const store = storage('legacy').getStore()
272
- const span = store?.span
287
+ this.addBind('ci:mocha:test:error', (ctx) => {
288
+ const { err } = ctx
289
+ const span = ctx.currentStore?.span
290
+
273
291
  if (err && span) {
274
292
  if (err.constructor.name === 'Pending' && !this.forbidPending) {
275
293
  span.setTag(TEST_STATUS, 'skip')
@@ -277,12 +295,17 @@ class MochaPlugin extends CiPlugin {
277
295
  span.setTag(TEST_STATUS, 'fail')
278
296
  span.setTag('error', err)
279
297
  }
298
+
299
+ ctx.parentStore = ctx.currentStore
300
+ ctx.currentStore = { ...ctx.currentStore, span }
301
+
302
+ this.activeTestSpan = span
280
303
  }
304
+
305
+ return ctx.currentStore
281
306
  })
282
307
 
283
- this.addSub('ci:mocha:test:retry', ({ isFirstAttempt, willBeRetried, err, test, isAtrRetry }) => {
284
- const store = storage('legacy').getStore()
285
- const span = store?.span
308
+ this.addSub('ci:mocha:test:retry', ({ span, isFirstAttempt, willBeRetried, err, test, isAtrRetry }) => {
286
309
  if (span) {
287
310
  span.setTag(TEST_STATUS, 'fail')
288
311
  if (!isFirstAttempt) {
@@ -6,15 +6,17 @@ class NetIPCPlugin extends ClientPlugin {
6
6
  static get id () { return 'net' }
7
7
  static get operation () { return 'ipc' }
8
8
 
9
- start ({ options }) {
9
+ bindStart (ctx) {
10
10
  this.startSpan('ipc.connect', {
11
11
  service: this.config.service,
12
- resource: options.path,
12
+ resource: ctx.options.path,
13
13
  kind: 'client',
14
14
  meta: {
15
- 'ipc.path': options.path
15
+ 'ipc.path': ctx.options.path
16
16
  }
17
- })
17
+ }, ctx)
18
+
19
+ return ctx.currentStore
18
20
  }
19
21
  }
20
22
 
@@ -10,20 +10,24 @@ class NetTCPPlugin extends ClientPlugin {
10
10
  constructor (...args) {
11
11
  super(...args)
12
12
 
13
- this.addTraceSub('connection', ({ socket }) => {
14
- const span = this.activeSpan
13
+ this.addTraceBind('ready', (ctx) => {
14
+ return ctx.parentStore
15
+ })
16
+
17
+ this.addTraceSub('connection', (ctx) => {
18
+ const span = ctx.currentStore.span
15
19
 
16
20
  span.addTags({
17
- 'tcp.local.address': socket.localAddress,
18
- 'tcp.local.port': socket.localPort
21
+ 'tcp.local.address': ctx.socket.localAddress,
22
+ 'tcp.local.port': ctx.socket.localPort
19
23
  })
20
24
  })
21
25
  }
22
26
 
23
- start ({ options }) {
24
- const host = options.host || 'localhost'
25
- const port = options.port || 0
26
- const family = options.family || 4
27
+ bindStart (ctx) {
28
+ const host = ctx.options.host || 'localhost'
29
+ const port = ctx.options.port || 0
30
+ const family = ctx.options.family || 4
27
31
 
28
32
  this.startSpan('tcp.connect', {
29
33
  service: this.config.service,
@@ -40,7 +44,9 @@ class NetTCPPlugin extends ClientPlugin {
40
44
  'tcp.local.port': 0,
41
45
  [CLIENT_PORT_KEY]: port
42
46
  }
43
- })
47
+ }, ctx)
48
+
49
+ return ctx.currentStore
44
50
  }
45
51
  }
46
52
 
@@ -8,7 +8,7 @@ class PGPlugin extends DatabasePlugin {
8
8
  static get operation () { return 'query' }
9
9
  static get system () { return 'postgres' }
10
10
 
11
- start ({ params = {}, query, processId }) {
11
+ start ({ params = {}, query, processId, stream }) {
12
12
  const service = this.serviceName({ pluginConfig: this.config, params })
13
13
  const originalStatement = this.maybeTruncate(query.text)
14
14
 
@@ -27,6 +27,10 @@ class PGPlugin extends DatabasePlugin {
27
27
  }
28
28
  })
29
29
 
30
+ if (stream) {
31
+ span.setTag('db.stream', 1)
32
+ }
33
+
30
34
  query.__ddInjectableQuery = this.injectDbmQuery(span, query.text, service, !!query.name)
31
35
  }
32
36
  }
@@ -97,7 +97,9 @@ class PlaywrightPlugin extends CiPlugin {
97
97
  this.numFailedTests = 0
98
98
  })
99
99
 
100
- this.addSub('ci:playwright:test-suite:start', (testSuiteAbsolutePath) => {
100
+ this.addBind('ci:playwright:test-suite:start', (ctx) => {
101
+ const { testSuiteAbsolutePath } = ctx
102
+
101
103
  const store = storage('legacy').getStore()
102
104
  const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.rootDir)
103
105
  const testSourceFile = getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
@@ -126,27 +128,28 @@ class PlaywrightPlugin extends CiPlugin {
126
128
  }
127
129
  })
128
130
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
129
- this.enter(testSuiteSpan, store)
131
+ ctx.parentStore = store
132
+ ctx.currentStore = { ...store, testSuiteSpan }
130
133
 
131
134
  this._testSuites.set(testSuiteAbsolutePath, testSuiteSpan)
135
+
136
+ return ctx.currentStore
132
137
  })
133
138
 
134
- this.addSub('ci:playwright:test-suite:finish', ({ status, error }) => {
135
- const store = storage('legacy').getStore()
136
- const span = store && store.span
137
- if (!span) return
139
+ this.addSub('ci:playwright:test-suite:finish', ({ testSuiteSpan, status, error }) => {
140
+ if (!testSuiteSpan) return
138
141
  if (error) {
139
- span.setTag('error', error)
140
- span.setTag(TEST_STATUS, 'fail')
142
+ testSuiteSpan.setTag('error', error)
143
+ testSuiteSpan.setTag(TEST_STATUS, 'fail')
141
144
  } else {
142
- span.setTag(TEST_STATUS, status)
145
+ testSuiteSpan.setTag(TEST_STATUS, status)
143
146
  }
144
147
 
145
148
  if (status === 'fail' || error) {
146
149
  this.numFailedSuites++
147
150
  }
148
151
 
149
- span.finish()
152
+ testSuiteSpan.finish()
150
153
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
151
154
  })
152
155
 
@@ -180,13 +183,14 @@ class PlaywrightPlugin extends CiPlugin {
180
183
  }
181
184
  })
182
185
 
183
- this.addSub('ci:playwright:test:start', ({
184
- testName,
185
- testSuiteAbsolutePath,
186
- testSourceLine,
187
- browserName,
188
- isDisabled
189
- }) => {
186
+ this.addBind('ci:playwright:test:start', (ctx) => {
187
+ const {
188
+ testName,
189
+ testSuiteAbsolutePath,
190
+ testSourceLine,
191
+ browserName,
192
+ isDisabled
193
+ } = ctx
190
194
  const store = storage('legacy').getStore()
191
195
  const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.rootDir)
192
196
  const testSourceFile = getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
@@ -203,7 +207,10 @@ class PlaywrightPlugin extends CiPlugin {
203
207
  span.setTag(TEST_MANAGEMENT_IS_DISABLED, 'true')
204
208
  }
205
209
 
206
- this.enter(span, store)
210
+ ctx.parentStore = store
211
+ ctx.currentStore = { ...store, span }
212
+
213
+ return ctx.currentStore
207
214
  })
208
215
 
209
216
  this.addSub('ci:playwright:worker:report', (serializedTraces) => {
@@ -254,6 +261,7 @@ class PlaywrightPlugin extends CiPlugin {
254
261
  })
255
262
 
256
263
  this.addSub('ci:playwright:test:finish', ({
264
+ span,
257
265
  testStatus,
258
266
  steps,
259
267
  error,
@@ -267,11 +275,10 @@ class PlaywrightPlugin extends CiPlugin {
267
275
  isAttemptToFixRetry,
268
276
  hasFailedAllRetries,
269
277
  hasPassedAttemptToFixRetries,
278
+ hasFailedAttemptToFixRetries,
270
279
  isAtrRetry,
271
280
  onDone
272
281
  }) => {
273
- const store = storage('legacy').getStore()
274
- const span = store && store.span
275
282
  if (!span) return
276
283
 
277
284
  const isRUMActive = span.context()._tags[TEST_IS_RUM_ACTIVE]
@@ -311,6 +318,8 @@ class PlaywrightPlugin extends CiPlugin {
311
318
  }
312
319
  if (hasPassedAttemptToFixRetries) {
313
320
  span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'true')
321
+ } else if (hasFailedAttemptToFixRetries) {
322
+ span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'false')
314
323
  }
315
324
  if (isDisabled) {
316
325
  span.setTag(TEST_MANAGEMENT_IS_DISABLED, 'true')
@@ -8,6 +8,11 @@ class RedisPlugin extends CachePlugin {
8
8
  static get id () { return 'redis' }
9
9
  static get system () { return 'redis' }
10
10
 
11
+ constructor (...args) {
12
+ super(...args)
13
+ this._spanType = 'redis'
14
+ }
15
+
11
16
  start ({ db, command, args, connectionOptions = {}, connectionName }) {
12
17
  const resource = command
13
18
  const normalizedCommand = command.toUpperCase()
@@ -16,11 +21,11 @@ class RedisPlugin extends CachePlugin {
16
21
  this.startSpan({
17
22
  resource,
18
23
  service: this.serviceName({ pluginConfig: this.config, system: this.system, connectionName }),
19
- type: 'redis',
24
+ type: this._spanType,
20
25
  meta: {
21
- 'db.type': 'redis',
26
+ 'db.type': this._spanType,
22
27
  'db.name': db || '0',
23
- 'redis.raw_command': formatCommand(normalizedCommand, args),
28
+ [`${this._spanType}.raw_command`]: formatCommand(normalizedCommand, args),
24
29
  'out.host': connectionOptions.host,
25
30
  [CLIENT_PORT_KEY]: connectionOptions.port
26
31
  }
@@ -95,19 +95,21 @@ class VitestPlugin extends CiPlugin {
95
95
  onDone(isFaulty)
96
96
  })
97
97
 
98
- this.addSub('ci:vitest:test:start', ({
99
- testName,
100
- testSuiteAbsolutePath,
101
- isRetry,
102
- isNew,
103
- isAttemptToFix,
104
- isQuarantined,
105
- isDisabled,
106
- mightHitProbe,
107
- isRetryReasonEfd,
108
- isRetryReasonAttemptToFix,
109
- isRetryReasonAtr
110
- }) => {
98
+ this.addBind('ci:vitest:test:start', (ctx) => {
99
+ const {
100
+ testName,
101
+ testSuiteAbsolutePath,
102
+ isRetry,
103
+ isNew,
104
+ isAttemptToFix,
105
+ isQuarantined,
106
+ isDisabled,
107
+ mightHitProbe,
108
+ isRetryReasonEfd,
109
+ isRetryReasonAttemptToFix,
110
+ isRetryReasonAtr
111
+ } = ctx
112
+
111
113
  const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
112
114
  const store = storage('legacy').getStore()
113
115
 
@@ -146,18 +148,21 @@ class VitestPlugin extends CiPlugin {
146
148
  extraTags
147
149
  )
148
150
 
149
- this.enter(span, store)
151
+ ctx.parentStore = store
152
+ ctx.currentStore = { ...store, span }
150
153
 
151
154
  // TODO: there might be multiple tests for which mightHitProbe is true, so activeTestSpan
152
155
  // might be wrongly overwritten.
153
156
  if (mightHitProbe) {
154
157
  this.activeTestSpan = span
155
158
  }
159
+
160
+ return ctx.currentStore
156
161
  })
157
162
 
158
- this.addSub('ci:vitest:test:finish-time', ({ status, task, attemptToFixPassed }) => {
159
- const store = storage('legacy').getStore()
160
- const span = store?.span
163
+ this.addBind('ci:vitest:test:finish-time', (ctx) => {
164
+ const { status, task, attemptToFixPassed, attemptToFixFailed } = ctx
165
+ const span = ctx.currentStore?.span
161
166
 
162
167
  // we store the finish time to finish at a later hook
163
168
  // this is because the test might fail at a `afterEach` hook
@@ -166,16 +171,20 @@ class VitestPlugin extends CiPlugin {
166
171
 
167
172
  if (attemptToFixPassed) {
168
173
  span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'true')
174
+ } else if (attemptToFixFailed) {
175
+ span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'false')
169
176
  }
170
177
 
171
178
  this.taskToFinishTime.set(task, span._getTime())
179
+
180
+ ctx.parentStore = ctx.currentStore
181
+ ctx.currentStore = { ...ctx.currentStore, span }
172
182
  }
173
- })
174
183
 
175
- this.addSub('ci:vitest:test:pass', ({ task }) => {
176
- const store = storage('legacy').getStore()
177
- const span = store?.span
184
+ return ctx.currentStore
185
+ })
178
186
 
187
+ this.addSub('ci:vitest:test:pass', ({ span, task }) => {
179
188
  if (span) {
180
189
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test', {
181
190
  hasCodeowners: !!span.context()._tags[TEST_CODE_OWNERS]
@@ -186,10 +195,15 @@ class VitestPlugin extends CiPlugin {
186
195
  }
187
196
  })
188
197
 
189
- this.addSub('ci:vitest:test:error', ({ duration, error, shouldSetProbe, promises, hasFailedAllRetries }) => {
190
- const store = storage('legacy').getStore()
191
- const span = store?.span
192
-
198
+ this.addSub('ci:vitest:test:error', ({
199
+ span,
200
+ duration,
201
+ error,
202
+ shouldSetProbe,
203
+ promises,
204
+ hasFailedAllRetries,
205
+ attemptToFixFailed
206
+ }) => {
193
207
  if (span) {
194
208
  if (shouldSetProbe && this.di) {
195
209
  const probeInformation = this.addDiProbe(error)
@@ -211,6 +225,9 @@ class VitestPlugin extends CiPlugin {
211
225
  if (hasFailedAllRetries) {
212
226
  span.setTag(TEST_HAS_FAILED_ALL_RETRIES, 'true')
213
227
  }
228
+ if (attemptToFixFailed) {
229
+ span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'false')
230
+ }
214
231
  if (duration) {
215
232
  span.finish(span._startTime + duration - MILLISECONDS_TO_SUBTRACT_FROM_FAILED_TEST_DURATION) // milliseconds
216
233
  } else {
@@ -240,10 +257,9 @@ class VitestPlugin extends CiPlugin {
240
257
  testSpan.finish()
241
258
  })
242
259
 
243
- this.addSub('ci:vitest:test-suite:start', ({
244
- testSuiteAbsolutePath,
245
- frameworkVersion
246
- }) => {
260
+ this.addBind('ci:vitest:test-suite:start', (ctx) => {
261
+ const { testSuiteAbsolutePath, frameworkVersion } = ctx
262
+
247
263
  this.command = process.env.DD_CIVISIBILITY_TEST_COMMAND
248
264
  this.frameworkVersion = frameworkVersion
249
265
  const testSessionSpanContext = this.tracer.extract('text_map', {
@@ -293,17 +309,18 @@ class VitestPlugin extends CiPlugin {
293
309
  })
294
310
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
295
311
  const store = storage('legacy').getStore()
296
- this.enter(testSuiteSpan, store)
312
+ ctx.parentStore = store
313
+ ctx.currentStore = { ...store, testSuiteSpan }
297
314
  this.testSuiteSpan = testSuiteSpan
315
+
316
+ return ctx.currentStore
298
317
  })
299
318
 
300
- this.addSub('ci:vitest:test-suite:finish', ({ status, onFinish }) => {
301
- const store = storage('legacy').getStore()
302
- const span = store?.span
303
- if (span) {
304
- span.setTag(TEST_STATUS, status)
305
- span.finish()
306
- finishAllTraceSpans(span)
319
+ this.addSub('ci:vitest:test-suite:finish', ({ testSuiteSpan, status, onFinish }) => {
320
+ if (testSuiteSpan) {
321
+ testSuiteSpan.setTag(TEST_STATUS, status)
322
+ testSuiteSpan.finish()
323
+ finishAllTraceSpans(testSuiteSpan)
307
324
  }
308
325
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
309
326
  // TODO: too frequent flush - find for method in worker to decrease frequency
@@ -313,13 +330,19 @@ class VitestPlugin extends CiPlugin {
313
330
  }
314
331
  })
315
332
 
316
- this.addSub('ci:vitest:test-suite:error', ({ error }) => {
317
- const store = storage('legacy').getStore()
318
- const span = store?.span
319
- if (span && error) {
320
- span.setTag('error', error)
321
- span.setTag(TEST_STATUS, 'fail')
333
+ this.addBind('ci:vitest:test-suite:error', (ctx) => {
334
+ const { error } = ctx
335
+ const testSuiteSpan = ctx.currentStore?.testSuiteSpan
336
+
337
+ if (testSuiteSpan && error) {
338
+ testSuiteSpan.setTag('error', error)
339
+ testSuiteSpan.setTag(TEST_STATUS, 'fail')
340
+
341
+ ctx.parentStore = ctx.currentStore
342
+ ctx.currentStore = { ...ctx.currentStore, testSuiteSpan }
322
343
  }
344
+
345
+ return ctx.currentStore
323
346
  })
324
347
 
325
348
  this.addSub('ci:vitest:session:finish', ({
@@ -337,7 +360,7 @@ class VitestPlugin extends CiPlugin {
337
360
  this.testModuleSpan.setTag('error', error)
338
361
  this.testSessionSpan.setTag('error', error)
339
362
  }
340
- if (testCodeCoverageLinesTotal) {
363
+ if (testCodeCoverageLinesTotal !== undefined) {
341
364
  this.testModuleSpan.setTag(TEST_CODE_COVERAGE_LINES_PCT, testCodeCoverageLinesTotal)
342
365
  this.testSessionSpan.setTag(TEST_CODE_COVERAGE_LINES_PCT, testCodeCoverageLinesTotal)
343
366
  }