dd-trace 5.89.0 → 5.90.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 +0 -3
- package/index.d.ts +31 -0
- package/package.json +8 -8
- package/packages/datadog-instrumentations/src/azure-durable-functions.js +75 -0
- package/packages/datadog-instrumentations/src/cucumber.js +40 -1
- package/packages/datadog-instrumentations/src/elasticsearch.js +12 -3
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/jest.js +22 -0
- package/packages/datadog-instrumentations/src/mocha/main.js +10 -4
- package/packages/datadog-instrumentations/src/mocha/utils.js +6 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +10 -2
- package/packages/datadog-instrumentations/src/playwright.js +20 -2
- package/packages/datadog-instrumentations/src/prisma.js +4 -2
- package/packages/datadog-instrumentations/src/vitest.js +16 -0
- package/packages/datadog-plugin-apollo/src/gateway/execute.js +8 -0
- package/packages/datadog-plugin-apollo/src/gateway/fetch.js +5 -0
- package/packages/datadog-plugin-apollo/src/gateway/plan.js +8 -0
- package/packages/datadog-plugin-apollo/src/gateway/postprocessing.js +5 -0
- package/packages/datadog-plugin-apollo/src/gateway/request.js +4 -3
- package/packages/datadog-plugin-apollo/src/gateway/validate.js +4 -3
- package/packages/datadog-plugin-apollo/src/index.js +28 -0
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +49 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +11 -1
- package/packages/datadog-plugin-jest/src/index.js +6 -0
- package/packages/datadog-plugin-playwright/src/index.js +35 -8
- package/packages/dd-trace/src/aiguard/noop.js +1 -1
- package/packages/dd-trace/src/aiguard/sdk.js +14 -5
- package/packages/dd-trace/src/appsec/api_security_sampler.js +22 -1
- package/packages/dd-trace/src/appsec/index.js +11 -1
- package/packages/dd-trace/src/appsec/reporter.js +28 -11
- package/packages/dd-trace/src/appsec/waf/index.js +1 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +4 -4
- package/packages/dd-trace/src/config/index.js +1 -0
- package/packages/dd-trace/src/config/supported-configurations.json +7 -0
- package/packages/dd-trace/src/constants.js +1 -0
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +1 -8
- package/packages/dd-trace/src/encode/agentless-json.js +67 -22
- package/packages/dd-trace/src/exporters/agentless/index.js +58 -15
- package/packages/dd-trace/src/exporters/agentless/writer.js +35 -18
- package/packages/dd-trace/src/llmobs/constants/tags.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/anthropic.js +9 -0
- package/packages/dd-trace/src/llmobs/tagger.js +8 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -0
- package/packages/dd-trace/src/plugins/apollo.js +7 -2
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +95 -3
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +36 -2
- package/packages/dd-trace/src/plugins/util/web.js +31 -11
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +7 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +4 -0
- package/packages/dd-trace/src/standalone/product.js +2 -1
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -61,7 +61,6 @@
|
|
|
61
61
|
"crypto-randomuuid","npm:crypto-randomuuid","['MIT']","['Stephen Belanger']"
|
|
62
62
|
"dc-polyfill","https://github.com/DataDog/dc-polyfill","['MIT']","['Thomas Hunter II']"
|
|
63
63
|
"dd-trace","https://github.com/DataDog/dd-trace-js","['(Apache-2.0 OR BSD-3-Clause)']","['Datadog Inc. <info@datadoghq.com>']"
|
|
64
|
-
"delay","https://github.com/sindresorhus/delay","['MIT']","['Sindre Sorhus']"
|
|
65
64
|
"detect-newline","https://github.com/sindresorhus/detect-newline","['MIT']","['Sindre Sorhus']"
|
|
66
65
|
"escape-string-regexp","https://github.com/sindresorhus/escape-string-regexp","['MIT']","['Sindre Sorhus']"
|
|
67
66
|
"esquery","https://github.com/estools/esquery","['BSD-3-Clause']","['Joel Feenstra']"
|
|
@@ -85,7 +84,6 @@
|
|
|
85
84
|
"node-gyp-build","https://github.com/prebuild/node-gyp-build","['MIT']","['Mathias Buus']"
|
|
86
85
|
"opentracing","https://github.com/opentracing/opentracing-javascript","['Apache-2.0']","['opentracing']"
|
|
87
86
|
"oxc-parser","https://github.com/oxc-project/oxc","['MIT']","['Boshen and oxc contributors']"
|
|
88
|
-
"p-limit","https://github.com/sindresorhus/p-limit","['MIT']","['Sindre Sorhus']"
|
|
89
87
|
"path-to-regexp","https://github.com/pillarjs/path-to-regexp","['MIT']","['pillarjs']"
|
|
90
88
|
"pprof-format","https://github.com/DataDog/pprof-format","['MIT']","['Datadog Inc.']"
|
|
91
89
|
"protobufjs","https://github.com/protobufjs/protobuf.js","['BSD-3-Clause']","['Daniel Wirtz']"
|
|
@@ -100,6 +98,5 @@
|
|
|
100
98
|
"tslib","https://github.com/microsoft/tslib","['0BSD']","['Microsoft Corp.']"
|
|
101
99
|
"ttl-set","https://github.com/watson/ttl-set","['MIT']","['Thomas Watson']"
|
|
102
100
|
"undici-types","https://github.com/nodejs/undici","['MIT']","['nodejs']"
|
|
103
|
-
"yocto-queue","https://github.com/sindresorhus/yocto-queue","['MIT']","['Sindre Sorhus']"
|
|
104
101
|
"aws-lambda-nodejs-runtime-interface-client","https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/blob/v2.1.0/src/utils/UserFunction.ts","['Apache-2.0']","['Amazon.com Inc. or its affiliates']"
|
|
105
102
|
"is-git-url","https://github.com/jonschlinkert/is-git-url/blob/396965ffabf2f46656c8af4c47bef1d69f09292e/index.js#L9C15-L9C87","['MIT']","['Jon Schlinkert']"
|
package/index.d.ts
CHANGED
|
@@ -228,6 +228,7 @@ interface Plugins {
|
|
|
228
228
|
"azure-event-hubs": tracer.plugins.azure_event_hubs;
|
|
229
229
|
"azure-functions": tracer.plugins.azure_functions;
|
|
230
230
|
"azure-service-bus": tracer.plugins.azure_service_bus;
|
|
231
|
+
"azure-durable-functions": tracer.plugins.azure_durable_functions
|
|
231
232
|
"bullmq": tracer.plugins.bullmq;
|
|
232
233
|
"bunyan": tracer.plugins.bunyan;
|
|
233
234
|
"cassandra-driver": tracer.plugins.cassandra_driver;
|
|
@@ -1626,6 +1627,10 @@ declare namespace tracer {
|
|
|
1626
1627
|
* List of tags associated with the evaluation (e.g. indirect-prompt-injection)
|
|
1627
1628
|
*/
|
|
1628
1629
|
tags: string[];
|
|
1630
|
+
/**
|
|
1631
|
+
* Sensitive Data Scanner findings from the evaluation.
|
|
1632
|
+
*/
|
|
1633
|
+
sds: Object[];
|
|
1629
1634
|
}
|
|
1630
1635
|
|
|
1631
1636
|
/**
|
|
@@ -1641,6 +1646,10 @@ declare namespace tracer {
|
|
|
1641
1646
|
* List of tags associated with the evaluation (e.g. indirect-prompt-injection)
|
|
1642
1647
|
*/
|
|
1643
1648
|
tags: string[];
|
|
1649
|
+
/**
|
|
1650
|
+
* Sensitive Data Scanner findings from the evaluation.
|
|
1651
|
+
*/
|
|
1652
|
+
sds: Object[];
|
|
1644
1653
|
}
|
|
1645
1654
|
|
|
1646
1655
|
/**
|
|
@@ -2034,6 +2043,22 @@ declare namespace tracer {
|
|
|
2034
2043
|
* @default true
|
|
2035
2044
|
*/
|
|
2036
2045
|
signature?: boolean;
|
|
2046
|
+
|
|
2047
|
+
/**
|
|
2048
|
+
* An object of optional callbacks to be executed during the respective
|
|
2049
|
+
* phase of an Apollo Gateway operation. Undefined callbacks default to a
|
|
2050
|
+
* noop function.
|
|
2051
|
+
*
|
|
2052
|
+
* @default {}
|
|
2053
|
+
*/
|
|
2054
|
+
hooks?: {
|
|
2055
|
+
request?: (span?: Span, ctx?: any) => void;
|
|
2056
|
+
validate?: (span?: Span, ctx?: any) => void;
|
|
2057
|
+
plan?: (span?: Span, ctx?: any) => void;
|
|
2058
|
+
execute?: (span?: Span, ctx?: any) => void;
|
|
2059
|
+
fetch?: (span?: Span, ctx?: any) => void;
|
|
2060
|
+
postprocessing?: (span?: Span, ctx?: any) => void;
|
|
2061
|
+
};
|
|
2037
2062
|
}
|
|
2038
2063
|
|
|
2039
2064
|
/**
|
|
@@ -2097,6 +2122,12 @@ declare namespace tracer {
|
|
|
2097
2122
|
*/
|
|
2098
2123
|
interface azure_service_bus extends Integration {}
|
|
2099
2124
|
|
|
2125
|
+
/**
|
|
2126
|
+
* This plugin automatically instruments the
|
|
2127
|
+
* durable-functions module
|
|
2128
|
+
*/
|
|
2129
|
+
interface azure_durable_functions extends Integration {}
|
|
2130
|
+
|
|
2100
2131
|
/**
|
|
2101
2132
|
* This plugin patches the [bunyan](https://github.com/trentm/node-bunyan)
|
|
2102
2133
|
* to automatically inject trace identifiers in log records when the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.90.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -142,11 +142,11 @@
|
|
|
142
142
|
"@datadog/native-iast-taint-tracking": "4.1.0",
|
|
143
143
|
"@datadog/native-metrics": "3.1.1",
|
|
144
144
|
"@datadog/openfeature-node-server": "^1.1.0",
|
|
145
|
-
"@datadog/pprof": "5.13.
|
|
145
|
+
"@datadog/pprof": "5.13.5",
|
|
146
146
|
"@datadog/wasm-js-rewriter": "5.0.1",
|
|
147
147
|
"@opentelemetry/api": ">=1.0.0 <1.10.0",
|
|
148
148
|
"@opentelemetry/api-logs": "<1.0.0",
|
|
149
|
-
"oxc-parser": "^0.
|
|
149
|
+
"oxc-parser": "^0.116.0"
|
|
150
150
|
},
|
|
151
151
|
"devDependencies": {
|
|
152
152
|
"@actions/core": "^3.0.0",
|
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
"@msgpack/msgpack": "^3.1.3",
|
|
158
158
|
"@openfeature/core": "^1.8.1",
|
|
159
159
|
"@openfeature/server-sdk": "~1.20.0",
|
|
160
|
-
"@stylistic/eslint-plugin": "^5.
|
|
160
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
161
161
|
"@types/mocha": "^10.0.10",
|
|
162
162
|
"@types/node": "^18.19.106",
|
|
163
163
|
"@types/sinon": "^21.0.0",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
"benchmark": "^2.1.4",
|
|
166
166
|
"body-parser": "^2.2.2",
|
|
167
167
|
"bun": "1.3.10",
|
|
168
|
-
"codeowners-audit": "^2.
|
|
168
|
+
"codeowners-audit": "^2.7.1",
|
|
169
169
|
"eslint": "^9.39.2",
|
|
170
170
|
"eslint-plugin-cypress": "^6.1.0",
|
|
171
171
|
"eslint-plugin-import": "^2.32.0",
|
|
@@ -183,9 +183,9 @@
|
|
|
183
183
|
"mocha": "^11.6.0",
|
|
184
184
|
"mocha-junit-reporter": "^2.2.1",
|
|
185
185
|
"mocha-multi-reporters": "^1.5.1",
|
|
186
|
-
"multer": "^2.
|
|
186
|
+
"multer": "^2.1.1",
|
|
187
187
|
"nock": "^13.5.6",
|
|
188
|
-
"nyc": "^
|
|
188
|
+
"nyc": "^18.0.0",
|
|
189
189
|
"octokit": "^5.0.3",
|
|
190
190
|
"opentracing": ">=0.14.7",
|
|
191
191
|
"p-limit": "^7.2.0",
|
|
@@ -193,7 +193,7 @@
|
|
|
193
193
|
"retry": "^0.13.1",
|
|
194
194
|
"semifies": "^1.0.0",
|
|
195
195
|
"semver": "^7.7.2",
|
|
196
|
-
"sinon": "^21.0.
|
|
196
|
+
"sinon": "^21.0.2",
|
|
197
197
|
"tiktoken": "^1.0.21",
|
|
198
198
|
"typescript": "^5.9.2",
|
|
199
199
|
"workerpool": "^10.0.0",
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const dc = require('dc-polyfill')
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
addHook,
|
|
8
|
+
} = require('./helpers/instrument')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @type {import('diagnostics_channel').TracingChannel}
|
|
12
|
+
*/
|
|
13
|
+
const azureDurableFunctionsChannel = dc.tracingChannel('datadog:azure:durable-functions:invoke')
|
|
14
|
+
|
|
15
|
+
addHook({ name: 'durable-functions', versions: ['>=3'], patchDefault: false }, (df) => {
|
|
16
|
+
const { app } = df
|
|
17
|
+
|
|
18
|
+
shimmer.wrap(app, 'entity', entityWrapper)
|
|
19
|
+
shimmer.wrap(app, 'activity', activityHandler)
|
|
20
|
+
|
|
21
|
+
return df
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
function entityWrapper (method) {
|
|
25
|
+
return function (entityName, arg) {
|
|
26
|
+
// because this method is overloaded, the second argument can either be an object
|
|
27
|
+
// with the handler or the handler itself, so first we figure which type it is
|
|
28
|
+
if (typeof arg === 'function') {
|
|
29
|
+
// if a function, this is the handler we want to wrap and trace
|
|
30
|
+
arguments[1] = shimmer.wrapFunction(arg, handler => entityHandler(handler, entityName))
|
|
31
|
+
} else {
|
|
32
|
+
// if an object, access the handler then trace it
|
|
33
|
+
shimmer.wrap(arg, 'handler', handler => entityHandler(handler, entityName))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return method.apply(this, arguments)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function entityHandler (handler, entityName) {
|
|
41
|
+
return function () {
|
|
42
|
+
if (!azureDurableFunctionsChannel.hasSubscribers) return handler.apply(this, arguments)
|
|
43
|
+
|
|
44
|
+
const entityContext = arguments[0]
|
|
45
|
+
return azureDurableFunctionsChannel.traceSync(
|
|
46
|
+
handler,
|
|
47
|
+
{ trigger: 'Entity', functionName: entityName, operationName: entityContext?.df?.operationName },
|
|
48
|
+
this, ...arguments)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function activityHandler (method) {
|
|
53
|
+
return function (activityName, activityOptions) {
|
|
54
|
+
shimmer.wrap(activityOptions, 'handler', handler => {
|
|
55
|
+
const isAsync =
|
|
56
|
+
handler && handler.constructor && handler.constructor.name === 'AsyncFunction'
|
|
57
|
+
|
|
58
|
+
return function () {
|
|
59
|
+
if (!azureDurableFunctionsChannel.hasSubscribers) return handler.apply(this, arguments)
|
|
60
|
+
|
|
61
|
+
// use tracePromise if this is an async handler. otherwise, use traceSync
|
|
62
|
+
return isAsync
|
|
63
|
+
? azureDurableFunctionsChannel.tracePromise(
|
|
64
|
+
handler,
|
|
65
|
+
{ trigger: 'Activity', functionName: activityName },
|
|
66
|
+
this, ...arguments)
|
|
67
|
+
: azureDurableFunctionsChannel.traceSync(
|
|
68
|
+
handler,
|
|
69
|
+
{ trigger: 'Activity', functionName: activityName },
|
|
70
|
+
this, ...arguments)
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
return method.apply(this, arguments)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -55,6 +55,8 @@ const originalCoverageMap = createCoverageMap()
|
|
|
55
55
|
const patched = new WeakSet()
|
|
56
56
|
|
|
57
57
|
const lastStatusByPickleId = new Map()
|
|
58
|
+
/** For ATR: statuses keyed by stable scenario id (uri:name) so retries accumulate correctly */
|
|
59
|
+
const atrStatusesByScenarioKey = new Map()
|
|
58
60
|
const numRetriesByPickleId = new Map()
|
|
59
61
|
const numAttemptToCtx = new Map()
|
|
60
62
|
const newTestsByTestFullname = new Map()
|
|
@@ -275,6 +277,17 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
275
277
|
const isFirstAttempt = numAttempt++ === 0
|
|
276
278
|
const isAtrRetry = !isFirstAttempt && isFlakyTestRetriesEnabled
|
|
277
279
|
|
|
280
|
+
// ATR: record this attempt as failed so when run().finally runs (after retry) we have all statuses
|
|
281
|
+
if (isFlakyTestRetriesEnabled && isAtrRetry === false) {
|
|
282
|
+
const nameForKey = this.pickle.name.replace(/\s*\(attempt \d+(?:, retried)?\)\s*$/, '')
|
|
283
|
+
const atrKey = `${this.pickle.uri}:${nameForKey}`
|
|
284
|
+
if (atrStatusesByScenarioKey.has(atrKey)) {
|
|
285
|
+
atrStatusesByScenarioKey.get(atrKey).push('fail')
|
|
286
|
+
} else {
|
|
287
|
+
atrStatusesByScenarioKey.set(atrKey, ['fail'])
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
278
291
|
if (promises.hitBreakpointPromise) {
|
|
279
292
|
await promises.hitBreakpointPromise
|
|
280
293
|
}
|
|
@@ -367,6 +380,25 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
367
380
|
}
|
|
368
381
|
}
|
|
369
382
|
|
|
383
|
+
// ATR: accumulate statuses by stable scenario key (uri:name) so retries are grouped.
|
|
384
|
+
// Cucumber appends " (attempt N)" or " (attempt N, retried)" to the scenario name; normalize for keying.
|
|
385
|
+
if (isFlakyTestRetriesEnabled && !isAttemptToFix && !isEfdRetry && numTestRetries > 0) {
|
|
386
|
+
const nameForKey = this.pickle.name.replace(/\s*\(attempt \d+(?:, retried)?\)\s*$/, '')
|
|
387
|
+
const atrKey = `${this.pickle.uri}:${nameForKey}`
|
|
388
|
+
if (atrStatusesByScenarioKey.has(atrKey)) {
|
|
389
|
+
atrStatusesByScenarioKey.get(atrKey).push(status)
|
|
390
|
+
} else {
|
|
391
|
+
atrStatusesByScenarioKey.set(atrKey, [status])
|
|
392
|
+
}
|
|
393
|
+
const atrStatuses = atrStatusesByScenarioKey.get(atrKey)
|
|
394
|
+
const pickleStatuses = lastStatusByPickleId.get(this.pickle.id)
|
|
395
|
+
const statusesToCheck = atrStatuses?.length >= (numTestRetries + 1) ? atrStatuses : pickleStatuses
|
|
396
|
+
if (statusesToCheck && statusesToCheck.length === numTestRetries + 1 &&
|
|
397
|
+
statusesToCheck.every(s => s === 'fail')) {
|
|
398
|
+
hasFailedAllRetries = true
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
370
402
|
const attemptCtx = numAttemptToCtx.get(numAttempt)
|
|
371
403
|
|
|
372
404
|
const error = getErrorFromCucumberResult(result)
|
|
@@ -480,7 +512,8 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
480
512
|
earlyFlakeDetectionFaultyThreshold = configurationResponse.libraryConfig?.earlyFlakeDetectionFaultyThreshold
|
|
481
513
|
isSuitesSkippingEnabled = configurationResponse.libraryConfig?.isSuitesSkippingEnabled
|
|
482
514
|
isFlakyTestRetriesEnabled = configurationResponse.libraryConfig?.isFlakyTestRetriesEnabled
|
|
483
|
-
|
|
515
|
+
const configRetryCount = configurationResponse.libraryConfig?.flakyTestRetriesCount
|
|
516
|
+
numTestRetries = (typeof configRetryCount === 'number' && configRetryCount > 0) ? configRetryCount : 0
|
|
484
517
|
isKnownTestsEnabled = configurationResponse.libraryConfig?.isKnownTestsEnabled
|
|
485
518
|
isTestManagementTestsEnabled = configurationResponse.libraryConfig?.isTestManagementEnabled
|
|
486
519
|
testManagementAttemptToFixRetries = configurationResponse.libraryConfig?.testManagementAttemptToFixRetries
|
|
@@ -563,6 +596,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
563
596
|
options.retry = numTestRetries
|
|
564
597
|
}
|
|
565
598
|
|
|
599
|
+
atrStatusesByScenarioKey.clear()
|
|
566
600
|
sessionStartCh.publish({ command, frameworkVersion })
|
|
567
601
|
|
|
568
602
|
if (!errorSkippableRequest && skippedSuites.length) {
|
|
@@ -1016,6 +1050,9 @@ addHook({
|
|
|
1016
1050
|
this.options.worldParameters._ddModifiedFiles = modifiedFiles
|
|
1017
1051
|
}
|
|
1018
1052
|
|
|
1053
|
+
this.options.worldParameters._ddIsFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
|
|
1054
|
+
this.options.worldParameters._ddNumTestRetries = numTestRetries
|
|
1055
|
+
|
|
1019
1056
|
return startWorker.apply(this, arguments)
|
|
1020
1057
|
})
|
|
1021
1058
|
return adapterPackage
|
|
@@ -1051,6 +1088,8 @@ addHook({
|
|
|
1051
1088
|
if (isImpactedTestsEnabled) {
|
|
1052
1089
|
modifiedFiles = this.options.worldParameters._ddModifiedFiles
|
|
1053
1090
|
}
|
|
1091
|
+
isFlakyTestRetriesEnabled = !!this.options.worldParameters._ddIsFlakyTestRetriesEnabled
|
|
1092
|
+
numTestRetries = this.options.worldParameters._ddNumTestRetries ?? 0
|
|
1054
1093
|
}
|
|
1055
1094
|
)
|
|
1056
1095
|
return workerPackage
|
|
@@ -6,12 +6,21 @@ const {
|
|
|
6
6
|
addHook,
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
8
|
|
|
9
|
-
addHook({ name: '@elastic/transport', file: 'lib/Transport.js', versions: ['>=8'] }, (exports) => {
|
|
10
|
-
|
|
11
|
-
shimmer.wrap(exports.default.prototype, 'getConnection', createWrapGetConnection('elasticsearch'))
|
|
9
|
+
addHook({ name: '@elastic/transport', file: 'lib/Transport.js', versions: ['>=8 <9'] }, (exports) => {
|
|
10
|
+
wrapTransportPrototype(exports.default)
|
|
12
11
|
return exports
|
|
13
12
|
})
|
|
14
13
|
|
|
14
|
+
addHook({ name: '@elastic/transport', versions: ['>=9'] }, (exports) => {
|
|
15
|
+
wrapTransportPrototype(exports.Transport)
|
|
16
|
+
return exports
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
function wrapTransportPrototype (Transport) {
|
|
20
|
+
shimmer.wrap(Transport.prototype, 'request', createWrapRequest('elasticsearch'))
|
|
21
|
+
shimmer.wrap(Transport.prototype, 'getConnection', createWrapGetConnection('elasticsearch'))
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
addHook({ name: '@elastic/elasticsearch', file: 'lib/Transport.js', versions: ['>=5.6.16 <8', '>=8'] }, Transport => {
|
|
16
25
|
shimmer.wrap(Transport.prototype, 'request', createWrapRequest('elasticsearch'))
|
|
17
26
|
shimmer.wrap(Transport.prototype, 'getConnection', createWrapGetConnection('elasticsearch'))
|
|
@@ -8,6 +8,7 @@ module.exports = {
|
|
|
8
8
|
'@aws-sdk/smithy-client': () => require('../aws-sdk'),
|
|
9
9
|
'@azure/event-hubs': () => require('../azure-event-hubs'),
|
|
10
10
|
'@azure/functions': () => require('../azure-functions'),
|
|
11
|
+
'durable-functions': () => require('../azure-durable-functions'),
|
|
11
12
|
'@azure/service-bus': () => require('../azure-service-bus'),
|
|
12
13
|
'@cucumber/cucumber': () => require('../cucumber'),
|
|
13
14
|
'@playwright/test': () => require('../playwright'),
|
|
@@ -47,6 +47,7 @@ const testSkippedCh = channel('ci:jest:test:skip')
|
|
|
47
47
|
const testFinishCh = channel('ci:jest:test:finish')
|
|
48
48
|
const testErrCh = channel('ci:jest:test:err')
|
|
49
49
|
const testFnCh = channel('ci:jest:test:fn')
|
|
50
|
+
const testSuiteHookFnCh = channel('ci:jest:test-suite:hook:fn')
|
|
50
51
|
|
|
51
52
|
const skippableSuitesCh = channel('ci:jest:test-suite:skippable')
|
|
52
53
|
const libraryConfigurationCh = channel('ci:jest:library-configuration')
|
|
@@ -505,6 +506,19 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
505
506
|
})
|
|
506
507
|
}
|
|
507
508
|
|
|
509
|
+
if (event.name === 'hook_start' && (event.hook.type === 'beforeAll' || event.hook.type === 'afterAll')) {
|
|
510
|
+
const ctx = { testSuiteAbsolutePath: this.testSuiteAbsolutePath }
|
|
511
|
+
let hookFn = event.hook.fn
|
|
512
|
+
if (originalHookFns.has(event.hook)) {
|
|
513
|
+
hookFn = originalHookFns.get(event.hook)
|
|
514
|
+
} else {
|
|
515
|
+
originalHookFns.set(event.hook, hookFn)
|
|
516
|
+
}
|
|
517
|
+
event.hook.fn = shimmer.wrapFunction(hookFn, hookFn => function () {
|
|
518
|
+
return testSuiteHookFnCh.runStores(ctx, () => hookFn.apply(this, arguments))
|
|
519
|
+
})
|
|
520
|
+
}
|
|
521
|
+
|
|
508
522
|
if (event.name === 'add_test') {
|
|
509
523
|
if (event.failing) {
|
|
510
524
|
return
|
|
@@ -673,6 +687,14 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
673
687
|
}
|
|
674
688
|
}
|
|
675
689
|
|
|
690
|
+
// ATR: set failedAllTests when all auto test retries were exhausted and every attempt failed
|
|
691
|
+
if (this.isFlakyTestRetriesEnabled && !isAttemptToFix && !isEfdRetry) {
|
|
692
|
+
const maxRetries = Number(this.global[RETRY_TIMES]) || 0
|
|
693
|
+
if (event.test?.invocations === maxRetries + 1 && status === 'fail') {
|
|
694
|
+
failedAllTests = true
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
676
698
|
const promises = {}
|
|
677
699
|
const numRetries = this.global[RETRY_TIMES]
|
|
678
700
|
const numTestExecutions = event.test?.invocations
|
|
@@ -315,10 +315,10 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
|
|
|
315
315
|
config.isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
316
316
|
config.testManagementAttemptToFixRetries = libraryConfig.testManagementAttemptToFixRetries
|
|
317
317
|
config.isImpactedTestsEnabled = libraryConfig.isImpactedTestsEnabled
|
|
318
|
-
// ITR
|
|
318
|
+
// ITR is not supported in parallel mode yet
|
|
319
319
|
config.isSuitesSkippingEnabled = !isParallel && libraryConfig.isSuitesSkippingEnabled
|
|
320
|
-
config.isFlakyTestRetriesEnabled =
|
|
321
|
-
config.flakyTestRetriesCount =
|
|
320
|
+
config.isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
|
|
321
|
+
config.flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
|
|
322
322
|
|
|
323
323
|
if (config.isKnownTestsEnabled) {
|
|
324
324
|
ctx.onDone = onReceivedKnownTests
|
|
@@ -663,7 +663,8 @@ addHook({
|
|
|
663
663
|
if (!testFinishCh.hasSubscribers ||
|
|
664
664
|
(!config.isKnownTestsEnabled &&
|
|
665
665
|
!config.isTestManagementTestsEnabled &&
|
|
666
|
-
!config.isImpactedTestsEnabled
|
|
666
|
+
!config.isImpactedTestsEnabled &&
|
|
667
|
+
!config.isFlakyTestRetriesEnabled)) {
|
|
667
668
|
return run.apply(this, arguments)
|
|
668
669
|
}
|
|
669
670
|
|
|
@@ -709,6 +710,11 @@ addHook({
|
|
|
709
710
|
newWorkerArgs._ddModifiedFiles = config.modifiedFiles || {}
|
|
710
711
|
}
|
|
711
712
|
|
|
713
|
+
if (config.isFlakyTestRetriesEnabled) {
|
|
714
|
+
newWorkerArgs._ddIsFlakyTestRetriesEnabled = true
|
|
715
|
+
newWorkerArgs._ddFlakyTestRetriesCount = config.flakyTestRetriesCount
|
|
716
|
+
}
|
|
717
|
+
|
|
712
718
|
// We pass the known tests for the test file to the worker
|
|
713
719
|
const testFileResult = await run.apply(
|
|
714
720
|
this,
|
|
@@ -289,6 +289,12 @@ function getOnTestEndHandler (config) {
|
|
|
289
289
|
hasFailedAllRetries = true
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
+
// ATR: set hasFailedAllRetries when all auto test retries were exhausted and every attempt failed
|
|
293
|
+
if (config.isFlakyTestRetriesEnabled && !test._ddIsAttemptToFix && !test._ddIsEfdRetry &&
|
|
294
|
+
getIsLastRetry(test) && testStatuses.every(status => status === 'fail')) {
|
|
295
|
+
hasFailedAllRetries = true
|
|
296
|
+
}
|
|
297
|
+
|
|
292
298
|
const isAttemptToFixRetry = test._ddIsAttemptToFix && testStatuses.length > 1
|
|
293
299
|
const isAtrRetry = config.isFlakyTestRetriesEnabled &&
|
|
294
300
|
!test._ddIsAttemptToFix &&
|
|
@@ -10,6 +10,7 @@ const {
|
|
|
10
10
|
getOnHookEndHandler,
|
|
11
11
|
getOnFailHandler,
|
|
12
12
|
getOnPendingHandler,
|
|
13
|
+
getOnTestRetryHandler,
|
|
13
14
|
getRunTestsWrapper,
|
|
14
15
|
} = require('./utils')
|
|
15
16
|
require('./common')
|
|
@@ -48,6 +49,12 @@ addHook({
|
|
|
48
49
|
delete this.options._ddIsTestManagementTestsEnabled
|
|
49
50
|
delete this.options._ddTestManagementTests
|
|
50
51
|
}
|
|
52
|
+
if (this.options._ddIsFlakyTestRetriesEnabled) {
|
|
53
|
+
config.isFlakyTestRetriesEnabled = true
|
|
54
|
+
config.flakyTestRetriesCount = this.options._ddFlakyTestRetriesCount
|
|
55
|
+
delete this.options._ddIsFlakyTestRetriesEnabled
|
|
56
|
+
delete this.options._ddFlakyTestRetriesCount
|
|
57
|
+
}
|
|
51
58
|
return run.apply(this, arguments)
|
|
52
59
|
})
|
|
53
60
|
|
|
@@ -74,6 +81,8 @@ addHook({
|
|
|
74
81
|
|
|
75
82
|
this.on('test end', getOnTestEndHandler(config))
|
|
76
83
|
|
|
84
|
+
this.on('retry', getOnTestRetryHandler(config))
|
|
85
|
+
|
|
77
86
|
// If the hook passes, 'hook end' will be emitted. Otherwise, 'fail' will be emitted
|
|
78
87
|
this.on('hook end', getOnHookEndHandler())
|
|
79
88
|
|
|
@@ -92,5 +101,4 @@ addHook({
|
|
|
92
101
|
name: 'mocha',
|
|
93
102
|
versions: ['>=5.2.0'],
|
|
94
103
|
file: 'lib/runnable.js',
|
|
95
|
-
}, runnableWrapper)
|
|
96
|
-
// TODO: parallel mode does not support flaky test retries, so no library config is passed.
|
|
104
|
+
}, (runnablePackage) => runnableWrapper(runnablePackage, config))
|
|
@@ -302,6 +302,7 @@ function testBeginHandler (test, browserName, shouldCreateTestSpan) {
|
|
|
302
302
|
const {
|
|
303
303
|
_requireFile: testSuiteAbsolutePath,
|
|
304
304
|
location: {
|
|
305
|
+
file: testSourceFileAbsolutePath,
|
|
305
306
|
line: testSourceLine,
|
|
306
307
|
},
|
|
307
308
|
_type,
|
|
@@ -319,7 +320,7 @@ function testBeginHandler (test, browserName, shouldCreateTestSpan) {
|
|
|
319
320
|
|
|
320
321
|
if (isNewTestSuite) {
|
|
321
322
|
startedSuites.push(testSuiteAbsolutePath)
|
|
322
|
-
const testSuiteCtx = { testSuiteAbsolutePath }
|
|
323
|
+
const testSuiteCtx = { testSuiteAbsolutePath, testSourceFileAbsolutePath }
|
|
323
324
|
testSuiteToCtx.set(testSuiteAbsolutePath, testSuiteCtx)
|
|
324
325
|
testSuiteStartCh.runStores(testSuiteCtx, () => {})
|
|
325
326
|
}
|
|
@@ -335,6 +336,7 @@ function testBeginHandler (test, browserName, shouldCreateTestSpan) {
|
|
|
335
336
|
const testCtx = {
|
|
336
337
|
testName,
|
|
337
338
|
testSuiteAbsolutePath,
|
|
339
|
+
testSourceFileAbsolutePath,
|
|
338
340
|
testSourceLine,
|
|
339
341
|
browserName,
|
|
340
342
|
isDisabled: test._ddIsDisabled,
|
|
@@ -404,6 +406,15 @@ function testEndHandler ({
|
|
|
404
406
|
test._ddHasFailedAllRetries = true
|
|
405
407
|
}
|
|
406
408
|
|
|
409
|
+
// ATR: set _ddHasFailedAllRetries when all auto test retries were exhausted and every attempt failed
|
|
410
|
+
if (isFlakyTestRetriesEnabled && !testProperties.attemptToFix && !test._ddIsEfdRetry &&
|
|
411
|
+
!(test._ddIsNew || test._ddIsModified) &&
|
|
412
|
+
flakyTestRetriesCount != null && flakyTestRetriesCount > 0 &&
|
|
413
|
+
testStatuses.length === flakyTestRetriesCount + 1 &&
|
|
414
|
+
testStatuses.every(status => status === 'fail')) {
|
|
415
|
+
test._ddHasFailedAllRetries = true
|
|
416
|
+
}
|
|
417
|
+
|
|
407
418
|
// this handles tests that do not go through the worker process (because they're skipped)
|
|
408
419
|
if (shouldCreateTestSpan) {
|
|
409
420
|
const testResult = results.at(-1)
|
|
@@ -459,6 +470,7 @@ function testEndHandler ({
|
|
|
459
470
|
testSkipCh.publish({
|
|
460
471
|
testName: getTestFullname(test),
|
|
461
472
|
testSuiteAbsolutePath,
|
|
473
|
+
testSourceFileAbsolutePath: test.location.file,
|
|
462
474
|
testSourceLine: test.location.line,
|
|
463
475
|
browserName,
|
|
464
476
|
isNew: test._ddIsNew,
|
|
@@ -1144,6 +1156,7 @@ addHook({
|
|
|
1144
1156
|
const {
|
|
1145
1157
|
_requireFile: testSuiteAbsolutePath,
|
|
1146
1158
|
location: {
|
|
1159
|
+
file: testSourceFileAbsolutePath,
|
|
1147
1160
|
line: testSourceLine,
|
|
1148
1161
|
},
|
|
1149
1162
|
} = test
|
|
@@ -1159,6 +1172,7 @@ addHook({
|
|
|
1159
1172
|
const testCtx = {
|
|
1160
1173
|
testName,
|
|
1161
1174
|
testSuiteAbsolutePath,
|
|
1175
|
+
testSourceFileAbsolutePath,
|
|
1162
1176
|
testSourceLine,
|
|
1163
1177
|
browserName,
|
|
1164
1178
|
}
|
|
@@ -1322,7 +1336,10 @@ function generateSummaryWrapper (generateSummary) {
|
|
|
1322
1336
|
if (didNotRun) {
|
|
1323
1337
|
const {
|
|
1324
1338
|
_requireFile: testSuiteAbsolutePath,
|
|
1325
|
-
location: {
|
|
1339
|
+
location: {
|
|
1340
|
+
file: testSourceFileAbsolutePath,
|
|
1341
|
+
line: testSourceLine,
|
|
1342
|
+
},
|
|
1326
1343
|
_ddIsNew: isNew,
|
|
1327
1344
|
_ddIsDisabled: isDisabled,
|
|
1328
1345
|
_ddIsModified: isModified,
|
|
@@ -1333,6 +1350,7 @@ function generateSummaryWrapper (generateSummary) {
|
|
|
1333
1350
|
testSkipCh.publish({
|
|
1334
1351
|
testName: getTestFullname(test),
|
|
1335
1352
|
testSuiteAbsolutePath,
|
|
1353
|
+
testSourceFileAbsolutePath,
|
|
1336
1354
|
testSourceLine,
|
|
1337
1355
|
browserName,
|
|
1338
1356
|
isNew,
|
|
@@ -172,8 +172,10 @@ const prismaHook = (runtime, versions, name, isIitm) => {
|
|
|
172
172
|
prismaHelperInit.publish(prismaHelperCtx)
|
|
173
173
|
|
|
174
174
|
const helper = prismaHelperCtx.helper
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
if (helper) {
|
|
176
|
+
this._tracingHelper = helper
|
|
177
|
+
this._engine.tracingHelper = helper
|
|
178
|
+
}
|
|
177
179
|
}
|
|
178
180
|
}
|
|
179
181
|
}
|
|
@@ -95,6 +95,7 @@ function getProvidedContext () {
|
|
|
95
95
|
_ddTestManagementAttemptToFixRetries: testManagementAttemptToFixRetries,
|
|
96
96
|
_ddTestManagementTests: testManagementTests,
|
|
97
97
|
_ddIsFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled,
|
|
98
|
+
_ddFlakyTestRetriesCount: flakyTestRetriesCount,
|
|
98
99
|
_ddIsImpactedTestsEnabled: isImpactedTestsEnabled,
|
|
99
100
|
_ddModifiedFiles: modifiedFiles,
|
|
100
101
|
} = globalThis.__vitest_worker__.providedContext
|
|
@@ -109,6 +110,7 @@ function getProvidedContext () {
|
|
|
109
110
|
testManagementAttemptToFixRetries,
|
|
110
111
|
testManagementTests,
|
|
111
112
|
isFlakyTestRetriesEnabled,
|
|
113
|
+
flakyTestRetriesCount: flakyTestRetriesCount ?? 0,
|
|
112
114
|
isImpactedTestsEnabled,
|
|
113
115
|
modifiedFiles,
|
|
114
116
|
}
|
|
@@ -124,6 +126,7 @@ function getProvidedContext () {
|
|
|
124
126
|
testManagementAttemptToFixRetries: 0,
|
|
125
127
|
testManagementTests: {},
|
|
126
128
|
isFlakyTestRetriesEnabled: false,
|
|
129
|
+
flakyTestRetriesCount: 0,
|
|
127
130
|
isImpactedTestsEnabled: false,
|
|
128
131
|
modifiedFiles: {},
|
|
129
132
|
}
|
|
@@ -260,6 +263,7 @@ function getSortWrapper (sort, frameworkVersion) {
|
|
|
260
263
|
? this.ctx.getCoreWorkspaceProject()
|
|
261
264
|
: this.ctx.getRootProject()
|
|
262
265
|
workspaceProject._provided._ddIsFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
|
|
266
|
+
workspaceProject._provided._ddFlakyTestRetriesCount = flakyTestRetriesCount
|
|
263
267
|
} catch {
|
|
264
268
|
log.warn('Could not send library configuration to workers.')
|
|
265
269
|
}
|
|
@@ -657,6 +661,9 @@ function wrapVitestTestRunner (VitestTestRunner) {
|
|
|
657
661
|
}
|
|
658
662
|
task.result.state = 'pass'
|
|
659
663
|
} else if (isQuarantined) {
|
|
664
|
+
if (task.result.state === 'fail') {
|
|
665
|
+
switchedStatuses.add(task)
|
|
666
|
+
}
|
|
660
667
|
task.result.state = 'pass'
|
|
661
668
|
}
|
|
662
669
|
}
|
|
@@ -1047,6 +1054,15 @@ addHook({
|
|
|
1047
1054
|
}
|
|
1048
1055
|
}
|
|
1049
1056
|
|
|
1057
|
+
// ATR: set hasFailedAllRetries when all auto test retries were exhausted and every attempt failed
|
|
1058
|
+
if (providedContext.isFlakyTestRetriesEnabled && !attemptToFixTasks.has(task) &&
|
|
1059
|
+
!newTasks.has(task) && !modifiedTasks.has(task)) {
|
|
1060
|
+
const maxRetries = providedContext.flakyTestRetriesCount ?? 0
|
|
1061
|
+
if (maxRetries > 0 && task.result?.retryCount === maxRetries) {
|
|
1062
|
+
hasFailedAllRetries = true
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1050
1066
|
if (testCtx) {
|
|
1051
1067
|
const isRetry = task.result?.retryCount > 0
|
|
1052
1068
|
// `duration` is the duration of all the retries, so it can't be used if there are retries
|
|
@@ -5,6 +5,14 @@ const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
|
5
5
|
class ApolloGatewayExecutePlugin extends ApolloBasePlugin {
|
|
6
6
|
static operation = 'execute'
|
|
7
7
|
static prefix = 'tracing:apm:apollo:gateway:execute'
|
|
8
|
+
|
|
9
|
+
onAsyncStart (ctx) {
|
|
10
|
+
const span = ctx?.currentStore?.span
|
|
11
|
+
|
|
12
|
+
if (!span) return
|
|
13
|
+
|
|
14
|
+
this.config.hooks.execute(span, ctx)
|
|
15
|
+
}
|
|
8
16
|
}
|
|
9
17
|
|
|
10
18
|
module.exports = ApolloGatewayExecutePlugin
|
|
@@ -29,6 +29,11 @@ class ApolloGatewayFetchPlugin extends ApolloBasePlugin {
|
|
|
29
29
|
|
|
30
30
|
return ctx.currentStore
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
onAsyncStart (ctx) {
|
|
34
|
+
const span = ctx?.currentStore?.span
|
|
35
|
+
this.config.hooks.fetch(span, ctx)
|
|
36
|
+
}
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
module.exports = ApolloGatewayFetchPlugin
|