dd-trace 3.1.0 → 3.3.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 (61) hide show
  1. package/LICENSE-3rdparty.csv +2 -0
  2. package/README.md +4 -0
  3. package/ext/tags.d.ts +2 -1
  4. package/ext/tags.js +2 -1
  5. package/index.d.ts +43 -20
  6. package/package.json +6 -4
  7. package/packages/datadog-instrumentations/src/crypto.js +32 -0
  8. package/packages/datadog-instrumentations/src/grpc/server.js +15 -7
  9. package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
  10. package/packages/datadog-instrumentations/src/http/server.js +1 -1
  11. package/packages/datadog-instrumentations/src/jest.js +136 -14
  12. package/packages/datadog-instrumentations/src/mocha.js +77 -31
  13. package/packages/datadog-instrumentations/src/net.js +13 -0
  14. package/packages/datadog-instrumentations/src/next.js +7 -3
  15. package/packages/datadog-plugin-jest/src/index.js +106 -6
  16. package/packages/datadog-plugin-mocha/src/index.js +15 -7
  17. package/packages/datadog-plugin-mongodb-core/src/index.js +19 -10
  18. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +4 -0
  19. package/packages/dd-trace/src/appsec/iast/analyzers/index.js +20 -0
  20. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +48 -0
  21. package/packages/dd-trace/src/appsec/iast/analyzers/weak-cipher-analyzer.js +27 -0
  22. package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +24 -0
  23. package/packages/dd-trace/src/appsec/iast/iast-context.js +50 -0
  24. package/packages/dd-trace/src/appsec/iast/index.js +59 -0
  25. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +94 -0
  26. package/packages/dd-trace/src/appsec/iast/path-line.js +70 -0
  27. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +121 -0
  28. package/packages/dd-trace/src/appsec/recommended.json +1144 -275
  29. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
  30. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +3 -3
  31. package/packages/dd-trace/src/config.js +90 -10
  32. package/packages/dd-trace/src/constants.js +9 -1
  33. package/packages/dd-trace/src/encode/0.4.js +7 -1
  34. package/packages/dd-trace/src/encode/0.5.js +7 -1
  35. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +2 -2
  36. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +32 -20
  37. package/packages/dd-trace/src/encode/span-stats.js +155 -0
  38. package/packages/dd-trace/src/exporters/agent/index.js +14 -2
  39. package/packages/dd-trace/src/exporters/agent/writer.js +6 -3
  40. package/packages/dd-trace/src/exporters/common/request.js +9 -5
  41. package/packages/dd-trace/src/exporters/span-stats/index.js +20 -0
  42. package/packages/dd-trace/src/exporters/span-stats/writer.js +54 -0
  43. package/packages/dd-trace/src/format.js +2 -0
  44. package/packages/dd-trace/src/iitm.js +11 -0
  45. package/packages/dd-trace/src/opentracing/propagation/text_map.js +71 -0
  46. package/packages/dd-trace/src/opentracing/tracer.js +1 -1
  47. package/packages/dd-trace/src/plugin_manager.js +12 -2
  48. package/packages/dd-trace/src/plugins/index.js +3 -0
  49. package/packages/dd-trace/src/plugins/log_plugin.js +16 -9
  50. package/packages/dd-trace/src/plugins/util/ip_blocklist.js +51 -0
  51. package/packages/dd-trace/src/plugins/util/web.js +100 -2
  52. package/packages/dd-trace/src/priority_sampler.js +36 -1
  53. package/packages/dd-trace/src/proxy.js +3 -0
  54. package/packages/dd-trace/src/ritm.js +10 -1
  55. package/packages/dd-trace/src/span_processor.js +7 -1
  56. package/packages/dd-trace/src/span_stats.js +210 -0
  57. package/packages/dd-trace/src/telemetry/dependencies.js +83 -0
  58. package/packages/dd-trace/src/{telemetry.js → telemetry/index.js} +10 -65
  59. package/packages/dd-trace/src/telemetry/send-data.js +35 -0
  60. package/packages/dd-trace/src/plugins/util/redis.js +0 -74
  61. package/packages/dd-trace/src/plugins/util/tx.js +0 -75
