dd-trace 5.20.0 → 5.22.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 (108) hide show
  1. package/index.d.ts +2 -1
  2. package/package.json +6 -6
  3. package/packages/datadog-instrumentations/src/aerospike.js +1 -1
  4. package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
  5. package/packages/datadog-instrumentations/src/aws-sdk.js +4 -4
  6. package/packages/datadog-instrumentations/src/body-parser.js +17 -5
  7. package/packages/datadog-instrumentations/src/cassandra-driver.js +2 -2
  8. package/packages/datadog-instrumentations/src/child_process.js +2 -2
  9. package/packages/datadog-instrumentations/src/connect.js +4 -4
  10. package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
  11. package/packages/datadog-instrumentations/src/couchbase.js +12 -12
  12. package/packages/datadog-instrumentations/src/cucumber.js +16 -5
  13. package/packages/datadog-instrumentations/src/dns.js +10 -10
  14. package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
  15. package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +3 -3
  16. package/packages/datadog-instrumentations/src/express.js +4 -4
  17. package/packages/datadog-instrumentations/src/fastify.js +6 -6
  18. package/packages/datadog-instrumentations/src/fetch.js +1 -1
  19. package/packages/datadog-instrumentations/src/find-my-way.js +2 -2
  20. package/packages/datadog-instrumentations/src/fs.js +2 -2
  21. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +2 -2
  22. package/packages/datadog-instrumentations/src/grpc/client.js +4 -6
  23. package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
  24. package/packages/datadog-instrumentations/src/hapi.js +10 -13
  25. package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -2
  26. package/packages/datadog-instrumentations/src/helpers/register.js +9 -2
  27. package/packages/datadog-instrumentations/src/http/client.js +3 -3
  28. package/packages/datadog-instrumentations/src/jest.js +5 -4
  29. package/packages/datadog-instrumentations/src/knex.js +2 -2
  30. package/packages/datadog-instrumentations/src/koa.js +5 -5
  31. package/packages/datadog-instrumentations/src/ldapjs.js +1 -1
  32. package/packages/datadog-instrumentations/src/mariadb.js +8 -8
  33. package/packages/datadog-instrumentations/src/memcached.js +2 -2
  34. package/packages/datadog-instrumentations/src/microgateway-core.js +4 -4
  35. package/packages/datadog-instrumentations/src/mocha/common.js +1 -1
  36. package/packages/datadog-instrumentations/src/mocha/main.js +91 -70
  37. package/packages/datadog-instrumentations/src/mocha/utils.js +2 -3
  38. package/packages/datadog-instrumentations/src/mocha.js +4 -0
  39. package/packages/datadog-instrumentations/src/moleculer/server.js +2 -2
  40. package/packages/datadog-instrumentations/src/mongodb-core.js +7 -7
  41. package/packages/datadog-instrumentations/src/mongoose.js +5 -6
  42. package/packages/datadog-instrumentations/src/mysql.js +3 -3
  43. package/packages/datadog-instrumentations/src/mysql2.js +6 -6
  44. package/packages/datadog-instrumentations/src/net.js +2 -2
  45. package/packages/datadog-instrumentations/src/next.js +5 -5
  46. package/packages/datadog-instrumentations/src/nyc.js +23 -0
  47. package/packages/datadog-instrumentations/src/openai.js +58 -69
  48. package/packages/datadog-instrumentations/src/oracledb.js +8 -8
  49. package/packages/datadog-instrumentations/src/passport-http.js +1 -1
  50. package/packages/datadog-instrumentations/src/passport-local.js +1 -1
  51. package/packages/datadog-instrumentations/src/passport-utils.js +1 -1
  52. package/packages/datadog-instrumentations/src/pg.js +1 -1
  53. package/packages/datadog-instrumentations/src/pino.js +4 -4
  54. package/packages/datadog-instrumentations/src/playwright.js +6 -4
  55. package/packages/datadog-instrumentations/src/redis.js +2 -2
  56. package/packages/datadog-instrumentations/src/restify.js +4 -4
  57. package/packages/datadog-instrumentations/src/rhea.js +4 -4
  58. package/packages/datadog-instrumentations/src/router.js +5 -5
  59. package/packages/datadog-instrumentations/src/sharedb.js +2 -2
  60. package/packages/datadog-instrumentations/src/vitest.js +22 -5
  61. package/packages/datadog-instrumentations/src/winston.js +2 -3
  62. package/packages/datadog-plugin-cucumber/src/index.js +12 -2
  63. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +21 -10
  64. package/packages/datadog-plugin-hapi/src/index.js +2 -2
  65. package/packages/datadog-plugin-jest/src/index.js +18 -4
  66. package/packages/datadog-plugin-mocha/src/index.js +25 -6
  67. package/packages/datadog-plugin-nyc/src/index.js +35 -0
  68. package/packages/datadog-plugin-openai/src/index.js +58 -47
  69. package/packages/datadog-plugin-playwright/src/index.js +9 -4
  70. package/packages/datadog-plugin-vitest/src/index.js +30 -4
  71. package/packages/datadog-shimmer/src/shimmer.js +144 -10
  72. package/packages/dd-trace/src/appsec/blocking.js +23 -17
  73. package/packages/dd-trace/src/appsec/graphql.js +3 -1
  74. package/packages/dd-trace/src/appsec/iast/iast-log.js +2 -1
  75. package/packages/dd-trace/src/appsec/remote_config/manager.js +4 -1
  76. package/packages/dd-trace/src/appsec/rule_manager.js +8 -0
  77. package/packages/dd-trace/src/appsec/telemetry.js +3 -3
  78. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +40 -1
  79. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -4
  80. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -4
  81. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +2 -1
  82. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +8 -7
  83. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -4
  84. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -4
  85. package/packages/dd-trace/src/ci-visibility/telemetry.js +29 -2
  86. package/packages/dd-trace/src/config.js +157 -142
  87. package/packages/dd-trace/src/lambda/handler.js +1 -0
  88. package/packages/dd-trace/src/lambda/index.js +12 -1
  89. package/packages/dd-trace/src/opentelemetry/context_manager.js +22 -39
  90. package/packages/dd-trace/src/opentelemetry/span_context.js +2 -2
  91. package/packages/dd-trace/src/opentelemetry/tracer.js +23 -14
  92. package/packages/dd-trace/src/opentelemetry/tracer_provider.js +9 -1
  93. package/packages/dd-trace/src/opentracing/propagation/log.js +1 -1
  94. package/packages/dd-trace/src/opentracing/propagation/text_map.js +61 -6
  95. package/packages/dd-trace/src/opentracing/span_context.js +1 -0
  96. package/packages/dd-trace/src/plugins/ci_plugin.js +2 -2
  97. package/packages/dd-trace/src/plugins/index.js +1 -0
  98. package/packages/dd-trace/src/plugins/util/git.js +14 -1
  99. package/packages/dd-trace/src/plugins/util/test.js +1 -5
  100. package/packages/dd-trace/src/profiler.js +15 -5
  101. package/packages/dd-trace/src/profiling/config.js +2 -4
  102. package/packages/dd-trace/src/profiling/exporter_cli.js +13 -1
  103. package/packages/dd-trace/src/profiling/exporters/agent.js +7 -1
  104. package/packages/dd-trace/src/profiling/profiler.js +0 -9
  105. package/packages/dd-trace/src/profiling/ssi-heuristics.js +49 -58
  106. package/packages/dd-trace/src/proxy.js +21 -21
  107. package/packages/dd-trace/src/telemetry/index.js +24 -7
  108. package/packages/dd-trace/src/telemetry/logs/index.js +20 -0
