dd-trace 5.89.0 → 5.91.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 +38 -0
- package/package.json +12 -11
- package/packages/datadog-instrumentations/src/azure-durable-functions.js +75 -0
- package/packages/datadog-instrumentations/src/cucumber.js +58 -4
- package/packages/datadog-instrumentations/src/elasticsearch.js +12 -3
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langgraph.js +30 -0
- package/packages/datadog-instrumentations/src/jest.js +31 -2
- package/packages/datadog-instrumentations/src/langgraph.js +7 -0
- package/packages/datadog-instrumentations/src/mocha/main.js +41 -12
- package/packages/datadog-instrumentations/src/mocha/utils.js +6 -1
- package/packages/datadog-instrumentations/src/mocha/worker.js +12 -4
- 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 +69 -24
- 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 +12 -2
- package/packages/datadog-plugin-cypress/src/support.js +5 -7
- package/packages/datadog-plugin-jest/src/index.js +6 -0
- package/packages/datadog-plugin-langgraph/src/index.js +24 -0
- package/packages/datadog-plugin-langgraph/src/stream.js +41 -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/defaults.js +1 -0
- package/packages/dd-trace/src/config/index.js +9 -1
- package/packages/dd-trace/src/config/supported-configurations.json +14 -0
- package/packages/dd-trace/src/constants.js +2 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +3 -0
- package/packages/dd-trace/src/dogstatsd.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/plugins/langchain/handlers/chain.js +11 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +114 -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/ci_plugin.js +2 -2
- package/packages/dd-trace/src/plugins/index.js +2 -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/test.js +7 -10
- package/packages/dd-trace/src/plugins/util/web.js +31 -11
- package/packages/dd-trace/src/priority_sampler.js +20 -2
- package/packages/dd-trace/src/process-tags/index.js +41 -34
- package/packages/dd-trace/src/profiling/profilers/wall.js +9 -1
- package/packages/dd-trace/src/proxy.js +4 -0
- 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;
|
|
@@ -261,6 +262,7 @@ interface Plugins {
|
|
|
261
262
|
"knex": tracer.plugins.knex;
|
|
262
263
|
"koa": tracer.plugins.koa;
|
|
263
264
|
"langchain": tracer.plugins.langchain;
|
|
265
|
+
"langgraph": tracer.plugins.langgraph;
|
|
264
266
|
"mariadb": tracer.plugins.mariadb;
|
|
265
267
|
"memcached": tracer.plugins.memcached;
|
|
266
268
|
"microgateway-core": tracer.plugins.microgateway_core;
|
|
@@ -1626,6 +1628,10 @@ declare namespace tracer {
|
|
|
1626
1628
|
* List of tags associated with the evaluation (e.g. indirect-prompt-injection)
|
|
1627
1629
|
*/
|
|
1628
1630
|
tags: string[];
|
|
1631
|
+
/**
|
|
1632
|
+
* Sensitive Data Scanner findings from the evaluation.
|
|
1633
|
+
*/
|
|
1634
|
+
sds: Object[];
|
|
1629
1635
|
}
|
|
1630
1636
|
|
|
1631
1637
|
/**
|
|
@@ -1641,6 +1647,10 @@ declare namespace tracer {
|
|
|
1641
1647
|
* List of tags associated with the evaluation (e.g. indirect-prompt-injection)
|
|
1642
1648
|
*/
|
|
1643
1649
|
tags: string[];
|
|
1650
|
+
/**
|
|
1651
|
+
* Sensitive Data Scanner findings from the evaluation.
|
|
1652
|
+
*/
|
|
1653
|
+
sds: Object[];
|
|
1644
1654
|
}
|
|
1645
1655
|
|
|
1646
1656
|
/**
|
|
@@ -2034,6 +2044,22 @@ declare namespace tracer {
|
|
|
2034
2044
|
* @default true
|
|
2035
2045
|
*/
|
|
2036
2046
|
signature?: boolean;
|
|
2047
|
+
|
|
2048
|
+
/**
|
|
2049
|
+
* An object of optional callbacks to be executed during the respective
|
|
2050
|
+
* phase of an Apollo Gateway operation. Undefined callbacks default to a
|
|
2051
|
+
* noop function.
|
|
2052
|
+
*
|
|
2053
|
+
* @default {}
|
|
2054
|
+
*/
|
|
2055
|
+
hooks?: {
|
|
2056
|
+
request?: (span?: Span, ctx?: any) => void;
|
|
2057
|
+
validate?: (span?: Span, ctx?: any) => void;
|
|
2058
|
+
plan?: (span?: Span, ctx?: any) => void;
|
|
2059
|
+
execute?: (span?: Span, ctx?: any) => void;
|
|
2060
|
+
fetch?: (span?: Span, ctx?: any) => void;
|
|
2061
|
+
postprocessing?: (span?: Span, ctx?: any) => void;
|
|
2062
|
+
};
|
|
2037
2063
|
}
|
|
2038
2064
|
|
|
2039
2065
|
/**
|
|
@@ -2097,6 +2123,12 @@ declare namespace tracer {
|
|
|
2097
2123
|
*/
|
|
2098
2124
|
interface azure_service_bus extends Integration {}
|
|
2099
2125
|
|
|
2126
|
+
/**
|
|
2127
|
+
* This plugin automatically instruments the
|
|
2128
|
+
* durable-functions module
|
|
2129
|
+
*/
|
|
2130
|
+
interface azure_durable_functions extends Integration {}
|
|
2131
|
+
|
|
2100
2132
|
/**
|
|
2101
2133
|
* This plugin patches the [bunyan](https://github.com/trentm/node-bunyan)
|
|
2102
2134
|
* to automatically inject trace identifiers in log records when the
|
|
@@ -2548,6 +2580,12 @@ declare namespace tracer {
|
|
|
2548
2580
|
|
|
2549
2581
|
/**
|
|
2550
2582
|
* This plugin automatically instruments the
|
|
2583
|
+
* [langgraph](https://github.com/npmjs/package/langgraph) library.
|
|
2584
|
+
*/
|
|
2585
|
+
interface langgraph extends Instrumentation {}
|
|
2586
|
+
|
|
2587
|
+
/**
|
|
2588
|
+
* This plugin automatically instruments the
|
|
2551
2589
|
* [ldapjs](https://github.com/ldapjs/node-ldapjs/) module.
|
|
2552
2590
|
*/
|
|
2553
2591
|
interface ldapjs extends Instrumentation {}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.91.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"env": "bash ./plugin-env",
|
|
9
|
+
"prepare": "cd vendor && npm ci --include=dev",
|
|
9
10
|
"preinstall": "node scripts/preinstall.js",
|
|
10
11
|
"bench": "node benchmark/index.js",
|
|
11
12
|
"bench:e2e:test-optimization": "node benchmark/e2e-test-optimization/benchmark-run.js",
|
|
@@ -142,22 +143,22 @@
|
|
|
142
143
|
"@datadog/native-iast-taint-tracking": "4.1.0",
|
|
143
144
|
"@datadog/native-metrics": "3.1.1",
|
|
144
145
|
"@datadog/openfeature-node-server": "^1.1.0",
|
|
145
|
-
"@datadog/pprof": "5.13.
|
|
146
|
+
"@datadog/pprof": "5.13.5",
|
|
146
147
|
"@datadog/wasm-js-rewriter": "5.0.1",
|
|
147
148
|
"@opentelemetry/api": ">=1.0.0 <1.10.0",
|
|
148
149
|
"@opentelemetry/api-logs": "<1.0.0",
|
|
149
|
-
"oxc-parser": "^0.
|
|
150
|
+
"oxc-parser": "^0.118.0"
|
|
150
151
|
},
|
|
151
152
|
"devDependencies": {
|
|
152
153
|
"@actions/core": "^3.0.0",
|
|
153
154
|
"@actions/github": "^9.0.0",
|
|
154
155
|
"@babel/helpers": "^7.28.6",
|
|
155
|
-
"@eslint/eslintrc": "^3.3.
|
|
156
|
+
"@eslint/eslintrc": "^3.3.5",
|
|
156
157
|
"@eslint/js": "^9.39.2",
|
|
157
158
|
"@msgpack/msgpack": "^3.1.3",
|
|
158
159
|
"@openfeature/core": "^1.8.1",
|
|
159
160
|
"@openfeature/server-sdk": "~1.20.0",
|
|
160
|
-
"@stylistic/eslint-plugin": "^5.
|
|
161
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
161
162
|
"@types/mocha": "^10.0.10",
|
|
162
163
|
"@types/node": "^18.19.106",
|
|
163
164
|
"@types/sinon": "^21.0.0",
|
|
@@ -165,11 +166,11 @@
|
|
|
165
166
|
"benchmark": "^2.1.4",
|
|
166
167
|
"body-parser": "^2.2.2",
|
|
167
168
|
"bun": "1.3.10",
|
|
168
|
-
"codeowners-audit": "^2.
|
|
169
|
+
"codeowners-audit": "^2.9.0",
|
|
169
170
|
"eslint": "^9.39.2",
|
|
170
|
-
"eslint-plugin-cypress": "^6.
|
|
171
|
+
"eslint-plugin-cypress": "^6.2.0",
|
|
171
172
|
"eslint-plugin-import": "^2.32.0",
|
|
172
|
-
"eslint-plugin-jsdoc": "^62.
|
|
173
|
+
"eslint-plugin-jsdoc": "^62.8.0",
|
|
173
174
|
"eslint-plugin-mocha": "^11.2.0",
|
|
174
175
|
"eslint-plugin-n": "^17.23.2",
|
|
175
176
|
"eslint-plugin-promise": "^7.2.1",
|
|
@@ -183,9 +184,9 @@
|
|
|
183
184
|
"mocha": "^11.6.0",
|
|
184
185
|
"mocha-junit-reporter": "^2.2.1",
|
|
185
186
|
"mocha-multi-reporters": "^1.5.1",
|
|
186
|
-
"multer": "^2.
|
|
187
|
+
"multer": "^2.1.1",
|
|
187
188
|
"nock": "^13.5.6",
|
|
188
|
-
"nyc": "^
|
|
189
|
+
"nyc": "^18.0.0",
|
|
189
190
|
"octokit": "^5.0.3",
|
|
190
191
|
"opentracing": ">=0.14.7",
|
|
191
192
|
"p-limit": "^7.2.0",
|
|
@@ -193,7 +194,7 @@
|
|
|
193
194
|
"retry": "^0.13.1",
|
|
194
195
|
"semifies": "^1.0.0",
|
|
195
196
|
"semver": "^7.7.2",
|
|
196
|
-
"sinon": "^21.0.
|
|
197
|
+
"sinon": "^21.0.2",
|
|
197
198
|
"tiktoken": "^1.0.21",
|
|
198
199
|
"typescript": "^5.9.2",
|
|
199
200
|
"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()
|
|
@@ -164,9 +166,9 @@ function getErrorFromCucumberResult (cucumberResult) {
|
|
|
164
166
|
return error
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
function getChannelPromise (channelToPublishTo,
|
|
169
|
+
function getChannelPromise (channelToPublishTo, frameworkVersion = null) {
|
|
168
170
|
return new Promise(resolve => {
|
|
169
|
-
channelToPublishTo.publish({ onDone: resolve,
|
|
171
|
+
channelToPublishTo.publish({ onDone: resolve, frameworkVersion })
|
|
170
172
|
})
|
|
171
173
|
}
|
|
172
174
|
|
|
@@ -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)
|
|
@@ -473,14 +505,15 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
473
505
|
}
|
|
474
506
|
let errorSkippableRequest
|
|
475
507
|
|
|
476
|
-
const configurationResponse = await getChannelPromise(libraryConfigurationCh,
|
|
508
|
+
const configurationResponse = await getChannelPromise(libraryConfigurationCh, frameworkVersion)
|
|
477
509
|
|
|
478
510
|
isEarlyFlakeDetectionEnabled = configurationResponse.libraryConfig?.isEarlyFlakeDetectionEnabled
|
|
479
511
|
earlyFlakeDetectionNumRetries = configurationResponse.libraryConfig?.earlyFlakeDetectionNumRetries
|
|
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) {
|
|
@@ -647,6 +681,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
647
681
|
let isQuarantined = false
|
|
648
682
|
let isModified = false
|
|
649
683
|
|
|
684
|
+
const originalDryRun = this.options.dryRun
|
|
650
685
|
if (isTestManagementTestsEnabled) {
|
|
651
686
|
const testProperties = getTestProperties(testSuitePath, pickle.name)
|
|
652
687
|
isAttemptToFix = testProperties.attemptToFix
|
|
@@ -685,6 +720,9 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
685
720
|
// TODO: for >=11 we could use `runTestCaseResult` instead of accumulating results in `lastStatusByPickleId`
|
|
686
721
|
let runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
|
|
687
722
|
|
|
723
|
+
// Restore dryRun so it doesn't affect subsequent tests in the same worker
|
|
724
|
+
this.options.dryRun = originalDryRun
|
|
725
|
+
|
|
688
726
|
const testStatuses = lastStatusByPickleId.get(pickle.id)
|
|
689
727
|
const lastTestStatus = testStatuses.at(-1)
|
|
690
728
|
|
|
@@ -1016,6 +1054,15 @@ addHook({
|
|
|
1016
1054
|
this.options.worldParameters._ddModifiedFiles = modifiedFiles
|
|
1017
1055
|
}
|
|
1018
1056
|
|
|
1057
|
+
this.options.worldParameters._ddIsFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
|
|
1058
|
+
this.options.worldParameters._ddNumTestRetries = numTestRetries
|
|
1059
|
+
|
|
1060
|
+
if (isTestManagementTestsEnabled) {
|
|
1061
|
+
this.options.worldParameters._ddIsTestManagementTestsEnabled = true
|
|
1062
|
+
this.options.worldParameters._ddTestManagementTests = testManagementTests
|
|
1063
|
+
this.options.worldParameters._ddTestManagementAttemptToFixRetries = testManagementAttemptToFixRetries
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1019
1066
|
return startWorker.apply(this, arguments)
|
|
1020
1067
|
})
|
|
1021
1068
|
return adapterPackage
|
|
@@ -1051,6 +1098,13 @@ addHook({
|
|
|
1051
1098
|
if (isImpactedTestsEnabled) {
|
|
1052
1099
|
modifiedFiles = this.options.worldParameters._ddModifiedFiles
|
|
1053
1100
|
}
|
|
1101
|
+
isFlakyTestRetriesEnabled = !!this.options.worldParameters._ddIsFlakyTestRetriesEnabled
|
|
1102
|
+
numTestRetries = this.options.worldParameters._ddNumTestRetries ?? 0
|
|
1103
|
+
isTestManagementTestsEnabled = !!this.options.worldParameters._ddIsTestManagementTestsEnabled
|
|
1104
|
+
if (isTestManagementTestsEnabled) {
|
|
1105
|
+
testManagementTests = this.options.worldParameters._ddTestManagementTests
|
|
1106
|
+
testManagementAttemptToFixRetries = this.options.worldParameters._ddTestManagementAttemptToFixRetries
|
|
1107
|
+
}
|
|
1054
1108
|
}
|
|
1055
1109
|
)
|
|
1056
1110
|
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'))
|
|
@@ -4,10 +4,12 @@ module.exports = {
|
|
|
4
4
|
'@anthropic-ai/sdk': { esmFirst: true, fn: () => require('../anthropic') },
|
|
5
5
|
'@apollo/server': () => require('../apollo-server'),
|
|
6
6
|
'@apollo/gateway': () => require('../apollo'),
|
|
7
|
+
'@langchain/langgraph': { esmFirst: true, fn: () => require('../langgraph') },
|
|
7
8
|
'apollo-server-core': () => require('../apollo-server-core'),
|
|
8
9
|
'@aws-sdk/smithy-client': () => require('../aws-sdk'),
|
|
9
10
|
'@azure/event-hubs': () => require('../azure-event-hubs'),
|
|
10
11
|
'@azure/functions': () => require('../azure-functions'),
|
|
12
|
+
'durable-functions': () => require('../azure-durable-functions'),
|
|
11
13
|
'@azure/service-bus': () => require('../azure-service-bus'),
|
|
12
14
|
'@cucumber/cucumber': () => require('../cucumber'),
|
|
13
15
|
'@playwright/test': () => require('../playwright'),
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = [
|
|
4
|
+
{
|
|
5
|
+
module: {
|
|
6
|
+
name: '@langchain/langgraph',
|
|
7
|
+
versionRange: '>=1.1.2',
|
|
8
|
+
filePath: 'dist/pregel/index.js',
|
|
9
|
+
},
|
|
10
|
+
functionQuery: {
|
|
11
|
+
methodName: 'stream',
|
|
12
|
+
className: 'Pregel',
|
|
13
|
+
kind: 'AsyncIterator',
|
|
14
|
+
},
|
|
15
|
+
channelName: 'Pregel_stream',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
module: {
|
|
19
|
+
name: '@langchain/langgraph',
|
|
20
|
+
versionRange: '>=1.1.2',
|
|
21
|
+
filePath: 'dist/pregel/index.cjs',
|
|
22
|
+
},
|
|
23
|
+
functionQuery: {
|
|
24
|
+
methodName: 'stream',
|
|
25
|
+
className: 'Pregel',
|
|
26
|
+
kind: 'AsyncIterator',
|
|
27
|
+
},
|
|
28
|
+
channelName: 'Pregel_stream',
|
|
29
|
+
},
|
|
30
|
+
]
|
|
@@ -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
|
|
@@ -680,11 +702,15 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
680
702
|
const mightHitBreakpoint = this.isDiEnabled && numTestExecutions >= 2
|
|
681
703
|
|
|
682
704
|
const ctx = testContexts.get(event.test)
|
|
705
|
+
if (!ctx) {
|
|
706
|
+
log.warn('"ci:jest:test_done": no context found for test "%s"', testName)
|
|
707
|
+
return
|
|
708
|
+
}
|
|
683
709
|
|
|
684
710
|
const finalStatus = this.getFinalStatus(testName,
|
|
685
711
|
status,
|
|
686
|
-
!!ctx
|
|
687
|
-
!!ctx
|
|
712
|
+
!!ctx.isNew,
|
|
713
|
+
!!ctx.isModified,
|
|
688
714
|
isEfdRetry,
|
|
689
715
|
isAttemptToFix,
|
|
690
716
|
numTestExecutions)
|
|
@@ -739,6 +765,9 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
739
765
|
efdDeterminedRetries.clear()
|
|
740
766
|
efdSlowAbortedTests.clear()
|
|
741
767
|
efdNewTestCandidates.clear()
|
|
768
|
+
retriedTestsToNumAttempts.clear()
|
|
769
|
+
attemptToFixRetriedTestsStatuses.clear()
|
|
770
|
+
testsToBeRetried.clear()
|
|
742
771
|
}
|
|
743
772
|
if (event.name === 'test_skip' || event.name === 'test_todo') {
|
|
744
773
|
const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
|
|
@@ -101,12 +101,12 @@ function getFilteredSuites (originalSuites) {
|
|
|
101
101
|
}, { suitesToRun: [], skippedSuites: new Set() })
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
function getOnStartHandler (
|
|
104
|
+
function getOnStartHandler (frameworkVersion) {
|
|
105
105
|
return function () {
|
|
106
106
|
const processArgv = process.argv.slice(2).join(' ')
|
|
107
107
|
const command = `mocha ${processArgv}`
|
|
108
108
|
testSessionStartCh.publish({ command, frameworkVersion })
|
|
109
|
-
if (
|
|
109
|
+
if (skippedSuites.length) {
|
|
110
110
|
itrSkippedSuitesCh.publish({ skippedSuites, frameworkVersion })
|
|
111
111
|
}
|
|
112
112
|
}
|
|
@@ -315,10 +315,9 @@ 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
|
-
|
|
319
|
-
config.
|
|
320
|
-
config.
|
|
321
|
-
config.flakyTestRetriesCount = !isParallel && libraryConfig.flakyTestRetriesCount
|
|
318
|
+
config.isSuitesSkippingEnabled = libraryConfig.isSuitesSkippingEnabled
|
|
319
|
+
config.isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
|
|
320
|
+
config.flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
|
|
322
321
|
|
|
323
322
|
if (config.isKnownTestsEnabled) {
|
|
324
323
|
ctx.onDone = onReceivedKnownTests
|
|
@@ -452,7 +451,7 @@ addHook({
|
|
|
452
451
|
|
|
453
452
|
const { suitesByTestFile, numSuitesByTestFile } = getSuitesByTestFile(this.suite)
|
|
454
453
|
|
|
455
|
-
this.once('start', getOnStartHandler(
|
|
454
|
+
this.once('start', getOnStartHandler(frameworkVersion))
|
|
456
455
|
|
|
457
456
|
this.once('end', getOnEndHandler(false))
|
|
458
457
|
|
|
@@ -623,9 +622,16 @@ addHook({
|
|
|
623
622
|
return run.apply(this, arguments)
|
|
624
623
|
}
|
|
625
624
|
|
|
626
|
-
this.once('start', getOnStartHandler(
|
|
625
|
+
this.once('start', getOnStartHandler(frameworkVersion))
|
|
627
626
|
this.once('end', getOnEndHandler(true))
|
|
628
627
|
|
|
628
|
+
// Populate unskippable suites before config is fetched (matches serial mode at Mocha.prototype.run)
|
|
629
|
+
for (const filePath of files) {
|
|
630
|
+
if (isMarkedAsUnskippable({ path: filePath })) {
|
|
631
|
+
unskippableSuites.push(filePath)
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
629
635
|
getExecutionConfiguration(this, true, frameworkVersion, () => {
|
|
630
636
|
if (config.isKnownTestsEnabled) {
|
|
631
637
|
const testSuites = files.map(file => getTestSuitePath(file, process.cwd()))
|
|
@@ -640,7 +646,25 @@ addHook({
|
|
|
640
646
|
config.isEarlyFlakeDetectionFaulty = true
|
|
641
647
|
}
|
|
642
648
|
}
|
|
643
|
-
|
|
649
|
+
if (config.isSuitesSkippingEnabled && suitesToSkip.length) {
|
|
650
|
+
const filteredFiles = []
|
|
651
|
+
const skippedFiles = []
|
|
652
|
+
for (const file of files) {
|
|
653
|
+
const testPath = getTestSuitePath(file, process.cwd())
|
|
654
|
+
const shouldSkip = suitesToSkip.includes(testPath)
|
|
655
|
+
const isUnskippable = unskippableSuites.includes(file)
|
|
656
|
+
if (shouldSkip && !isUnskippable) {
|
|
657
|
+
skippedFiles.push(testPath)
|
|
658
|
+
} else {
|
|
659
|
+
filteredFiles.push(file)
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
isSuitesSkipped = skippedFiles.length > 0
|
|
663
|
+
skippedSuites = skippedFiles
|
|
664
|
+
run.apply(this, [cb, { files: filteredFiles }])
|
|
665
|
+
} else {
|
|
666
|
+
run.apply(this, arguments)
|
|
667
|
+
}
|
|
644
668
|
})
|
|
645
669
|
|
|
646
670
|
return this
|
|
@@ -663,7 +687,8 @@ addHook({
|
|
|
663
687
|
if (!testFinishCh.hasSubscribers ||
|
|
664
688
|
(!config.isKnownTestsEnabled &&
|
|
665
689
|
!config.isTestManagementTestsEnabled &&
|
|
666
|
-
!config.isImpactedTestsEnabled
|
|
690
|
+
!config.isImpactedTestsEnabled &&
|
|
691
|
+
!config.isFlakyTestRetriesEnabled)) {
|
|
667
692
|
return run.apply(this, arguments)
|
|
668
693
|
}
|
|
669
694
|
|
|
@@ -693,8 +718,7 @@ addHook({
|
|
|
693
718
|
if (config.isTestManagementTestsEnabled) {
|
|
694
719
|
const testSuiteTestManagementTests = config.testManagementTests?.mocha?.suites?.[testPath] || {}
|
|
695
720
|
newWorkerArgs._ddIsTestManagementTestsEnabled = true
|
|
696
|
-
|
|
697
|
-
// newWorkerArgs._ddTestManagementAttemptToFixRetries = config.testManagementAttemptToFixRetries
|
|
721
|
+
newWorkerArgs._ddTestManagementAttemptToFixRetries = config.testManagementAttemptToFixRetries
|
|
698
722
|
newWorkerArgs._ddTestManagementTests = {
|
|
699
723
|
mocha: {
|
|
700
724
|
suites: {
|
|
@@ -709,6 +733,11 @@ addHook({
|
|
|
709
733
|
newWorkerArgs._ddModifiedFiles = config.modifiedFiles || {}
|
|
710
734
|
}
|
|
711
735
|
|
|
736
|
+
if (config.isFlakyTestRetriesEnabled) {
|
|
737
|
+
newWorkerArgs._ddIsFlakyTestRetriesEnabled = true
|
|
738
|
+
newWorkerArgs._ddFlakyTestRetriesCount = config.flakyTestRetriesCount
|
|
739
|
+
}
|
|
740
|
+
|
|
712
741
|
// We pass the known tests for the test file to the worker
|
|
713
742
|
const testFileResult = await run.apply(
|
|
714
743
|
this,
|