@@ -7,6 +7,7 @@ require,crypto-randomuuid,MIT,Copyright 2021 Node.js Foundation and contributors
7
7
  require,diagnostics_channel,MIT,Copyright 2021 Simon D.
8
8
  require,ignore,MIT,Copyright 2013 Kael Zhang and contributors
9
9
  require,import-in-the-middle,Apache license 2.0,Copyright 2021 Datadog Inc.
10
+ require,ipaddr.js,MIT,Copyright 2011-2017 whitequark
10
11
  require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
11
12
  require,koalas,MIT,Copyright 2013-2017 Brian Woodward
12
13
  require,limiter,MIT,Copyright 2011 John Hurliman
@@ -14,6 +15,7 @@ require,lodash.kebabcase,MIT,Copyright JS Foundation and other contributors
14
15
  require,lodash.pick,MIT,Copyright JS Foundation and other contributors
15
16
  require,lodash.sortby,MIT,Copyright JS Foundation and other contributors
16
17
  require,lodash.uniq,MIT,Copyright JS Foundation and other contributors
18
+ require,lru-cache,ISC,Copyright (c) 2010-2022 Isaac Z. Schlueter and Contributors
17
19
  require,methods,MIT,Copyright 2013-2014 TJ Holowaychuk
18
20
  require,module-details-from-path,MIT,Copyright 2016 Thomas Watson Steen
19
21
  require,opentracing,MIT,Copyright 2016 Resonance Labs Inc