@@ -40,7 +40,7 @@ function wrapMiddleware (middleware) {
40
40
  function wrapFn (fn) {
41
41
  if (Array.isArray(fn)) return wrapMiddleware(fn)
42
42
 
43
- return function (req, res, next) {
43
+ return shimmer.wrapFunction(fn, fn => function (req, res, next) {
44
44
  if (typeof next === 'function') {
45
45
  arguments[2] = wrapNext(req, next)
46
46
  }
@@ -72,16 +72,16 @@ function wrapFn (fn) {
72
72
  } finally {
73
73
  exitChannel.publish({ req })
74
74
  }
75
- }
75
+ })
76
76
  }
77
77
 
78
78
  function wrapNext (req, next) {
79
- return function () {
79
+ return shimmer.wrapFunction(next, next => function () {
80
80
  nextChannel.publish({ req })
81
81
  finishChannel.publish({ req })
82
82
 
83
83
  next.apply(this, arguments)
84
- }
84
+ })
85
85
  }
86
86
 
87
87
  addHook({ name: 'restify', versions: ['>=3'], file: 'lib/server.js' }, Server => {
@@ -153,11 +153,11 @@ function wrapDeliveryUpdate (obj, update) {
153
153
  const asyncResource = context.asyncResource
154
154
  if (obj && asyncResource) {
155
155
  const cb = asyncResource.bind(update)
156
- return AsyncResource.bind(function wrappedUpdate (settled, stateData) {
156
+ return shimmer.wrapFunction(cb, cb => AsyncResource.bind(function wrappedUpdate (settled, stateData) {
157
157
  const state = getStateFromData(stateData)
158
158
  dispatchReceiveCh.publish({ state })
159
159
  return cb.apply(this, arguments)
160
- })
160
+ }))
161
161
  }
162
162
  return function wrappedUpdate (settled, stateData) {
163
163
  return update.apply(this, arguments)
@@ -178,7 +178,7 @@ function patchCircularBuffer (proto, Session) {
178
178
  }
179
179
  if (CircularBuffer && !patched.has(CircularBuffer.prototype)) {
180
180
  shimmer.wrap(CircularBuffer.prototype, 'pop_if', popIf => function (fn) {
181
- arguments[0] = AsyncResource.bind(function (entry) {
181
+ arguments[0] = shimmer.wrapFunction(fn, fn => AsyncResource.bind(function (entry) {
182
182
  const context = contexts.get(entry)
183
183
  const asyncResource = context && context.asyncResource
184
184
 
@@ -198,7 +198,7 @@ function patchCircularBuffer (proto, Session) {
198
198
  }
199
199
 
200
200
  return shouldPop
201
- })
201
+ }))
202
202
  return popIf.apply(this, arguments)
203
203
  })
204
204
  patched.add(CircularBuffer.prototype)
@@ -18,7 +18,7 @@ function createWrapRouterMethod (name) {
18
18
  function wrapLayerHandle (layer, original) {
19
19
  original._name = original._name || layer.name
20
20
 
21
- const handle = shimmer.wrap(original, function () {
21
+ const handle = shimmer.wrapFunction(original, original => function () {
22
22
  if (!enterChannel.hasSubscribers) return original.apply(this, arguments)
23
23
 
24
24
  const matchers = layerMatchers.get(layer)
@@ -89,7 +89,7 @@ function createWrapRouterMethod (name) {
89
89
  }
90
90
 
91
91
  function wrapNext (req, next) {
92
- return function (error) {
92
+ return shimmer.wrapFunction(next, next => function (error) {
93
93
  if (error && error !== 'route' && error !== 'router') {
94
94
  errorChannel.publish({ req, error })
95
95
  }
@@ -98,7 +98,7 @@ function createWrapRouterMethod (name) {
98
98
  finishChannel.publish({ req })
99
99
 
100
100
  next.apply(this, arguments)
101
- }
101
+ })
102
102
  }
103
103
 
104
104
  function extractMatchers (fn) {
@@ -151,7 +151,7 @@ function createWrapRouterMethod (name) {
151
151
  }
152
152
 
153
153
  function wrapMethod (original) {
154
- return function methodWithTrace (fn) {
154
+ return shimmer.wrapFunction(original, original => function methodWithTrace (fn) {
155
155
  const offset = this.stack ? [].concat(this.stack).length : 0
156
156
  const router = original.apply(this, arguments)
157
157
 
@@ -162,7 +162,7 @@ function createWrapRouterMethod (name) {
162
162
  wrapStack(this.stack, offset, extractMatchers(fn))
163
163
 
164
164
  return router
165
- }
165
+ })
166
166
  }
167
167
 
168
168
  return wrapMethod
@@ -48,14 +48,14 @@ addHook({ name: 'sharedb', versions: ['>=1'], file: 'lib/agent.js' }, Agent => {
48
48
 
49
49
  callback = callbackResource.bind(callback)
50
50
 
51
- arguments[1] = asyncResource.bind(function (error, res) {
51
+ arguments[1] = shimmer.wrapFunction(callback, callback => asyncResource.bind(function (error, res) {
52
52
  if (error) {
53
53
  errorCh.publish(error)
54
54
  }
55
55
  finishCh.publish({ request, res })
56
56
 
57
57
  return callback.apply(this, arguments)
58
- })
58
+ }))
59
59
 
60
60
  try {
61
61
  return origHandleMessageFn.apply(this, arguments)
@@ -1,6 +1,5 @@
1
1
  const { addHook, channel, AsyncResource } = require('./helpers/instrument')
2
2
  const shimmer = require('../../datadog-shimmer')
3
- const { NUM_FAILED_TEST_RETRIES } = require('../../dd-trace/src/plugins/util/test')
4
3
 
5
4
  // test hooks
6
5
  const testStartCh = channel('ci:vitest:test:start')
@@ -108,17 +107,34 @@ function getSortWrapper (sort) {
108
107
  // So we will use the sort from BaseSequencer. This means that a custom sequencer
109
108
  // will not work. This will be a known limitation.
110
109
  let isFlakyTestRetriesEnabled = false
110
+ let flakyTestRetriesCount = 0
111
111
 
112
112
  try {
113
113
  const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh)
114
114
  if (!err) {
115
115
  isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
116
+ flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
116
117
  }
117
118
  } catch (e) {
118
119
  isFlakyTestRetriesEnabled = false
119
120
  }
120
- if (isFlakyTestRetriesEnabled && !this.ctx.config.retry) {
121
- this.ctx.config.retry = NUM_FAILED_TEST_RETRIES
121
+ if (isFlakyTestRetriesEnabled && !this.ctx.config.retry && flakyTestRetriesCount > 0) {
122
+ this.ctx.config.retry = flakyTestRetriesCount
123
+ }
124
+
125
+ let testCodeCoverageLinesTotal
126
+
127
+ if (this.ctx.coverageProvider?.generateCoverage) {
128
+ shimmer.wrap(this.ctx.coverageProvider, 'generateCoverage', generateCoverage => async function () {
129
+ const totalCodeCoverage = await generateCoverage.apply(this, arguments)
130
+
131
+ try {
132
+ testCodeCoverageLinesTotal = totalCodeCoverage.getCoverageSummary().lines.pct
133
+ } catch (e) {
134
+ // ignore errors
135
+ }
136
+ return totalCodeCoverage
137
+ })
122
138
  }
123
139
 
124
140
  shimmer.wrap(this.ctx, 'exit', exit => async function () {
@@ -136,8 +152,9 @@ function getSortWrapper (sort) {
136
152
  sessionAsyncResource.runInAsyncScope(() => {
137
153
  testSessionFinishCh.publish({
138
154
  status: getSessionStatus(this.state),
139
- onFinish,
140
- error
155
+ testCodeCoverageLinesTotal,
156
+ error,
157
+ onFinish
141
158
  })
142
159
  })
143
160
 
@@ -42,13 +42,12 @@ function wrapMethod (method, logCh) {
42
42
 
43
43
  if (patched.has(transport) || typeof transport.log !== 'function') continue
44
44
 
45
- const log = transport.log
46
- transport.log = function wrappedLog (level, msg, meta, callback) {
45
+ shimmer.wrap(transport, 'log', log => function wrappedLog (level, msg, meta, callback) {
47
46
  const payload = { message: meta || {} }
48
47
  logCh.publish(payload)
49
48
  arguments[2] = payload.message
50
49
  log.apply(this, arguments)
51
- }
50
+ })
52
51
  patched.add(transport)
53
52
  }
54
53
  }
@@ -37,7 +37,10 @@ const {
37
37
  TELEMETRY_ITR_FORCED_TO_RUN,
38
38
  TELEMETRY_CODE_COVERAGE_EMPTY,
39
39
  TELEMETRY_ITR_UNSKIPPABLE,
40
- TELEMETRY_CODE_COVERAGE_NUM_FILES
40
+ TELEMETRY_CODE_COVERAGE_NUM_FILES,
41
+ TEST_IS_RUM_ACTIVE,
42
+ TEST_BROWSER_DRIVER,
43
+ TELEMETRY_TEST_SESSION
41
44
  } = require('../../dd-trace/src/ci-visibility/telemetry')
42
45
  const id = require('../../dd-trace/src/id')
43
46
 
@@ -107,6 +110,7 @@ class CucumberPlugin extends CiPlugin {
107
110
  this.testSessionSpan.finish()
108
111
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
109
112
  finishAllTraceSpans(this.testSessionSpan)
113
+ this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
110
114
 
111
115
  this.libraryConfig = null
112
116
  this.tracer._exporter.flush()
@@ -285,10 +289,16 @@ class CucumberPlugin extends CiPlugin {
285
289
 
286
290
  span.finish()
287
291
  if (!isStep) {
292
+ const spanTags = span.context()._tags
288
293
  this.telemetry.ciVisEvent(
289
294
  TELEMETRY_EVENT_FINISHED,
290
295
  'test',
291
- { hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
296
+ {
297
+ hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
298
+ isNew,
299
+ isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
300
+ browserDriver: spanTags[TEST_BROWSER_DRIVER]
301
+ }
292
302
  )
293
303
  finishAllTraceSpans(span)
294
304
  // If it's a worker, flushing is cheap, as it's just sending data to the main process
@@ -28,8 +28,7 @@ const {
28
28
  TEST_SOURCE_FILE,
29
29
  TEST_IS_NEW,
30
30
  TEST_IS_RETRY,
31
- TEST_EARLY_FLAKE_ENABLED,
32
- NUM_FAILED_TEST_RETRIES
31
+ TEST_EARLY_FLAKE_ENABLED
33
32
  } = require('../../dd-trace/src/plugins/util/test')
34
33
  const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')
35
34
  const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
@@ -44,7 +43,9 @@ const {
44
43
  TELEMETRY_ITR_UNSKIPPABLE,
45
44
  TELEMETRY_CODE_COVERAGE_NUM_FILES,
46
45
  incrementCountMetric,
47
- distributionMetric
46
+ distributionMetric,
47
+ TELEMETRY_ITR_SKIPPED,
48
+ TELEMETRY_TEST_SESSION
48
49
  } = require('../../dd-trace/src/ci-visibility/telemetry')
49
50
 
50
51
  const {
@@ -179,7 +180,7 @@ class CypressPlugin {
179
180
  } = this.testEnvironmentMetadata
180
181
 
181
182
  this.repositoryRoot = repositoryRoot
182
- this.isUnsupportedCIProvider = !ciProviderName
183
+ this.ciProviderName = ciProviderName
183
184
  this.codeOwnersEntries = getCodeOwnersFileEntries(repositoryRoot)
184
185
 
185
186
  this.testConfiguration = {
@@ -227,16 +228,16 @@ class CypressPlugin {
227
228
  isCodeCoverageEnabled,
228
229
  isEarlyFlakeDetectionEnabled,
229
230
  earlyFlakeDetectionNumRetries,
230
- isFlakyTestRetriesEnabled
231
+ isFlakyTestRetriesEnabled,
232
+ flakyTestRetriesCount
231
233
  }
232
234
  } = libraryConfigurationResponse
233
235
  this.isSuitesSkippingEnabled = isSuitesSkippingEnabled
234
236
  this.isCodeCoverageEnabled = isCodeCoverageEnabled
235
237
  this.isEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
236
238
  this.earlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
237
- this.isFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
238
- if (this.isFlakyTestRetriesEnabled) {
239
- this.cypressConfig.retries.runMode = NUM_FAILED_TEST_RETRIES
239
+ if (isFlakyTestRetriesEnabled) {
240
+ this.cypressConfig.retries.runMode = flakyTestRetriesCount
240
241
  }
241
242
  }
242
243
  return this.cypressConfig
@@ -321,7 +322,7 @@ class CypressPlugin {
321
322
  incrementCountMetric(name, {
322
323
  testLevel,
323
324
  testFramework: 'cypress',
324
- isUnsupportedCIProvider: this.isUnsupportedCIProvider,
325
+ isUnsupportedCIProvider: !this.ciProviderName,
325
326
  ...tags
326
327
  })
327
328
  }
@@ -363,6 +364,7 @@ class CypressPlugin {
363
364
  const { skippableTests, correlationId } = skippableTestsResponse
364
365
  this.testsToSkip = skippableTests || []
365
366
  this.itrCorrelationId = correlationId
367
+ incrementCountMetric(TELEMETRY_ITR_SKIPPED, { testLevel: 'test' }, this.testsToSkip.length)
366
368
  }
367
369
  }
368
370
 
@@ -436,6 +438,9 @@ class CypressPlugin {
436
438
  this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
437
439
  this.testSessionSpan.finish()
438
440
  this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
441
+ incrementCountMetric(TELEMETRY_TEST_SESSION, {
442
+ provider: this.ciProviderName
443
+ })
439
444
 
440
445
  finishAllTraceSpans(this.testSessionSpan)
441
446
  }
@@ -668,8 +673,14 @@ class CypressPlugin {
668
673
  }
669
674
  // test spans are finished at after:spec
670
675
  }
676
+ this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test', {
677
+ hasCodeOwners: !!this.activeTestSpan.context()._tags[TEST_CODE_OWNERS],
678
+ isNew,
679
+ isRum: isRUMActive,
680
+ browserDriver: 'cypress'
681
+ })
671
682
  this.activeTestSpan = null
672
- this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test')
683
+
673
684
  return null
674
685
  },
675
686
  'dd:addTags': (tags) => {
@@ -32,8 +32,8 @@ class HapiPlugin extends RouterPlugin {
32
32
  }
33
33
  })
34
34
 
35
- this.addSub('apm:hapi:extension:enter', ({ req }) => {
36
- this.enter(this._requestSpans.get(req))
35
+ this.addBind('apm:hapi:extension:start', ({ req }) => {
36
+ return this._requestSpans.get(req)
37
37
  })
38
38
  }
39
39
  }
@@ -20,7 +20,9 @@ const {
20
20
  TEST_IS_RETRY,
21
21
  TEST_EARLY_FLAKE_ENABLED,
22
22
  TEST_EARLY_FLAKE_ABORT_REASON,
23
- JEST_DISPLAY_NAME
23
+ JEST_DISPLAY_NAME,
24
+ TEST_IS_RUM_ACTIVE,
25
+ TEST_BROWSER_DRIVER
24
26
  } = require('../../dd-trace/src/plugins/util/test')
25
27
  const { COMPONENT } = require('../../dd-trace/src/constants')
26
28
  const id = require('../../dd-trace/src/id')
@@ -32,7 +34,8 @@ const {
32
34
  TELEMETRY_ITR_FORCED_TO_RUN,
33
35
  TELEMETRY_CODE_COVERAGE_EMPTY,
34
36
  TELEMETRY_ITR_UNSKIPPABLE,
35
- TELEMETRY_CODE_COVERAGE_NUM_FILES
37
+ TELEMETRY_CODE_COVERAGE_NUM_FILES,
38
+ TELEMETRY_TEST_SESSION
36
39
  } = require('../../dd-trace/src/ci-visibility/telemetry')
37
40
 
38
41
  const isJestWorker = !!process.env.JEST_WORKER_ID
@@ -129,6 +132,8 @@ class JestPlugin extends CiPlugin {
129
132
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
130
133
  finishAllTraceSpans(this.testSessionSpan)
131
134
 
135
+ this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
136
+
132
137
  this.tracer._exporter.flush(() => {
133
138
  if (onDone) {
134
139
  onDone()
@@ -149,6 +154,7 @@ class JestPlugin extends CiPlugin {
149
154
  config._ddEarlyFlakeDetectionNumRetries = this.libraryConfig?.earlyFlakeDetectionNumRetries ?? 0
150
155
  config._ddRepositoryRoot = this.repositoryRoot
151
156
  config._ddIsFlakyTestRetriesEnabled = this.libraryConfig?.isFlakyTestRetriesEnabled ?? false
157
+ config._ddFlakyTestRetriesCount = this.libraryConfig?.flakyTestRetriesCount
152
158
  })
153
159
  })
154
160
 
@@ -287,12 +293,20 @@ class JestPlugin extends CiPlugin {
287
293
  if (testStartLine) {
288
294
  span.setTag(TEST_SOURCE_START, testStartLine)
289
295
  }
290
- span.finish()
296
+
297
+ const spanTags = span.context()._tags
291
298
  this.telemetry.ciVisEvent(
292
299
  TELEMETRY_EVENT_FINISHED,
293
300
  'test',
294
- { hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
301
+ {
302
+ hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
303
+ isNew: spanTags[TEST_IS_NEW] === 'true',
304
+ isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
305
+ browserDriver: spanTags[TEST_BROWSER_DRIVER]
306
+ }
295
307
  )
308
+
309
+ span.finish()
296
310
  finishAllTraceSpans(span)
297
311
  })
298
312
 
@@ -27,7 +27,9 @@ const {
27
27
  TEST_SUITE_ID,
28
28
  TEST_COMMAND,
29
29
  TEST_SUITE,
30
- MOCHA_IS_PARALLEL
30
+ MOCHA_IS_PARALLEL,
31
+ TEST_IS_RUM_ACTIVE,
32
+ TEST_BROWSER_DRIVER
31
33
  } = require('../../dd-trace/src/plugins/util/test')
32
34
  const { COMPONENT } = require('../../dd-trace/src/constants')
33
35
  const {
@@ -38,7 +40,8 @@ const {
38
40
  TELEMETRY_ITR_FORCED_TO_RUN,
39
41
  TELEMETRY_CODE_COVERAGE_EMPTY,
40
42
  TELEMETRY_ITR_UNSKIPPABLE,
41
- TELEMETRY_CODE_COVERAGE_NUM_FILES
43
+ TELEMETRY_CODE_COVERAGE_NUM_FILES,
44
+ TELEMETRY_TEST_SESSION
42
45
  } = require('../../dd-trace/src/ci-visibility/telemetry')
43
46
  const id = require('../../dd-trace/src/id')
44
47
  const log = require('../../dd-trace/src/log')
@@ -184,12 +187,20 @@ class MochaPlugin extends CiPlugin {
184
187
  if (hasBeenRetried) {
185
188
  span.setTag(TEST_IS_RETRY, 'true')
186
189
  }
187
- span.finish()
190
+
191
+ const spanTags = span.context()._tags
188
192
  this.telemetry.ciVisEvent(
189
193
  TELEMETRY_EVENT_FINISHED,
190
194
  'test',
191
- { hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
195
+ {
196
+ hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
197
+ isNew: spanTags[TEST_IS_NEW] === 'true',
198
+ isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
199
+ browserDriver: spanTags[TEST_BROWSER_DRIVER]
200
+ }
192
201
  )
202
+
203
+ span.finish()
193
204
  finishAllTraceSpans(span)
194
205
  }
195
206
  })
@@ -226,12 +237,19 @@ class MochaPlugin extends CiPlugin {
226
237
  span.setTag(TEST_IS_RETRY, 'true')
227
238
  }
228
239
 
229
- span.finish()
240
+ const spanTags = span.context()._tags
230
241
  this.telemetry.ciVisEvent(
231
242
  TELEMETRY_EVENT_FINISHED,
232
243
  'test',
233
- { hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
244
+ {
245
+ hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
246
+ isNew: spanTags[TEST_IS_NEW] === 'true',
247
+ isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
248
+ browserDriver: spanTags[TEST_BROWSER_DRIVER]
249
+ }
234
250
  )
251
+
252
+ span.finish()
235
253
  finishAllTraceSpans(span)
236
254
  }
237
255
  })
@@ -289,6 +307,7 @@ class MochaPlugin extends CiPlugin {
289
307
  this.testSessionSpan.finish()
290
308
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
291
309
  finishAllTraceSpans(this.testSessionSpan)
310
+ this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
292
311
  }
293
312
  this.libraryConfig = null
294
313
  this.tracer._exporter.flush()
@@ -0,0 +1,35 @@
1
+ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
2
+
3
+ class NycPlugin extends CiPlugin {
4
+ static get id () {
5
+ return 'nyc'
6
+ }
7
+
8
+ constructor (...args) {
9
+ super(...args)
10
+
11
+ this.addSub('ci:nyc:wrap', (nyc) => {
12
+ if (nyc?.config?.all) {
13
+ this.nyc = nyc
14
+ }
15
+ })
16
+
17
+ this.addSub('ci:nyc:get-coverage', ({ onDone }) => {
18
+ if (this.nyc?.getCoverageMapFromAllCoverageFiles) {
19
+ this.nyc.getCoverageMapFromAllCoverageFiles()
20
+ .then((untestedCoverageMap) => {
21
+ this.nyc = null
22
+ onDone(untestedCoverageMap)
23
+ }).catch((e) => {
24
+ this.nyc = null
25
+ onDone()
26
+ })
27
+ } else {
28
+ this.nyc = null
29
+ onDone()
30
+ }
31
+ })
32
+ }
33
+ }
34
+
35
+ module.exports = NycPlugin