dd-trace 5.30.0 → 5.32.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.
- package/LICENSE-3rdparty.csv +1 -0
- package/README.md +9 -7
- package/package.json +7 -6
- package/packages/datadog-core/src/storage.js +11 -2
- package/packages/datadog-instrumentations/src/aerospike.js +1 -1
- package/packages/datadog-instrumentations/src/aws-sdk.js +2 -1
- package/packages/datadog-instrumentations/src/cucumber.js +14 -5
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -0
- package/packages/datadog-instrumentations/src/jest.js +70 -36
- package/packages/datadog-instrumentations/src/mocha/utils.js +23 -7
- package/packages/datadog-instrumentations/src/node-serialize.js +22 -0
- package/packages/datadog-instrumentations/src/openai.js +2 -0
- package/packages/datadog-instrumentations/src/vitest.js +107 -59
- package/packages/datadog-instrumentations/src/vm.js +49 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime.js +295 -0
- package/packages/datadog-plugin-aws-sdk/src/services/index.js +1 -0
- package/packages/datadog-plugin-cucumber/src/index.js +30 -32
- package/packages/datadog-plugin-jest/src/index.js +34 -37
- package/packages/datadog-plugin-langchain/src/index.js +12 -80
- package/packages/datadog-plugin-langchain/src/tracing.js +89 -0
- package/packages/datadog-plugin-mocha/src/index.js +18 -36
- package/packages/datadog-plugin-vitest/src/index.js +20 -34
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +2 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/untrusted-deserialization-analyzer.js +16 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +9 -8
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/remote_config/manager.js +11 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +37 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +65 -28
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +57 -17
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +18 -3
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +20 -3
- package/packages/dd-trace/src/config.js +39 -3
- package/packages/dd-trace/src/crashtracking/crashtracker.js +9 -0
- package/packages/dd-trace/src/crashtracking/noop.js +3 -0
- package/packages/dd-trace/src/datastreams/fnv.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/config.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +32 -14
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +36 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +29 -10
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +35 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +112 -0
- package/packages/dd-trace/src/debugger/devtools_client/status.js +20 -11
- package/packages/dd-trace/src/debugger/index.js +2 -13
- package/packages/dd-trace/src/llmobs/plugins/base.js +40 -11
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +24 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +111 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +42 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +102 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/llm.js +32 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +131 -0
- package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +90 -26
- package/packages/dd-trace/src/llmobs/tagger.js +11 -3
- package/packages/dd-trace/src/llmobs/util.js +7 -1
- package/packages/dd-trace/src/llmobs/writers/spans/agentProxy.js +3 -3
- package/packages/dd-trace/src/log/index.js +8 -9
- package/packages/dd-trace/src/noop/proxy.js +2 -2
- package/packages/dd-trace/src/noop/span.js +1 -1
- package/packages/dd-trace/src/opentelemetry/context_manager.js +43 -3
- package/packages/dd-trace/src/opentracing/span.js +11 -1
- package/packages/dd-trace/src/opentracing/span_context.js +12 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +57 -27
- package/packages/dd-trace/src/plugins/util/test.js +42 -12
- package/packages/dd-trace/src/priority_sampler.js +7 -2
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +21 -0
- package/packages/dd-trace/src/profiling/profiler.js +11 -8
- package/packages/dd-trace/src/profiling/profilers/events.js +17 -1
- package/packages/dd-trace/src/proxy.js +6 -3
- package/packages/dd-trace/src/scope.js +1 -1
- package/packages/dd-trace/src/telemetry/index.js +2 -0
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -30,6 +30,7 @@ require,rfdc,MIT,Copyright 2019 David Mark Clements
|
|
|
30
30
|
require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
|
|
31
31
|
require,shell-quote,mit,Copyright (c) 2013 James Halliday
|
|
32
32
|
require,source-map,BSD-3-Clause,Copyright (c) 2009-2011, Mozilla Foundation and contributors
|
|
33
|
+
require,ttl-set,MIT,Copyright (c) 2024 Thomas Watson
|
|
33
34
|
dev,@apollo/server,MIT,Copyright (c) 2016-2020 Apollo Graph, Inc. (Formerly Meteor Development Group, Inc.)
|
|
34
35
|
dev,@types/node,MIT,Copyright Authors
|
|
35
36
|
dev,@eslint/eslintrc,MIT,Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
|
package/README.md
CHANGED
|
@@ -23,13 +23,15 @@ Most of the documentation for `dd-trace` is available on these webpages:
|
|
|
23
23
|
|
|
24
24
|
## Version Release Lines and Maintenance
|
|
25
25
|
|
|
26
|
-
| Release Line | Latest Version | Node.js | Status |Initial Release | End of Life |
|
|
27
|
-
| :---: | :---: | :---: | :---: | :---: | :---: |
|
|
28
|
-
| [`v1`](https://github.com/DataDog/dd-trace-js/tree/v1.x) |  | `>= v12` | **End of Life** | 2021-07-13 | 2022-02-25 |
|
|
29
|
-
| [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) |  | `>= v12` | **End of Life** | 2022-01-28 | 2023-08-15 |
|
|
30
|
-
| [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) |  | `>= v14` | **End of Life** | 2022-08-15 | 2024-05-15 |
|
|
31
|
-
| [`v4`](https://github.com/DataDog/dd-trace-js/tree/v4.x) | 
|
|
32
|
-
| [`v5`](https://github.com/DataDog/dd-trace-js/tree/v5.x) |  | `>= v18` | **Current** | 2024-01-11 | Unknown |
|
|
26
|
+
| Release Line | Latest Version | Node.js | [SSI](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/single-step-apm/?tab=linuxhostorvm) | [K8s Injection](https://docs.datadoghq.com/tracing/trace_collection/library_injection_local/?tab=kubernetes) |Status |Initial Release | End of Life |
|
|
27
|
+
| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
|
|
28
|
+
| [`v1`](https://github.com/DataDog/dd-trace-js/tree/v1.x) |  | `>= v12` | NO | NO | **End of Life** | 2021-07-13 | 2022-02-25 |
|
|
29
|
+
| [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) |  | `>= v12` | NO | NO | **End of Life** | 2022-01-28 | 2023-08-15 |
|
|
30
|
+
| [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) |  | `>= v14` | NO | YES | **End of Life** | 2022-08-15 | 2024-05-15 |
|
|
31
|
+
| [`v4`](https://github.com/DataDog/dd-trace-js/tree/v4.x) |  | `>= v16` | YES | YES | **Maintenance** | 2023-05-12 | 2025-01-11 |
|
|
32
|
+
| [`v5`](https://github.com/DataDog/dd-trace-js/tree/v5.x) |  | `>= v18` | YES | YES | **Current** | 2024-01-11 | Unknown |
|
|
33
|
+
|
|
34
|
+
* SSI = Single-Step Install
|
|
33
35
|
|
|
34
36
|
We currently maintain two release lines, namely `v5`, and `v4`.
|
|
35
37
|
Features and bug fixes that are merged are released to the `v5` line and, if appropriate, also `v4`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.32.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"test:lambda:ci": "nyc --no-clean --include \"packages/dd-trace/src/lambda/**/*.js\" -- npm run test:lambda",
|
|
34
34
|
"test:llmobs:sdk": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" --exclude \"packages/dd-trace/test/llmobs/plugins/**/*.spec.js\" \"packages/dd-trace/test/llmobs/**/*.spec.js\" ",
|
|
35
35
|
"test:llmobs:sdk:ci": "nyc --no-clean --include \"packages/dd-trace/src/llmobs/**/*.js\" -- npm run test:llmobs:sdk",
|
|
36
|
-
"test:llmobs:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/llmobs/plugins
|
|
36
|
+
"test:llmobs:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/llmobs/plugins/@($(echo $PLUGINS))/*.spec.js\"",
|
|
37
37
|
"test:llmobs:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/src/llmobs/**/*.js\" -- npm run test:llmobs:plugins",
|
|
38
38
|
"test:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-instrumentations/test/@($(echo $PLUGINS)).spec.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/**/*.spec.js\"",
|
|
39
39
|
"test:plugins:ci": "yarn services && nyc --no-clean --include \"packages/datadog-instrumentations/src/@($(echo $PLUGINS)).js\" --include \"packages/datadog-instrumentations/src/@($(echo $PLUGINS))/**/*.js\" --include \"packages/datadog-plugin-@($(echo $PLUGINS))/src/**/*.js\" -- npm run test:plugins",
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
"node": ">=18"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@datadog/libdatadog": "^0.
|
|
85
|
-
"@datadog/native-appsec": "8.
|
|
84
|
+
"@datadog/libdatadog": "^0.4.0",
|
|
85
|
+
"@datadog/native-appsec": "8.4.0",
|
|
86
86
|
"@datadog/native-iast-rewriter": "2.6.1",
|
|
87
87
|
"@datadog/native-iast-taint-tracking": "3.2.0",
|
|
88
88
|
"@datadog/native-metrics": "^3.1.0",
|
|
@@ -111,7 +111,8 @@
|
|
|
111
111
|
"semver": "^7.5.4",
|
|
112
112
|
"shell-quote": "^1.8.1",
|
|
113
113
|
"source-map": "^0.7.4",
|
|
114
|
-
"tlhunter-sorted-set": "^0.1.0"
|
|
114
|
+
"tlhunter-sorted-set": "^0.1.0",
|
|
115
|
+
"ttl-set": "^1.0.0"
|
|
115
116
|
},
|
|
116
117
|
"devDependencies": {
|
|
117
118
|
"@apollo/server": "^4.11.0",
|
|
@@ -145,7 +146,7 @@
|
|
|
145
146
|
"jszip": "^3.5.0",
|
|
146
147
|
"knex": "^2.4.2",
|
|
147
148
|
"mkdirp": "^3.0.1",
|
|
148
|
-
"mocha": "^
|
|
149
|
+
"mocha": "^10",
|
|
149
150
|
"msgpack-lite": "^0.1.26",
|
|
150
151
|
"multer": "^1.4.5-lts.1",
|
|
151
152
|
"nock": "^11.3.3",
|
|
@@ -21,8 +21,16 @@ class DatadogStorage {
|
|
|
21
21
|
this._storage.exit(callback, ...args)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
// TODO: Refactor the Scope class to use a span-only store and remove this.
|
|
25
|
+
getHandle () {
|
|
26
|
+
return this._storage.getStore()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getStore (handle) {
|
|
30
|
+
if (!handle) {
|
|
31
|
+
handle = this._storage.getStore()
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
return stores.get(handle)
|
|
27
35
|
}
|
|
28
36
|
|
|
@@ -50,6 +58,7 @@ const storage = function (namespace) {
|
|
|
50
58
|
storage.disable = legacyStorage.disable.bind(legacyStorage)
|
|
51
59
|
storage.enterWith = legacyStorage.enterWith.bind(legacyStorage)
|
|
52
60
|
storage.exit = legacyStorage.exit.bind(legacyStorage)
|
|
61
|
+
storage.getHandle = legacyStorage.getHandle.bind(legacyStorage)
|
|
53
62
|
storage.getStore = legacyStorage.getStore.bind(legacyStorage)
|
|
54
63
|
storage.run = legacyStorage.run.bind(legacyStorage)
|
|
55
64
|
|
|
@@ -238,8 +238,9 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
238
238
|
asyncResource.runInAsyncScope(() => {
|
|
239
239
|
testStartCh.publish(testStartPayload)
|
|
240
240
|
})
|
|
241
|
+
const promises = {}
|
|
241
242
|
try {
|
|
242
|
-
this.eventBroadcaster.on('envelope', shimmer.wrapFunction(null, () => (testCase) => {
|
|
243
|
+
this.eventBroadcaster.on('envelope', shimmer.wrapFunction(null, () => async (testCase) => {
|
|
243
244
|
// Only supported from >=8.0.0
|
|
244
245
|
if (testCase?.testCaseFinished) {
|
|
245
246
|
const { testCaseFinished: { willBeRetried } } = testCase
|
|
@@ -253,17 +254,22 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
253
254
|
}
|
|
254
255
|
|
|
255
256
|
const failedAttemptAsyncResource = numAttemptToAsyncResource.get(numAttempt)
|
|
256
|
-
const
|
|
257
|
+
const isFirstAttempt = numAttempt++ === 0
|
|
258
|
+
|
|
259
|
+
if (promises.hitBreakpointPromise) {
|
|
260
|
+
await promises.hitBreakpointPromise
|
|
261
|
+
}
|
|
262
|
+
|
|
257
263
|
failedAttemptAsyncResource.runInAsyncScope(() => {
|
|
258
264
|
// the current span will be finished and a new one will be created
|
|
259
|
-
testRetryCh.publish({
|
|
265
|
+
testRetryCh.publish({ isFirstAttempt, error })
|
|
260
266
|
})
|
|
261
267
|
|
|
262
268
|
const newAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
263
269
|
numAttemptToAsyncResource.set(numAttempt, newAsyncResource)
|
|
264
270
|
|
|
265
271
|
newAsyncResource.runInAsyncScope(() => {
|
|
266
|
-
testStartCh.publish(testStartPayload) // a new span will be created
|
|
272
|
+
testStartCh.publish({ ...testStartPayload, promises }) // a new span will be created
|
|
267
273
|
})
|
|
268
274
|
}
|
|
269
275
|
}
|
|
@@ -273,7 +279,7 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
273
279
|
asyncResource.runInAsyncScope(() => {
|
|
274
280
|
promise = run.apply(this, arguments)
|
|
275
281
|
})
|
|
276
|
-
promise.finally(() => {
|
|
282
|
+
promise.finally(async () => {
|
|
277
283
|
const result = this.getWorstStepResult()
|
|
278
284
|
const { status, skipReason } = isLatestVersion
|
|
279
285
|
? getStatusFromResultLatest(result)
|
|
@@ -296,6 +302,9 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
296
302
|
|
|
297
303
|
const error = getErrorFromCucumberResult(result)
|
|
298
304
|
|
|
305
|
+
if (promises.hitBreakpointPromise) {
|
|
306
|
+
await promises.hitBreakpointPromise
|
|
307
|
+
}
|
|
299
308
|
attemptAsyncResource.runInAsyncScope(() => {
|
|
300
309
|
testFinishCh.publish({ status, skipReason, error, isNew, isEfdRetry, isFlakyRetry: numAttempt > 0 })
|
|
301
310
|
})
|
|
@@ -88,6 +88,7 @@ module.exports = {
|
|
|
88
88
|
mysql2: () => require('../mysql2'),
|
|
89
89
|
net: () => require('../net'),
|
|
90
90
|
next: () => require('../next'),
|
|
91
|
+
'node-serialize': () => require('../node-serialize'),
|
|
91
92
|
'node:child_process': () => require('../child_process'),
|
|
92
93
|
'node:crypto': () => require('../crypto'),
|
|
93
94
|
'node:dns': () => require('../dns'),
|
|
@@ -96,6 +97,7 @@ module.exports = {
|
|
|
96
97
|
'node:https': () => require('../http'),
|
|
97
98
|
'node:net': () => require('../net'),
|
|
98
99
|
'node:url': () => require('../url'),
|
|
100
|
+
'node:vm': () => require('../vm'),
|
|
99
101
|
nyc: () => require('../nyc'),
|
|
100
102
|
oracledb: () => require('../oracledb'),
|
|
101
103
|
openai: () => require('../openai'),
|
|
@@ -122,6 +124,7 @@ module.exports = {
|
|
|
122
124
|
undici: () => require('../undici'),
|
|
123
125
|
url: () => require('../url'),
|
|
124
126
|
vitest: { esmFirst: true, fn: () => require('../vitest') },
|
|
127
|
+
vm: () => require('../vm'),
|
|
125
128
|
when: () => require('../when'),
|
|
126
129
|
winston: () => require('../winston'),
|
|
127
130
|
workerpool: () => require('../mocha')
|
|
@@ -12,7 +12,8 @@ const {
|
|
|
12
12
|
getTestParametersString,
|
|
13
13
|
addEfdStringToTestName,
|
|
14
14
|
removeEfdStringFromTestName,
|
|
15
|
-
getIsFaultyEarlyFlakeDetection
|
|
15
|
+
getIsFaultyEarlyFlakeDetection,
|
|
16
|
+
JEST_WORKER_LOGS_PAYLOAD_CODE
|
|
16
17
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
17
18
|
const {
|
|
18
19
|
getFormattedJestTestParameters,
|
|
@@ -30,12 +31,13 @@ const testSuiteFinishCh = channel('ci:jest:test-suite:finish')
|
|
|
30
31
|
|
|
31
32
|
const workerReportTraceCh = channel('ci:jest:worker-report:trace')
|
|
32
33
|
const workerReportCoverageCh = channel('ci:jest:worker-report:coverage')
|
|
34
|
+
const workerReportLogsCh = channel('ci:jest:worker-report:logs')
|
|
33
35
|
|
|
34
36
|
const testSuiteCodeCoverageCh = channel('ci:jest:test-suite:code-coverage')
|
|
35
37
|
|
|
36
38
|
const testStartCh = channel('ci:jest:test:start')
|
|
37
39
|
const testSkippedCh = channel('ci:jest:test:skip')
|
|
38
|
-
const
|
|
40
|
+
const testFinishCh = channel('ci:jest:test:finish')
|
|
39
41
|
const testErrCh = channel('ci:jest:test:err')
|
|
40
42
|
|
|
41
43
|
const skippableSuitesCh = channel('ci:jest:test-suite:skippable')
|
|
@@ -75,6 +77,8 @@ const originalTestFns = new WeakMap()
|
|
|
75
77
|
const retriedTestsToNumAttempts = new Map()
|
|
76
78
|
const newTestsTestStatuses = new Map()
|
|
77
79
|
|
|
80
|
+
const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
|
|
81
|
+
|
|
78
82
|
// based on https://github.com/facebook/jest/blob/main/packages/jest-circus/src/formatNodeAssertErrors.ts#L41
|
|
79
83
|
function formatJestError (errors) {
|
|
80
84
|
let error
|
|
@@ -274,46 +278,70 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
274
278
|
}
|
|
275
279
|
}
|
|
276
280
|
if (event.name === 'test_done') {
|
|
277
|
-
|
|
281
|
+
let status = 'pass'
|
|
282
|
+
if (event.test.errors && event.test.errors.length) {
|
|
283
|
+
status = 'fail'
|
|
284
|
+
}
|
|
285
|
+
// restore in case it is retried
|
|
286
|
+
event.test.fn = originalTestFns.get(event.test)
|
|
287
|
+
|
|
288
|
+
// We'll store the test statuses of the retries
|
|
289
|
+
if (this.isEarlyFlakeDetectionEnabled) {
|
|
290
|
+
const testName = getJestTestName(event.test)
|
|
291
|
+
const originalTestName = removeEfdStringFromTestName(testName)
|
|
292
|
+
const isNewTest = retriedTestsToNumAttempts.has(originalTestName)
|
|
293
|
+
if (isNewTest) {
|
|
294
|
+
if (newTestsTestStatuses.has(originalTestName)) {
|
|
295
|
+
newTestsTestStatuses.get(originalTestName).push(status)
|
|
296
|
+
} else {
|
|
297
|
+
newTestsTestStatuses.set(originalTestName, [status])
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const promises = {}
|
|
303
|
+
const numRetries = this.global[RETRY_TIMES]
|
|
304
|
+
const numTestExecutions = event.test?.invocations
|
|
305
|
+
const willBeRetried = numRetries > 0 && numTestExecutions - 1 < numRetries
|
|
306
|
+
const mightHitBreakpoint = this.isDiEnabled && numTestExecutions >= 2
|
|
307
|
+
|
|
278
308
|
const asyncResource = asyncResources.get(event.test)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
status = 'fail'
|
|
283
|
-
const numRetries = this.global[RETRY_TIMES]
|
|
284
|
-
const numTestExecutions = event.test?.invocations
|
|
285
|
-
const willBeRetried = numRetries > 0 && numTestExecutions - 1 < numRetries
|
|
286
|
-
|
|
287
|
-
const error = formatJestError(event.test.errors[0])
|
|
309
|
+
|
|
310
|
+
if (status === 'fail') {
|
|
311
|
+
asyncResource.runInAsyncScope(() => {
|
|
288
312
|
testErrCh.publish({
|
|
289
|
-
error,
|
|
290
|
-
willBeRetried,
|
|
291
|
-
|
|
292
|
-
isDiEnabled: this.isDiEnabled
|
|
313
|
+
error: formatJestError(event.test.errors[0]),
|
|
314
|
+
shouldSetProbe: this.isDiEnabled && willBeRetried && numTestExecutions === 1,
|
|
315
|
+
promises
|
|
293
316
|
})
|
|
294
|
-
}
|
|
295
|
-
|
|
317
|
+
})
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// After finishing it might take a bit for the snapshot to be handled.
|
|
321
|
+
// This means that tests retried with DI are BREAKPOINT_HIT_GRACE_PERIOD_MS slower at least.
|
|
322
|
+
if (status === 'fail' && mightHitBreakpoint) {
|
|
323
|
+
await new Promise(resolve => {
|
|
324
|
+
setTimeout(() => {
|
|
325
|
+
resolve()
|
|
326
|
+
}, BREAKPOINT_HIT_GRACE_PERIOD_MS)
|
|
327
|
+
})
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
asyncResource.runInAsyncScope(() => {
|
|
331
|
+
testFinishCh.publish({
|
|
296
332
|
status,
|
|
297
|
-
testStartLine: getTestLineStart(event.test.asyncError, this.testSuite)
|
|
333
|
+
testStartLine: getTestLineStart(event.test.asyncError, this.testSuite),
|
|
334
|
+
promises,
|
|
335
|
+
shouldRemoveProbe: this.isDiEnabled && !willBeRetried
|
|
298
336
|
})
|
|
299
|
-
// restore in case it is retried
|
|
300
|
-
event.test.fn = originalTestFns.get(event.test)
|
|
301
|
-
// We'll store the test statuses of the retries
|
|
302
|
-
if (this.isEarlyFlakeDetectionEnabled) {
|
|
303
|
-
const testName = getJestTestName(event.test)
|
|
304
|
-
const originalTestName = removeEfdStringFromTestName(testName)
|
|
305
|
-
const isNewTest = retriedTestsToNumAttempts.has(originalTestName)
|
|
306
|
-
if (isNewTest) {
|
|
307
|
-
if (newTestsTestStatuses.has(originalTestName)) {
|
|
308
|
-
newTestsTestStatuses.get(originalTestName).push(status)
|
|
309
|
-
} else {
|
|
310
|
-
newTestsTestStatuses.set(originalTestName, [status])
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
337
|
})
|
|
315
|
-
|
|
316
|
-
|
|
338
|
+
|
|
339
|
+
if (promises.isProbeReady) {
|
|
340
|
+
await promises.isProbeReady
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (promises.isProbeRemoved) {
|
|
344
|
+
await promises.isProbeRemoved
|
|
317
345
|
}
|
|
318
346
|
}
|
|
319
347
|
if (event.name === 'test_skip' || event.name === 'test_todo') {
|
|
@@ -953,6 +981,12 @@ addHook({
|
|
|
953
981
|
})
|
|
954
982
|
return
|
|
955
983
|
}
|
|
984
|
+
if (code === JEST_WORKER_LOGS_PAYLOAD_CODE) { // datadog logs payload
|
|
985
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
986
|
+
workerReportLogsCh.publish(data)
|
|
987
|
+
})
|
|
988
|
+
return
|
|
989
|
+
}
|
|
956
990
|
return _onMessage.apply(this, arguments)
|
|
957
991
|
})
|
|
958
992
|
return childProcessWorker
|
|
@@ -19,6 +19,7 @@ const skipCh = channel('ci:mocha:test:skip')
|
|
|
19
19
|
// suite channels
|
|
20
20
|
const testSuiteErrorCh = channel('ci:mocha:test-suite:error')
|
|
21
21
|
|
|
22
|
+
const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
|
|
22
23
|
const testToAr = new WeakMap()
|
|
23
24
|
const originalFns = new WeakMap()
|
|
24
25
|
const testToStartLine = new WeakMap()
|
|
@@ -73,7 +74,7 @@ function isMochaRetry (test) {
|
|
|
73
74
|
return test._currentRetry !== undefined && test._currentRetry !== 0
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
function
|
|
77
|
+
function getIsLastRetry (test) {
|
|
77
78
|
return test._currentRetry === test._retries
|
|
78
79
|
}
|
|
79
80
|
|
|
@@ -203,14 +204,28 @@ function getOnTestHandler (isMain) {
|
|
|
203
204
|
}
|
|
204
205
|
|
|
205
206
|
function getOnTestEndHandler () {
|
|
206
|
-
return function (test) {
|
|
207
|
+
return async function (test) {
|
|
207
208
|
const asyncResource = getTestAsyncResource(test)
|
|
208
209
|
const status = getTestStatus(test)
|
|
209
210
|
|
|
211
|
+
// After finishing it might take a bit for the snapshot to be handled.
|
|
212
|
+
// This means that tests retried with DI are BREAKPOINT_HIT_GRACE_PERIOD_MS slower at least.
|
|
213
|
+
if (test._ddShouldWaitForHitProbe || test._retriedTest?._ddShouldWaitForHitProbe) {
|
|
214
|
+
await new Promise((resolve) => {
|
|
215
|
+
setTimeout(() => {
|
|
216
|
+
resolve()
|
|
217
|
+
}, BREAKPOINT_HIT_GRACE_PERIOD_MS)
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
|
|
210
221
|
// if there are afterEach to be run, we don't finish the test yet
|
|
211
222
|
if (asyncResource && !test.parent._afterEach.length) {
|
|
212
223
|
asyncResource.runInAsyncScope(() => {
|
|
213
|
-
testFinishCh.publish({
|
|
224
|
+
testFinishCh.publish({
|
|
225
|
+
status,
|
|
226
|
+
hasBeenRetried: isMochaRetry(test),
|
|
227
|
+
isLastRetry: getIsLastRetry(test)
|
|
228
|
+
})
|
|
214
229
|
})
|
|
215
230
|
}
|
|
216
231
|
}
|
|
@@ -220,16 +235,17 @@ function getOnHookEndHandler () {
|
|
|
220
235
|
return function (hook) {
|
|
221
236
|
const test = hook.ctx.currentTest
|
|
222
237
|
if (test && hook.parent._afterEach.includes(hook)) { // only if it's an afterEach
|
|
223
|
-
const
|
|
224
|
-
if (test._retries > 0 && !isLastRetry
|
|
238
|
+
const isLastRetry = getIsLastRetry(test)
|
|
239
|
+
if (test._retries > 0 && !isLastRetry) {
|
|
225
240
|
return
|
|
226
241
|
}
|
|
242
|
+
const isLastAfterEach = hook.parent._afterEach.indexOf(hook) === hook.parent._afterEach.length - 1
|
|
227
243
|
if (isLastAfterEach) {
|
|
228
244
|
const status = getTestStatus(test)
|
|
229
245
|
const asyncResource = getTestAsyncResource(test)
|
|
230
246
|
if (asyncResource) {
|
|
231
247
|
asyncResource.runInAsyncScope(() => {
|
|
232
|
-
testFinishCh.publish({ status, hasBeenRetried: isMochaRetry(test) })
|
|
248
|
+
testFinishCh.publish({ status, hasBeenRetried: isMochaRetry(test), isLastRetry })
|
|
233
249
|
})
|
|
234
250
|
}
|
|
235
251
|
}
|
|
@@ -286,7 +302,7 @@ function getOnTestRetryHandler () {
|
|
|
286
302
|
const isFirstAttempt = test._currentRetry === 0
|
|
287
303
|
const willBeRetried = test._currentRetry < test._retries
|
|
288
304
|
asyncResource.runInAsyncScope(() => {
|
|
289
|
-
testRetryCh.publish({ isFirstAttempt, err, willBeRetried })
|
|
305
|
+
testRetryCh.publish({ isFirstAttempt, err, willBeRetried, test })
|
|
290
306
|
})
|
|
291
307
|
}
|
|
292
308
|
const key = getTestToArKey(test)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../datadog-shimmer')
|
|
4
|
+
const { channel, addHook } = require('./helpers/instrument')
|
|
5
|
+
|
|
6
|
+
const nodeUnserializeCh = channel('datadog:node-serialize:unserialize:start')
|
|
7
|
+
|
|
8
|
+
function wrapUnserialize (serialize) {
|
|
9
|
+
return function wrappedUnserialize (obj) {
|
|
10
|
+
if (nodeUnserializeCh.hasSubscribers) {
|
|
11
|
+
nodeUnserializeCh.publish({ obj })
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return serialize.apply(this, arguments)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
addHook({ name: 'node-serialize', versions: ['0.0.4'] }, serialize => {
|
|
19
|
+
shimmer.wrap(serialize, 'unserialize', wrapUnserialize)
|
|
20
|
+
|
|
21
|
+
return serialize
|
|
22
|
+
})
|