package/README.md CHANGED
@@ -21,6 +21,10 @@ For descriptions of terminology used in APM, take a look at the [official docume
21
21
 
22
22
  Before contributing to this open source project, read our [CONTRIBUTING.md](https://github.com/DataDog/dd-trace-js/blob/master/CONTRIBUTING.md).
23
23
 
24
+ ## Security Vulnerabilities
25
+
26
+ If you have found a security issue, please contact the security team directly at [security@datadoghq.com](mailto:security@datadoghq.com).
27
+
24
28
  ### Requirements
25
29
 
26
30
  Since this project supports multiple Node versions, using a version
package/ext/tags.d.ts CHANGED
@@ -15,7 +15,8 @@ declare const tags: {
15
15
  HTTP_ROUTE: 'http.route'
16
16
  HTTP_REQUEST_HEADERS: 'http.request.headers'
17
17
  HTTP_RESPONSE_HEADERS: 'http.response.headers'
18
- HTTP_USERAGENT: 'http.useragent'
18
+ HTTP_USERAGENT: 'http.useragent',
19
+ HTTP_CLIENT_IP: 'http.client_ip'
19
20
  }
20
21
 
21
22
  export = tags
package/ext/tags.js CHANGED
@@ -20,7 +20,8 @@ const tags = {
20
20
  HTTP_ROUTE: 'http.route',
21
21
  HTTP_REQUEST_HEADERS: 'http.request.headers',
22
22
  HTTP_RESPONSE_HEADERS: 'http.response.headers',
23
- HTTP_USERAGENT: 'http.useragent'
23
+ HTTP_USERAGENT: 'http.useragent',
24
+ HTTP_CLIENT_IP: 'http.client_ip'
24
25
  }
25
26
 
26
27
  // Deprecated
package/index.d.ts CHANGED
@@ -267,6 +267,22 @@ export declare interface TracerOptions {
267
267
  */
268
268
  sampleRate?: number;
269
269
 
270
+ /**
271
+ * Global rate limit that is applied on the global sample rate and all rules,
272
+ * and controls the ingestion rate limit between the agent and the backend.
273
+ * Defaults to deferring the decision to the agent.
274
+ */
275
+ rateLimit?: Number,
276
+
277
+ /**
278
+ * Sampling rules to apply to priority samplin. Each rule is a JSON,
279
+ * consisting of `service` and `name`, which are regexes to match against
280
+ * a trace's `service` and `name`, and a corresponding `sampleRate`. If not
281
+ * specified, will defer to global sampling rate for all spans.
282
+ * @default []
283
+ */
284
+ samplingRules?: SamplingRule[]
285
+
270
286
  /**
271
287
  * Interval in milliseconds at which the tracer will submit traces to the agent.
272
288
  * @default 2000
@@ -298,7 +314,10 @@ export declare interface TracerOptions {
298
314
  protocolVersion?: string
299
315
 
300
316
  /**
301
- * Configuration of the ingestion between the agent and the backend.
317
+ * Deprecated in favor of the global versions of the variables provided under this option
318
+ *
319
+ * @deprecated
320
+ * @hidden
302
321
  */
303
322
  ingestion?: {
304
323
  /**
@@ -307,7 +326,7 @@ export declare interface TracerOptions {
307
326
  sampleRate?: number
308
327
 
309
328
  /**
310
- * Controls the ingestion rate limit between the agent and the backend.
329
+ * Controls the ingestion rate limit between the agent and the backend. Defaults to deferring the decision to the agent.
311
330
  */
312
331
  rateLimit?: number
313
332
  };
@@ -333,32 +352,36 @@ export declare interface TracerOptions {
333
352
  exporter?: 'log' | 'agent'
334
353
 
335
354
  /**
336
- * Configuration of the priority sampler. Supports a global config and rules by span name or service name. The first matching rule is applied, and if no rule matches it falls back to the global config or on the rates provided by the agent if there is no global config.
355
+ * Whether to enable the experimental `getRumData` method.
356
+ * @default false
337
357
  */
338
- sampler?: {
358
+ enableGetRumData?: boolean
359
+
360
+ /**
361
+ * Configuration of the IAST. Can be a boolean as an alias to `iast.enabled`.
362
+ */
363
+ iast?: boolean | {
339
364
  /**
340
- * Sample rate to apply globally when no other rule is matched. Omit to fallback on the dynamic rates returned by the agent instead.
365
+ * Whether to enable IAST.
366
+ * @default false
341
367
  */
342
- sampleRate?: Number,
343
-
368
+ enabled?: boolean,
344
369
  /**
345
- * Global rate limit that is applied on the global sample rate and all rules.
346
- * @default 100
370
+ * Controls the percentage of requests that iast will analyze
371
+ * @default 30
347
372
  */
348
- rateLimit?: Number,
349
-
373
+ requestSampling?: number,
350
374
  /**
351
- * Sampling rules to apply to priority sampling.
352
- * @default []
375
+ * Controls how many request can be analyzing code vulnerabilities at the same time
376
+ * @default 2
353
377
  */
354
- rules?: SamplingRule[]
378
+ maxConcurrentRequests?: number,
379
+ /**
380
+ * Controls how many code vulnerabilities can be detected in the same request
381
+ * @default 2
382
+ */
383
+ maxContextOperations?: number
355
384
  }
356
-
357
- /**
358
- * Whether to enable the experimental `getRumData` method.
359
- * @default false
360
- */
361
- enableGetRumData?: boolean
362
385
  };
363
386
 
364
387
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -59,13 +59,14 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@datadog/native-appsec": "^1.2.1",
62
- "@datadog/native-metrics": "^1.4.2",
62
+ "@datadog/native-metrics": "^1.4.3",
63
63
  "@datadog/pprof": "^1.0.2",
64
- "@datadog/sketches-js": "^2.0.0",
64
+ "@datadog/sketches-js": "^2.1.0",
65
65
  "crypto-randomuuid": "^1.0.0",
66
66
  "diagnostics_channel": "^1.1.0",
67
67
  "ignore": "^5.2.0",
68
- "import-in-the-middle": "^1.3.0",
68
+ "import-in-the-middle": "^1.3.3",
69
+ "ipaddr.js": "^2.0.1",
69
70
  "istanbul-lib-coverage": "3.2.0",
70
71
  "koalas": "^1.0.2",
71
72
  "limiter": "^1.1.4",
@@ -73,6 +74,7 @@
73
74
  "lodash.pick": "^4.4.0",
74
75
  "lodash.sortby": "^4.7.0",
75
76
  "lodash.uniq": "^4.5.0",
77
+ "lru-cache": "^7.14.0",
76
78
  "methods": "^1.1.2",
77
79
  "module-details-from-path": "^1.0.3",
78
80
  "opentracing": ">=0.12.1",
@@ -0,0 +1,32 @@
1
+ 'use strict'
2
+
3
+ const {
4
+ channel,
5
+ addHook
6
+ } = require('./helpers/instrument')
7
+ const shimmer = require('../../datadog-shimmer')
8
+
9
+ const cryptoHashCh = channel('datadog:crypto:hashing:start')
10
+ const cryptoCipherCh = channel('datadog:crypto:cipher:start')
11
+
12
+ const hashMethods = ['createHash', 'createHmac', 'createSign', 'createVerify', 'sign', 'verify']
13
+ const cipherMethods = ['createCipheriv', 'createDecipheriv']
14
+
15
+ addHook({ name: 'crypto' }, crypto => {
16
+ shimmer.massWrap(crypto, hashMethods, wrapCryptoMethod(cryptoHashCh))
17
+ shimmer.massWrap(crypto, cipherMethods, wrapCryptoMethod(cryptoCipherCh))
18
+ return crypto
19
+ })
20
+
21
+ function wrapCryptoMethod (channel) {
22
+ function wrapMethod (cryptoMethod) {
23
+ return function () {
24
+ if (channel.hasSubscribers && arguments.length > 0) {
25
+ const algorithm = arguments[0]
26
+ channel.publish({ algorithm })
27
+ }
28
+ return cryptoMethod.apply(this, arguments)
29
+ }
30
+ }
31
+ return wrapMethod
32
+ }
@@ -37,15 +37,17 @@ function wrapHandler (func, name) {
37
37
  return requestResource.runInAsyncScope(() => {
38
38
  startChannel.publish({ name, metadata, type })
39
39
 
40
- // Finish the span if the call was cancelled.
41
- call.once('cancelled', requestResource.bind(() => {
40
+ const onCancel = requestResource.bind(() => {
42
41
  finishChannel.publish({ code: CANCELLED })
43
- }))
42
+ })
43
+
44
+ // Finish the span if the call was cancelled.
45
+ call.once('cancelled', onCancel)
44
46
 
45
47
  if (isStream) {
46
- wrapStream(call, requestResource, parentResource)
48
+ wrapStream(call, requestResource, onCancel)
47
49
  } else {
48
- arguments[1] = wrapCallback(callback, requestResource, parentResource)
50
+ arguments[1] = wrapCallback(callback, call, requestResource, parentResource, onCancel)
49
51
  }
50
52
 
51
53
  shimmer.wrap(call, 'emit', emit => requestResource.bind(emit))
@@ -65,7 +67,7 @@ function wrapRegister (register) {
65
67
  }
66
68
  }
67
69
 
68
- function wrapStream (call, requestResource) {
70
+ function wrapStream (call, requestResource, onCancel) {
69
71
  if (call.call && call.call.sendStatus) {
70
72
  call.call.sendStatus = wrapSendStatus(call.call.sendStatus, requestResource)
71
73
  }
@@ -77,6 +79,8 @@ function wrapStream (call, requestResource) {
77
79
  errorChannel.publish(args[0])
78
80
  finishChannel.publish({ code: args[0].code })
79
81
 
82
+ call.removeListener('cancelled', onCancel)
83
+
80
84
  break
81
85
 
82
86
  // Finish the span of the response only if it was successful.
@@ -90,6 +94,8 @@ function wrapStream (call, requestResource) {
90
94
  finishChannel.publish()
91
95
  }
92
96
 
97
+ call.removeListener('cancelled', onCancel)
98
+
93
99
  break
94
100
  }
95
101
 
@@ -98,7 +104,7 @@ function wrapStream (call, requestResource) {
98
104
  })
99
105
  }
100
106
 
101
- function wrapCallback (callback, requestResource, parentResource) {
107
+ function wrapCallback (callback, call, requestResource, parentResource, onCancel) {
102
108
  return function (err, value, trailer, flags) {
103
109
  requestResource.runInAsyncScope(() => {
104
110
  if (err instanceof Error) {
@@ -107,6 +113,8 @@ function wrapCallback (callback, requestResource, parentResource) {
107
113
  } else {
108
114
  finishChannel.publish({ code: OK, trailer })
109
115
  }
116
+
117
+ call.removeListener('cancelled', onCancel)
110
118
  })
111
119
 
112
120
  if (callback) {
@@ -7,6 +7,7 @@ module.exports = {
7
7
  '@google-cloud/pubsub': () => require('../google-cloud-pubsub'),
8
8
  '@grpc/grpc-js': () => require('../grpc'),
9
9
  '@hapi/hapi': () => require('../hapi'),
10
+ '@jest/core': () => require('../jest'),
10
11
  '@koa/router': () => require('../koa'),
11
12
  '@node-redis/client': () => require('../redis'),
12
13
  'amqp10': () => require('../amqp10'),
@@ -17,6 +18,7 @@ module.exports = {
17
18
  'cassandra-driver': () => require('../cassandra-driver'),
18
19
  'connect': () => require('../connect'),
19
20
  'couchbase': () => require('../couchbase'),
21
+ 'crypto': () => require('../crypto'),
20
22
  'cypress': () => require('../cypress'),
21
23
  'dns': () => require('../dns'),
22
24
  'elasticsearch': () => require('../elasticsearch'),
@@ -30,6 +32,8 @@ module.exports = {
30
32
  'http2': () => require('../http2'),
31
33
  'https': () => require('../http'),
32
34
  'ioredis': () => require('../ioredis'),
35
+ 'jest-circus': () => require('../jest'),
36
+ 'jest-config': () => require('../jest'),
33
37
  'jest-environment-node': () => require('../jest'),
34
38
  'jest-environment-jsdom': () => require('../jest'),
35
39
  'jest-jasmine2': () => require('../jest'),
@@ -29,7 +29,7 @@ function wrapResponseEmit (emit) {
29
29
  return emit.apply(this, arguments)
30
30
  }
31
31
 
32
- if (eventName === 'finish') {
32
+ if (eventName === 'close') {
33
33
  finishServerCh.publish({ req: this.req })
34
34
  }
35
35
 
@@ -3,13 +3,20 @@ const istanbul = require('istanbul-lib-coverage')
3
3
  const { addHook, channel, AsyncResource } = require('./helpers/instrument')
4
4
  const shimmer = require('../../datadog-shimmer')
5
5
 
6
+ const testSessionStartCh = channel('ci:jest:session:start')
7
+ const testSessionFinishCh = channel('ci:jest:session:finish')
8
+
9
+ const testSessionConfigurationCh = channel('ci:jest:session:configuration')
10
+
11
+ const testSuiteStartCh = channel('ci:jest:test-suite:start')
12
+ const testSuiteFinishCh = channel('ci:jest:test-suite:finish')
13
+ const testSuiteCodeCoverageCh = channel('ci:jest:test-suite:code-coverage')
14
+
6
15
  const testStartCh = channel('ci:jest:test:start')
7
16
  const testSkippedCh = channel('ci:jest:test:skip')
8
17
  const testRunFinishCh = channel('ci:jest:test:finish')
9
18
  const testErrCh = channel('ci:jest:test:err')
10
19
 
11
- const testCodeCoverageCh = channel('ci:jest:test:code-coverage')
12
-
13
20
  const {
14
21
  getTestSuitePath,
15
22
  getTestParametersString
@@ -17,7 +24,8 @@ const {
17
24
 
18
25
  const { getFormattedJestTestParameters, getJestTestName } = require('../../datadog-plugin-jest/src/util')
19
26
 
20
- // This function also resets the coverage counters
27
+ const sessionAsyncResource = new AsyncResource('bound-anonymous-fn')
28
+
21
29
  function extractCoverageInformation (coverage, rootDir) {
22
30
  const coverageMap = istanbul.createCoverageMap(coverage)
23
31
 
@@ -28,8 +36,6 @@ function extractCoverageInformation (coverage, rootDir) {
28
36
  const lineCoverage = fileCoverage.getLineCoverage()
29
37
  const isAnyLineExecuted = Object.entries(lineCoverage).some(([, numExecutions]) => !!numExecutions)
30
38
 
31
- fileCoverage.resetHits()
32
-
33
39
  return isAnyLineExecuted
34
40
  })
35
41
  .map(filename => filename.replace(`${rootDir}/`, ''))
@@ -63,6 +69,16 @@ function formatJestError (errors) {
63
69
  return error
64
70
  }
65
71
 
72
+ function getTestEnvironmentOptions (config) {
73
+ if (config.projectConfig && config.projectConfig.testEnvironmentOptions) { // newer versions
74
+ return config.projectConfig.testEnvironmentOptions
75
+ }
76
+ if (config.testEnvironmentOptions) {
77
+ return config.testEnvironmentOptions
78
+ }
79
+ return {}
80
+ }
81
+
66
82
  function getWrappedEnvironment (BaseEnvironment) {
67
83
  return class DatadogEnvironment extends BaseEnvironment {
68
84
  constructor (config, context) {
@@ -72,6 +88,8 @@ function getWrappedEnvironment (BaseEnvironment) {
72
88
  this.testSuite = getTestSuitePath(context.testPath, rootDir)
73
89
  this.nameToParams = {}
74
90
  this.global._ddtrace = global._ddtrace
91
+
92
+ this.testEnvironmentOptions = getTestEnvironmentOptions(config)
75
93
  }
76
94
 
77
95
  async handleTestEvent (event, state) {
@@ -114,10 +132,6 @@ function getWrappedEnvironment (BaseEnvironment) {
114
132
  if (event.name === 'test_done') {
115
133
  const asyncResource = asyncResources.get(event.test)
116
134
  asyncResource.runInAsyncScope(() => {
117
- if (this.global.__coverage__) {
118
- const coverageFiles = extractCoverageInformation(this.global.__coverage__, this.rootDir)
119
- testCodeCoverageCh.publish(coverageFiles)
120
- }
121
135
  let status = 'pass'
122
136
  if (event.test.errors && event.test.errors.length) {
123
137
  status = 'fail'
@@ -163,11 +177,113 @@ addHook({
163
177
  versions: ['>=24.8.0']
164
178
  }, getTestEnvironment)
165
179
 
180
+ function cliWrapper (cli) {
181
+ const wrapped = shimmer.wrap(cli, 'runCLI', runCLI => async function () {
182
+ const processArgv = process.argv.slice(2).join(' ')
183
+ sessionAsyncResource.runInAsyncScope(() => {
184
+ testSessionStartCh.publish(`jest ${processArgv}`)
185
+ })
186
+ return runCLI.apply(this, arguments).then(result => {
187
+ const { results: { success } } = result
188
+ sessionAsyncResource.runInAsyncScope(() => {
189
+ testSessionFinishCh.publish(success ? 'pass' : 'fail')
190
+ })
191
+ return result
192
+ })
193
+ })
194
+
195
+ cli.runCLI = wrapped.runCLI
196
+
197
+ return cli
198
+ }
199
+
166
200
  addHook({
167
- name: 'jest-jasmine2',
168
- versions: ['>=24.8.0'],
169
- file: 'build/jasmineAsyncInstall.js'
170
- }, (jasmineAsyncInstallExport) => {
201
+ name: '@jest/core',
202
+ file: 'build/cli/index.js',
203
+ versions: ['>=24.8.0']
204
+ }, cliWrapper)
205
+
206
+ function jestAdapterWrapper (jestAdapter) {
207
+ const adapter = jestAdapter.default ? jestAdapter.default : jestAdapter
208
+ const newAdapter = shimmer.wrap(adapter, function () {
209
+ const environment = arguments[2]
210
+ const asyncResource = new AsyncResource('bound-anonymous-fn')
211
+ return asyncResource.runInAsyncScope(() => {
212
+ testSuiteStartCh.publish({
213
+ testSuite: environment.testSuite,
214
+ testEnvironmentOptions: environment.testEnvironmentOptions
215
+ })
216
+ return adapter.apply(this, arguments).then(suiteResults => {
217
+ const { numFailingTests, skipped, failureMessage: errorMessage } = suiteResults
218
+ let status = 'pass'
219
+ if (skipped) {
220
+ status = 'skipped'
221
+ } else if (numFailingTests !== 0) {
222
+ status = 'fail'
223
+ }
224
+ testSuiteFinishCh.publish({ status, errorMessage })
225
+ if (environment.global.__coverage__) {
226
+ const coverageFiles = extractCoverageInformation(environment.global.__coverage__, environment.rootDir)
227
+ if (coverageFiles.length) {
228
+ testSuiteCodeCoverageCh.publish([...coverageFiles, environment.testSuite])
229
+ }
230
+ }
231
+ return suiteResults
232
+ })
233
+ })
234
+ })
235
+ if (jestAdapter.default) {
236
+ jestAdapter.default = newAdapter
237
+ } else {
238
+ jestAdapter = newAdapter
239
+ }
240
+
241
+ return jestAdapter
242
+ }
243
+
244
+ addHook({
245
+ name: 'jest-circus',
246
+ file: 'build/legacy-code-todo-rewrite/jestAdapter.js',
247
+ versions: ['>=24.8.0']
248
+ }, jestAdapterWrapper)
249
+
250
+ function configureTestEnvironment (readConfigsResult) {
251
+ const { configs } = readConfigsResult
252
+ sessionAsyncResource.runInAsyncScope(() => {
253
+ testSessionConfigurationCh.publish(configs.map(config => config.testEnvironmentOptions))
254
+ })
255
+ }
256
+
257
+ function jestConfigAsyncWrapper (jestConfig) {
258
+ shimmer.wrap(jestConfig, 'readConfigs', readConfigs => async function () {
259
+ const readConfigsResult = await readConfigs.apply(this, arguments)
260
+ configureTestEnvironment(readConfigsResult)
261
+ return readConfigsResult
262
+ })
263
+ return jestConfig
264
+ }
265
+
266
+ function jestConfigSyncWrapper (jestConfig) {
267
+ shimmer.wrap(jestConfig, 'readConfigs', readConfigs => function () {
268
+ const readConfigsResult = readConfigs.apply(this, arguments)
269
+ configureTestEnvironment(readConfigsResult)
270
+ return readConfigsResult
271
+ })
272
+ return jestConfig
273
+ }
274
+
275
+ // from 25.1.0 on, readConfigs becomes async
276
+ addHook({
277
+ name: 'jest-config',
278
+ versions: ['>=25.1.0']
279
+ }, jestConfigAsyncWrapper)
280
+
281
+ addHook({
282
+ name: 'jest-config',
283
+ versions: ['24.8.0 - 24.9.0']
284
+ }, jestConfigSyncWrapper)
285
+
286
+ function jasmineAsyncInstallWraper (jasmineAsyncInstallExport) {
171
287
  return function (globalConfig, globalInput) {
172
288
  globalInput._ddtrace = global._ddtrace
173
289
  shimmer.wrap(globalInput.jasmine.Spec.prototype, 'execute', execute => function (onComplete) {
@@ -194,4 +310,10 @@ addHook({
194
310
  })
195
311
  return jasmineAsyncInstallExport.default(globalConfig, globalInput)
196
312
  }
197
- })
313
+ }
314
+
315
+ addHook({
316
+ name: 'jest-jasmine2',
317
+ versions: ['>=24.8.0'],
318
+ file: 'build/jasmineAsyncInstall.js'
319
+ }, jasmineAsyncInstallWraper)