dd-trace 6.20.1 → 6.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ci/diagnose.js +9 -14
- package/ci/init.js +1 -2
- package/ci/test-optimization-validation/ci-discovery.js +9 -4
- package/ci/test-optimization-validation/executable.js +1 -5
- package/ci/test-optimization-validation/framework-adapters/cypress.js +1 -4
- package/ci/test-optimization-validation/framework-adapters/vitest.js +1 -1
- package/ci/test-optimization-validation/generated-files.js +6 -4
- package/ci/test-optimization-validation/generated-test-contract.js +7 -3
- package/ci/test-optimization-validation/manifest-scaffold.js +7 -2
- package/ci/test-optimization-validation/manifest-schema.js +6 -7
- package/ci/test-optimization-validation/report-writer.js +6 -2
- package/ci/test-optimization-validation/runner-command.js +2 -4
- package/ci/test-optimization-validation/runner-contract.js +1 -2
- package/ci/test-optimization-validation/scenarios/auto-test-retries.js +1 -15
- package/ci/vitest-no-worker-init-setup.mjs +10 -7
- package/index.d.ts +116 -17
- package/initialize.mjs +1 -3
- package/openfeature/rules-based.d.ts +11 -0
- package/openfeature/rules-based.js +7 -0
- package/package.json +13 -11
- package/packages/datadog-core/src/storage.js +16 -0
- package/packages/datadog-esbuild/index.js +18 -12
- package/packages/datadog-instrumentations/src/aerospike.js +3 -3
- package/packages/datadog-instrumentations/src/ai.js +3 -3
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -6
- package/packages/datadog-instrumentations/src/aws-sdk.js +21 -13
- package/packages/datadog-instrumentations/src/cassandra-driver.js +25 -20
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +9 -23
- package/packages/datadog-instrumentations/src/cucumber.js +48 -33
- package/packages/datadog-instrumentations/src/elasticsearch.js +1 -5
- package/packages/datadog-instrumentations/src/electron.js +6 -6
- package/packages/datadog-instrumentations/src/fastify.js +13 -4
- package/packages/datadog-instrumentations/src/fs.js +2 -2
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +9 -5
- package/packages/datadog-instrumentations/src/grpc/client.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +36 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +87 -6
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +5 -6
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +48 -31
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +64 -11
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +42 -4
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +7 -10
- package/packages/datadog-instrumentations/src/ioredis.js +7 -5
- package/packages/datadog-instrumentations/src/iovalkey.js +7 -5
- package/packages/datadog-instrumentations/src/jest.js +122 -11
- package/packages/datadog-instrumentations/src/knex.js +9 -5
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +3 -3
- package/packages/datadog-instrumentations/src/mocha/common.js +20 -8
- package/packages/datadog-instrumentations/src/mocha/main.js +140 -43
- package/packages/datadog-instrumentations/src/mocha/utils.js +127 -38
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +61 -34
- package/packages/datadog-instrumentations/src/mocha/worker.js +7 -5
- package/packages/datadog-instrumentations/src/mongodb-core.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +3 -3
- package/packages/datadog-instrumentations/src/nova-sonic/audio.js +173 -0
- package/packages/datadog-instrumentations/src/nova-sonic/index.js +209 -0
- package/packages/datadog-instrumentations/src/nova-sonic/session.js +483 -0
- package/packages/datadog-instrumentations/src/openai-realtime/index.js +18 -6
- package/packages/datadog-instrumentations/src/openai-realtime/session.js +1 -1
- package/packages/datadog-instrumentations/src/openai.js +7 -0
- package/packages/datadog-instrumentations/src/pino.js +5 -6
- package/packages/datadog-instrumentations/src/playwright.js +3 -0
- package/packages/datadog-instrumentations/src/redis.js +27 -13
- package/packages/datadog-instrumentations/src/router.js +30 -0
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +2 -6
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +7 -5
- package/packages/datadog-instrumentations/src/vitest-main.js +9 -17
- package/packages/datadog-instrumentations/src/vitest-util.js +2 -2
- package/packages/datadog-instrumentations/src/vitest-worker.js +1 -2
- package/packages/datadog-instrumentations/src/vitest.js +2 -2
- package/packages/datadog-instrumentations/src/webdriverio.js +118 -21
- package/packages/datadog-instrumentations/src/ws.js +1 -4
- package/packages/datadog-plugin-amqplib/src/client.js +1 -2
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -5
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +5 -8
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +18 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/sonic.js +45 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +9 -3
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -5
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +5 -4
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -3
- package/packages/datadog-plugin-claude-agent-sdk/src/index.js +0 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +18 -5
- package/packages/datadog-plugin-cypress/src/index.js +6 -6
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -2
- package/packages/datadog-plugin-cypress/src/support.js +1 -4
- package/packages/datadog-plugin-express/src/code_origin.js +1 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -2
- package/packages/datadog-plugin-graphql/src/execute.js +5 -5
- package/packages/datadog-plugin-grpc/src/util.js +1 -2
- package/packages/datadog-plugin-kafkajs/src/producer.js +1 -2
- package/packages/datadog-plugin-mocha/src/index.js +223 -39
- package/packages/datadog-plugin-mocha/src/webdriverio-video.js +453 -0
- package/packages/datadog-plugin-mongodb-core/src/query.js +8 -5
- package/packages/datadog-plugin-next/src/index.js +1 -2
- package/packages/datadog-plugin-openai/src/tracing.js +5 -2
- package/packages/datadog-plugin-openai-agents/src/integration.js +6 -2
- package/packages/datadog-plugin-openai-agents/src/processor.js +2 -4
- package/packages/datadog-plugin-postgres/src/index.js +24 -0
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -5
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -4
- package/packages/datadog-plugin-vitest/src/index.js +5 -2
- package/packages/datadog-shimmer/src/shimmer.js +5 -4
- package/packages/datadog-webpack/index.js +55 -43
- package/packages/datadog-webpack/src/loader.js +56 -8
- package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +2 -4
- package/packages/dd-trace/src/aiguard/messages/utils.js +1 -2
- package/packages/dd-trace/src/aiguard/redaction.js +8 -2
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +3 -2
- package/packages/dd-trace/src/appsec/api_security/sampler.js +2 -6
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -9
- package/packages/dd-trace/src/appsec/handlers/http-request.js +3 -9
- package/packages/dd-trace/src/appsec/handlers/http-response.js +7 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +4 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +1 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +7 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -3
- package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +1 -6
- package/packages/dd-trace/src/appsec/lambda.js +1 -3
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +37 -27
- package/packages/dd-trace/src/appsec/rasp/lfi.js +9 -5
- package/packages/dd-trace/src/appsec/reporter.js +21 -1
- package/packages/dd-trace/src/appsec/stack_trace.js +1 -2
- package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +3 -6
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +13 -7
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +1 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +2 -8
- package/packages/dd-trace/src/ci-visibility/resolve-runfile-path.js +54 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +5 -8
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +2 -53
- package/packages/dd-trace/src/config/config-types.d.ts +2 -2
- package/packages/dd-trace/src/config/defaults.js +5 -5
- package/packages/dd-trace/src/config/generated-config-types.d.ts +8 -0
- package/packages/dd-trace/src/config/helper.js +34 -3
- package/packages/dd-trace/src/config/index.js +10 -9
- package/packages/dd-trace/src/config/normalize-service.js +1 -1
- package/packages/dd-trace/src/config/parsers.js +2 -2
- package/packages/dd-trace/src/config/supported-configurations.json +35 -0
- package/packages/dd-trace/src/datastreams/processor.js +3 -2
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -4
- package/packages/dd-trace/src/debugger/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +5 -3
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +17 -12
- package/packages/dd-trace/src/debugger/devtools_client/send.js +7 -2
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/worker-error.js +21 -0
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +2 -2
- package/packages/dd-trace/src/debugger/index.js +24 -2
- package/packages/dd-trace/src/debugger/probe_sampler.js +108 -11
- package/packages/dd-trace/src/dogstatsd.js +1 -1
- package/packages/dd-trace/src/encode/tags-processors.js +2 -2
- package/packages/dd-trace/src/exporters/common/request.js +2 -5
- package/packages/dd-trace/src/exporters/common/url.js +1 -1
- package/packages/dd-trace/src/id.js +15 -5
- package/packages/dd-trace/src/lambda/handler.js +179 -19
- package/packages/dd-trace/src/lambda/index.js +15 -1
- package/packages/dd-trace/src/lambda/runtime/patch.js +34 -7
- package/packages/dd-trace/src/llmobs/agent-manifest.js +296 -0
- package/packages/dd-trace/src/llmobs/audio-utils.js +3 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +13 -0
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +15 -0
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +1 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +1 -3
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/nova-sonic.js +92 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +56 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +38 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +5 -7
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +23 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +18 -8
- package/packages/dd-trace/src/llmobs/tagger.js +56 -3
- package/packages/dd-trace/src/llmobs/util.js +1 -2
- package/packages/dd-trace/src/llmobs/writers/base.js +7 -6
- package/packages/dd-trace/src/llmobs/writers/util.js +3 -1
- package/packages/dd-trace/src/log/log.js +1 -5
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +30 -1
- package/packages/dd-trace/src/openfeature/configuration_source.js +17 -2
- package/packages/dd-trace/src/openfeature/debug-logging-hook.js +25 -0
- package/packages/dd-trace/src/openfeature/evaluation-telemetry-opt-out-hook.js +51 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +59 -3
- package/packages/dd-trace/src/openfeature/remote_config.js +9 -0
- package/packages/dd-trace/src/openfeature/writers/util.js +43 -4
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -2
- package/packages/dd-trace/src/opentelemetry/otlp/common.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/resource-attributes.js +1 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +6 -23
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +53 -13
- package/packages/dd-trace/src/otel-sampling.js +4 -5
- package/packages/dd-trace/src/otel-thread-ctx.js +81 -15
- package/packages/dd-trace/src/plugins/database.js +7 -16
- package/packages/dd-trace/src/plugins/util/git.js +9 -25
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -5
- package/packages/dd-trace/src/plugins/util/test.js +48 -4
- package/packages/dd-trace/src/priority_sampler.js +1 -2
- package/packages/dd-trace/src/profiling/profiler.js +4 -6
- package/packages/dd-trace/src/profiling/profilers/wall.js +4 -10
- package/packages/dd-trace/src/proxy.js +3 -2
- package/packages/dd-trace/src/ritm.js +4 -2
- package/packages/dd-trace/src/serverless.js +10 -0
- package/packages/dd-trace/src/span_processor.js +13 -17
- package/packages/dd-trace/src/storage-channels.js +112 -46
- package/packages/dd-trace/src/telemetry/endpoints.js +1 -3
- package/packages/dd-trace/src/util.js +29 -0
- package/packages/dd-trace/src/web-tags-cache.js +6 -2
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- package/vendor/dist/@datadog/openfeature-node-server/rules-based/LICENSE +201 -0
- package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.d.ts +925 -0
- package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.js +1 -0
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/shell-quote/index.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.22.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"test:integration:webdriverio": "mocha --timeout 60000 \"integration-tests/webdriverio/${SPEC:-*}.spec.js\"",
|
|
110
110
|
"test:integration:webdriverio:coverage": "node ./integration-tests/coverage/run-suite.js --timeout 60000 \"integration-tests/webdriverio/${SPEC:-*}.spec.js\"",
|
|
111
111
|
"test:integration:vitest": "mocha --timeout 60000 \"integration-tests/vitest/${SPEC:-vitest*}.spec.js\"",
|
|
112
|
-
"test:integration:vitest:coverage": "node ./integration-tests/
|
|
112
|
+
"test:integration:vitest:coverage": "node ./integration-tests/vitest/run-with-coverage.js --timeout 60000 \"integration-tests/vitest/${SPEC:-vitest*}.spec.js\"",
|
|
113
113
|
"test:integration:testopt": "mocha --timeout 120000 \"integration-tests/ci-visibility/*.spec.js\"",
|
|
114
114
|
"test:integration:testopt:coverage": "node ./integration-tests/coverage/run-suite.js --timeout 120000 \"integration-tests/ci-visibility/*.spec.js\"",
|
|
115
115
|
"test:integration:profiler": "mocha --timeout 180000 \"integration-tests/profiler/*.spec.js\"",
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"bugs": {
|
|
144
144
|
"url": "https://github.com/DataDog/dd-trace-js/issues"
|
|
145
145
|
},
|
|
146
|
-
"homepage": "https://github.com/DataDog/dd-trace-js
|
|
146
|
+
"homepage": "https://github.com/DataDog/dd-trace-js",
|
|
147
147
|
"engines": {
|
|
148
148
|
"node": ">=22"
|
|
149
149
|
},
|
|
@@ -169,6 +169,8 @@
|
|
|
169
169
|
"loader-hook.mjs",
|
|
170
170
|
"openfeature.d.ts",
|
|
171
171
|
"openfeature.js",
|
|
172
|
+
"openfeature/rules-based.js",
|
|
173
|
+
"openfeature/rules-based.d.ts",
|
|
172
174
|
"packages/*/index.js",
|
|
173
175
|
"packages/*/index.electron.js",
|
|
174
176
|
"packages/*/lib/**/*",
|
|
@@ -193,7 +195,7 @@
|
|
|
193
195
|
"@datadog/native-appsec": "11.0.3",
|
|
194
196
|
"@datadog/native-iast-taint-tracking": "4.2.1",
|
|
195
197
|
"@datadog/native-metrics": "4.0.0",
|
|
196
|
-
"@datadog/pprof": "5.
|
|
198
|
+
"@datadog/pprof": "5.20.0",
|
|
197
199
|
"@datadog/wasm-js-rewriter": "5.0.4",
|
|
198
200
|
"@opentelemetry/api": ">=1.0.0 <1.10.0",
|
|
199
201
|
"@opentelemetry/api-logs": "<1.0.0",
|
|
@@ -202,11 +204,11 @@
|
|
|
202
204
|
"devDependencies": {
|
|
203
205
|
"@actions/core": "^3.0.1",
|
|
204
206
|
"@actions/github": "^9.1.1",
|
|
205
|
-
"@babel/helpers": "^8.0.
|
|
207
|
+
"@babel/helpers": "^8.0.7",
|
|
206
208
|
"@eslint/eslintrc": "^3.3.7",
|
|
207
209
|
"@eslint/js": "^10.0.1",
|
|
208
210
|
"@eslint/plugin-kit": "^0.7.3",
|
|
209
|
-
"@datadog/openfeature-node-server": "2.
|
|
211
|
+
"@datadog/openfeature-node-server": "2.5.0",
|
|
210
212
|
"@msgpack/msgpack": "^3.1.3",
|
|
211
213
|
"@openfeature/core": "^1.12.0",
|
|
212
214
|
"@openfeature/server-sdk": "~1.23.0",
|
|
@@ -218,20 +220,20 @@
|
|
|
218
220
|
"@yarnpkg/lockfile": "^1.1.0",
|
|
219
221
|
"benchmark": "^2.1.4",
|
|
220
222
|
"body-parser": "^2.3.0",
|
|
221
|
-
"bun": "1.4.
|
|
223
|
+
"bun": "1.4.3",
|
|
222
224
|
"c8": "^12.0.0",
|
|
223
225
|
"codeowners-audit": "^2.9.0",
|
|
224
|
-
"eslint": "^10.
|
|
226
|
+
"eslint": "^10.13.0",
|
|
225
227
|
"eslint-plugin-cypress": "^7.0.2",
|
|
226
228
|
"eslint-plugin-import-x": "^4.16.2",
|
|
227
|
-
"eslint-plugin-jsdoc": "^
|
|
229
|
+
"eslint-plugin-jsdoc": "^65.3.12",
|
|
228
230
|
"eslint-plugin-mocha": "^12.0.2",
|
|
229
|
-
"eslint-plugin-n": "^18.
|
|
231
|
+
"eslint-plugin-n": "^18.5.0",
|
|
230
232
|
"eslint-plugin-promise": "^7.3.0",
|
|
231
233
|
"eslint-plugin-regexp": "^3.3.1",
|
|
232
234
|
"eslint-plugin-sonarjs": "^4.2.2",
|
|
233
235
|
"eslint-plugin-unicorn": "^74.0.0",
|
|
234
|
-
"express": "^5.
|
|
236
|
+
"express": "^5.3.0",
|
|
235
237
|
"glob": "^10.4.5",
|
|
236
238
|
"globals": "^17.13.0",
|
|
237
239
|
"graphql": "*",
|
|
@@ -56,12 +56,28 @@ const isACFActive = (() => {
|
|
|
56
56
|
if (!isACFActive) {
|
|
57
57
|
const superGetStore = AsyncLocalStorage.prototype.getStore
|
|
58
58
|
const superEnterWith = AsyncLocalStorage.prototype.enterWith
|
|
59
|
+
// @ts-expect-error Node calls this undocumented AsyncLocalStorage hook.
|
|
60
|
+
const superPropagate = AsyncLocalStorage.prototype._propagate
|
|
59
61
|
|
|
60
62
|
// Without ACF, ALS writes the entered value onto the async resource. Keep the
|
|
61
63
|
// real store off the resource by entering a small handle and mapping it to
|
|
62
64
|
// the store through a WeakMap, then reversing the lookup on read.
|
|
63
65
|
const stores = new WeakMap()
|
|
64
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Node can omit the trigger resource while the inspector is paused. Guard
|
|
69
|
+
* the shared hook because every enabled AsyncLocalStorage receives the call.
|
|
70
|
+
*
|
|
71
|
+
* @param {object} resource
|
|
72
|
+
* @param {object | undefined} triggerResource
|
|
73
|
+
* @param {string} type
|
|
74
|
+
*/
|
|
75
|
+
AsyncLocalStorage.prototype._propagate = function _propagate (resource, triggerResource, type) {
|
|
76
|
+
if (triggerResource) {
|
|
77
|
+
superPropagate.call(this, resource, triggerResource, type)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
65
81
|
/**
|
|
66
82
|
* @param {Store<unknown>} [store]
|
|
67
83
|
*/
|
|
@@ -8,6 +8,7 @@ const { pathToFileURL, fileURLToPath } = require('node:url')
|
|
|
8
8
|
const instrumentations = require('../datadog-instrumentations/src/helpers/instrumentations')
|
|
9
9
|
const extractPackageAndModulePath = require('../datadog-instrumentations/src/helpers/extract-package-and-module-path')
|
|
10
10
|
const hooks = require('../datadog-instrumentations/src/helpers/hooks')
|
|
11
|
+
const { getValueFromEnvSources } = require('../dd-trace/src/config/helper')
|
|
11
12
|
const log = require('./src/log')
|
|
12
13
|
const { createEsmResolver } = require('./src/resolver')
|
|
13
14
|
const { isESMFile, processModule } = require('./src/utils')
|
|
@@ -60,6 +61,7 @@ for (const builtin of builtinModules) {
|
|
|
60
61
|
|
|
61
62
|
// eslint-disable-next-line eslint-rules/eslint-process-env
|
|
62
63
|
const DD_IAST_ENABLED = process.env.DD_IAST_ENABLED?.toLowerCase() === 'true' || process.env.DD_IAST_ENABLED === '1'
|
|
64
|
+
const DD_BUNDLER_INJECT_GIT_METADATA = getValueFromEnvSources('DD_BUNDLER_INJECT_GIT_METADATA') !== false
|
|
63
65
|
|
|
64
66
|
module.exports.name = 'datadog-esbuild'
|
|
65
67
|
|
|
@@ -143,26 +145,30 @@ globalThis.__dirname ??= $dd_dirname(globalThis.__filename);
|
|
|
143
145
|
${build.initialOptions.banner.js}`
|
|
144
146
|
}
|
|
145
147
|
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
// Bake DD_GIT_* into the banner unless DD_BUNDLER_INJECT_GIT_METADATA=false (stable artifact hashes).
|
|
149
|
+
if (DD_BUNDLER_INJECT_GIT_METADATA) {
|
|
150
|
+
const gitMetadata = getGitMetadata()
|
|
151
|
+
if (gitMetadata.repositoryURL || gitMetadata.commitSHA) {
|
|
152
|
+
build.initialOptions.banner ??= {}
|
|
153
|
+
build.initialOptions.banner.js ??= ''
|
|
151
154
|
|
|
152
|
-
|
|
155
|
+
build.initialOptions.banner.js = `if (typeof process === 'object' && process !== null &&
|
|
153
156
|
process.env !== null && typeof process.env === 'object') {
|
|
154
157
|
${gitMetadata.repositoryURL ? `process.env.DD_GIT_REPOSITORY_URL = '${gitMetadata.repositoryURL}';` : ''}
|
|
155
158
|
${gitMetadata.commitSHA ? `process.env.DD_GIT_COMMIT_SHA = '${gitMetadata.commitSHA}';` : ''}
|
|
156
159
|
}
|
|
157
160
|
${build.initialOptions.banner.js}`
|
|
158
161
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
log.debug(
|
|
163
|
+
'Automatically injected git metadata (DD_GIT_REPOSITORY_URL: %s, DD_GIT_COMMIT_SHA: %s)',
|
|
164
|
+
gitMetadata.repositoryURL || 'not available',
|
|
165
|
+
gitMetadata.commitSHA || 'not available'
|
|
166
|
+
)
|
|
167
|
+
} else {
|
|
168
|
+
log.warn('No git metadata available - skipping injection')
|
|
169
|
+
}
|
|
164
170
|
} else {
|
|
165
|
-
log.
|
|
171
|
+
log.debug('Skipping git metadata injection (DD_BUNDLER_INJECT_GIT_METADATA=false)')
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
let resolver
|
|
@@ -42,9 +42,9 @@ function wrapExecuteWithCallback (executeWithCallback) {
|
|
|
42
42
|
function wrapProcess (process) {
|
|
43
43
|
return function (...args) {
|
|
44
44
|
const cb = args[0]
|
|
45
|
-
if (!ch.start.hasSubscribers || typeof cb !== 'function'
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
if (!ch.start.hasSubscribers || typeof cb !== 'function' || this[kTracingCallbackCommand]) {
|
|
46
|
+
return process.apply(this, args)
|
|
47
|
+
}
|
|
48
48
|
|
|
49
49
|
const ctx = getContext(this)
|
|
50
50
|
|
|
@@ -228,11 +228,11 @@ for (const hook of getHooks('ai').values()) {
|
|
|
228
228
|
|
|
229
229
|
// The SDK builds a model from a string id, in which case only the resolved instance is
|
|
230
230
|
// worth wrapping; when the caller passed an instance, that is the one the SDK calls.
|
|
231
|
-
if (typeof model
|
|
231
|
+
if (typeof model === 'string' || model === ctx.result) {
|
|
232
|
+
wrapModel(ctx.result)
|
|
233
|
+
} else {
|
|
232
234
|
wrapModel(model)
|
|
233
235
|
wrappedModels.add(ctx.result)
|
|
234
|
-
} else {
|
|
235
|
-
wrapModel(ctx.result)
|
|
236
236
|
}
|
|
237
237
|
},
|
|
238
238
|
})
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const { channel, tracingChannel } = require('dc-polyfill')
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
|
-
const { addHook, getHooks } = require('./helpers/instrument')
|
|
6
5
|
const LAZY_DURABLE_PROMISE_METHODS = require('./aws-durable-execution-sdk-js-context-methods')
|
|
7
6
|
|
|
8
7
|
for (const method of LAZY_DURABLE_PROMISE_METHODS) {
|
|
@@ -102,8 +101,3 @@ function observeDurablePromise (dp, onSettle) {
|
|
|
102
101
|
instrumentDurablePromiseProto(Object.getPrototypeOf(dp))
|
|
103
102
|
dp[ON_SETTLE] = onSettle
|
|
104
103
|
}
|
|
105
|
-
|
|
106
|
-
for (const hook of getHooks('@aws/durable-execution-sdk-js').values()) {
|
|
107
|
-
hook.file = null
|
|
108
|
-
addHook(hook, exports => exports)
|
|
109
|
-
}
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
4
|
const { channel, addHook } = require('./helpers/instrument')
|
|
5
|
+
const sendSonic = require('./nova-sonic')
|
|
5
6
|
|
|
6
7
|
const patchedClientConfigProtocols = new WeakSet()
|
|
7
8
|
const patchedCommandPrototypes = new WeakSet()
|
|
9
|
+
const patchedSmithyClients = new WeakSet()
|
|
8
10
|
|
|
9
11
|
// Resource identifiers that already match the channel-suffix slug. Anything
|
|
10
|
-
// else falls back to `'
|
|
12
|
+
// else falls back to `'aws'`. Hoisted out of the per-call hot path so we
|
|
11
13
|
// don't allocate a fresh Array literal + run `.includes` on every AWS send.
|
|
12
14
|
const KNOWN_CHANNEL_SUFFIXES = new Set([
|
|
13
15
|
'cloudwatchlogs',
|
|
@@ -161,6 +163,9 @@ function wrapSmithySend (send) {
|
|
|
161
163
|
const channels = getChannelBag(channelSuffix)
|
|
162
164
|
const clientName = getClientName(this.constructor)
|
|
163
165
|
const operation = getOperationName(command.constructor)
|
|
166
|
+
if (channelSuffix === 'bedrockruntime' && operation === 'invokeModelWithBidirectionalStream') {
|
|
167
|
+
return sendSonic(send, this, command, args)
|
|
168
|
+
}
|
|
164
169
|
const request = {
|
|
165
170
|
operation,
|
|
166
171
|
params: command.input,
|
|
@@ -320,18 +325,24 @@ function getChannelSuffix (name) {
|
|
|
320
325
|
// some resource identifiers have spaces between ex: bedrock runtime
|
|
321
326
|
name = String(name).replaceAll(' ', '')
|
|
322
327
|
if (KNOWN_CHANNEL_SUFFIXES.has(name)) return name
|
|
323
|
-
return CHANNEL_SUFFIX_ALIASES.get(name) ?? '
|
|
328
|
+
return CHANNEL_SUFFIX_ALIASES.get(name) ?? 'aws'
|
|
324
329
|
}
|
|
325
330
|
|
|
326
|
-
|
|
327
|
-
|
|
331
|
+
/** @param {{ Client: Function }} smithy */
|
|
332
|
+
function patchSmithyClient (smithy) {
|
|
333
|
+
const prototype = smithy.Client.prototype
|
|
334
|
+
// Recent smithy-client releases re-export core/client. Loading both entry points must not
|
|
335
|
+
// install two observers on the same send (and consume/charge every duplex event twice).
|
|
336
|
+
if (!patchedSmithyClients.has(prototype)) {
|
|
337
|
+
shimmer.wrap(prototype, 'send', wrapSmithySend)
|
|
338
|
+
patchedSmithyClients.add(prototype)
|
|
339
|
+
}
|
|
328
340
|
return smithy
|
|
329
|
-
}
|
|
341
|
+
}
|
|
330
342
|
|
|
331
|
-
addHook({ name: '@
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
})
|
|
343
|
+
addHook({ name: '@smithy/smithy-client', versions: ['>=1.0.3'] }, patchSmithyClient)
|
|
344
|
+
|
|
345
|
+
addHook({ name: '@aws-sdk/smithy-client', versions: ['>=3'] }, patchSmithyClient)
|
|
335
346
|
|
|
336
347
|
// `@aws-sdk/client-*` >= 3.1046.0 dropped `@smithy/smithy-client` and now
|
|
337
348
|
// extends from `@smithy/core/client` directly. The `Client.send` contract is
|
|
@@ -341,10 +352,7 @@ addHook({
|
|
|
341
352
|
name: '@smithy/core',
|
|
342
353
|
file: 'dist-cjs/submodules/client/index.js',
|
|
343
354
|
versions: ['>=3.24.0'],
|
|
344
|
-
},
|
|
345
|
-
shimmer.wrap(smithyCoreClient.Client.prototype, 'send', wrapSmithySend)
|
|
346
|
-
return smithyCoreClient
|
|
347
|
-
})
|
|
355
|
+
}, patchSmithyClient)
|
|
348
356
|
|
|
349
357
|
addHook({ name: 'aws-sdk', versions: ['>=2.3.0'] }, AWS => {
|
|
350
358
|
shimmer.wrap(AWS.config, 'setPromisesDependency', setPromisesDependency => {
|
|
@@ -11,6 +11,7 @@ const finishCh = channel('apm:cassandra-driver:query:finish')
|
|
|
11
11
|
const errorCh = channel('apm:cassandra-driver:query:error')
|
|
12
12
|
const connectCh = channel('apm:cassandra-driver:query:connect')
|
|
13
13
|
|
|
14
|
+
/** @type {Record<string, unknown> & { error?: Error }} */
|
|
14
15
|
let startCtx = {}
|
|
15
16
|
|
|
16
17
|
addHook({ name: 'cassandra-driver', versions: ['>=3.0.0'] }, cassandra => {
|
|
@@ -24,23 +25,23 @@ addHook({ name: 'cassandra-driver', versions: ['>=3.0.0'] }, cassandra => {
|
|
|
24
25
|
startCtx = { keyspace: this.keyspace, query: queries, contactPoints: this.options && this.options.contactPoints }
|
|
25
26
|
return startCh.runStores(startCtx, () => {
|
|
26
27
|
if (typeof cb === 'function') {
|
|
27
|
-
arguments[lastIndex] = wrapCallback(
|
|
28
|
+
arguments[lastIndex] = wrapCallback(startCtx, cb)
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
try {
|
|
31
32
|
const res = batch.apply(this, arguments)
|
|
32
33
|
if (typeof res === 'function') {
|
|
33
|
-
return wrapCallback(
|
|
34
|
+
return wrapCallback(startCtx, res)
|
|
34
35
|
}
|
|
35
36
|
if (!res) {
|
|
36
37
|
return res
|
|
37
38
|
}
|
|
38
39
|
return res.then(
|
|
39
|
-
() => finish(
|
|
40
|
-
err => finish(
|
|
40
|
+
() => finish(startCtx),
|
|
41
|
+
err => finish(startCtx, err)
|
|
41
42
|
)
|
|
42
43
|
} catch (e) {
|
|
43
|
-
finish(
|
|
44
|
+
finish(startCtx, e)
|
|
44
45
|
throw e
|
|
45
46
|
}
|
|
46
47
|
})
|
|
@@ -58,8 +59,8 @@ addHook({ name: 'cassandra-driver', versions: ['>=4.4'], patchDefault: false },
|
|
|
58
59
|
const promise = _execute.apply(this, arguments)
|
|
59
60
|
|
|
60
61
|
promise.then(
|
|
61
|
-
() => finish(
|
|
62
|
-
err => finish(
|
|
62
|
+
() => finish(startCtx),
|
|
63
|
+
err => finish(startCtx, err)
|
|
63
64
|
)
|
|
64
65
|
return promise
|
|
65
66
|
})
|
|
@@ -74,10 +75,7 @@ const isValid = (args) => {
|
|
|
74
75
|
addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'], patchDefault: false }, (cassandra) => {
|
|
75
76
|
shimmer.wrap(cassandra.Client.prototype, '_innerExecute', _innerExecute =>
|
|
76
77
|
function (query, params, execOptions, callback) {
|
|
77
|
-
if (!startCh.hasSubscribers) {
|
|
78
|
-
return _innerExecute.apply(this, arguments)
|
|
79
|
-
}
|
|
80
|
-
if (!isValid(arguments)) {
|
|
78
|
+
if (!startCh.hasSubscribers || !isValid(arguments)) {
|
|
81
79
|
return _innerExecute.apply(this, arguments)
|
|
82
80
|
}
|
|
83
81
|
|
|
@@ -87,13 +85,13 @@ addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'], patchDefault: false }
|
|
|
87
85
|
const cb = arguments[lastIndex]
|
|
88
86
|
|
|
89
87
|
if (typeof cb === 'function') {
|
|
90
|
-
arguments[lastIndex] = wrapCallback(
|
|
88
|
+
arguments[lastIndex] = wrapCallback(startCtx, cb)
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
try {
|
|
94
92
|
return _innerExecute.apply(this, arguments)
|
|
95
93
|
} catch (e) {
|
|
96
|
-
finish(
|
|
94
|
+
finish(startCtx, e)
|
|
97
95
|
throw e
|
|
98
96
|
}
|
|
99
97
|
})
|
|
@@ -156,7 +154,11 @@ addHook({ name: 'cassandra-driver', versions: ['3 - 3.2'], file: 'lib/request-ha
|
|
|
156
154
|
return RequestHandler
|
|
157
155
|
})
|
|
158
156
|
|
|
159
|
-
|
|
157
|
+
/**
|
|
158
|
+
* @param {Record<string, unknown> & { error?: Error }} ctx
|
|
159
|
+
* @param {Error} [error]
|
|
160
|
+
*/
|
|
161
|
+
function finish (ctx, error) {
|
|
160
162
|
if (error) {
|
|
161
163
|
ctx.error = error
|
|
162
164
|
errorCh.publish(ctx)
|
|
@@ -164,19 +166,22 @@ function finish (finishCh, errorCh, ctx, error) {
|
|
|
164
166
|
finishCh.runStores(ctx, () => {})
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
|
|
169
|
+
/**
|
|
170
|
+
* @param {Record<string, unknown> & { error?: Error }} ctx
|
|
171
|
+
* @param {Parameters<typeof finishCh.runStores>[1]} callback
|
|
172
|
+
*/
|
|
173
|
+
function wrapCallback (ctx, callback) {
|
|
168
174
|
return shimmer.wrapCallback(callback, callback => function (err) {
|
|
169
175
|
if (err) {
|
|
170
176
|
ctx.error = err
|
|
171
177
|
errorCh.publish(ctx)
|
|
172
178
|
}
|
|
173
|
-
return finishCh.runStores(
|
|
179
|
+
return finishCh.runStores(
|
|
180
|
+
ctx, /** @type {Parameters<typeof finishCh.runStores>[1]} */ (callback), this, ...arguments
|
|
181
|
+
)
|
|
174
182
|
})
|
|
175
183
|
}
|
|
176
184
|
|
|
177
185
|
function isRequestValid (exec, args, length) {
|
|
178
|
-
|
|
179
|
-
if (args.length !== length || typeof args[length - 1] !== 'function') return false
|
|
180
|
-
|
|
181
|
-
return true
|
|
186
|
+
return !!exec && args.length === length && typeof args[length - 1] === 'function'
|
|
182
187
|
}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const { tracingChannel } = require('dc-polyfill')
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
|
-
const { addHook, getHooks } = require('./helpers/instrument')
|
|
6
5
|
const queryChannel = tracingChannel('orchestrion:@anthropic-ai/claude-agent-sdk:query')
|
|
7
6
|
|
|
8
7
|
const stepCh = tracingChannel('apm:claude-agent-sdk:step')
|
|
@@ -638,28 +637,15 @@ function wrapQueryAsyncIterator (asyncIterator, ctx) {
|
|
|
638
637
|
}
|
|
639
638
|
}
|
|
640
639
|
|
|
641
|
-
|
|
640
|
+
queryChannel.subscribe({
|
|
641
|
+
start: onQueryStart,
|
|
642
|
+
end (ctx) {
|
|
643
|
+
if (!ctx.claudeAgentSdkTracing) return
|
|
642
644
|
|
|
643
|
-
|
|
644
|
-
hook.file = null
|
|
645
|
+
const { result } = ctx
|
|
645
646
|
|
|
646
|
-
|
|
647
|
-
if (!querySubscribed) {
|
|
648
|
-
querySubscribed = true
|
|
649
|
-
queryChannel.subscribe({
|
|
650
|
-
start: onQueryStart,
|
|
651
|
-
end (ctx) {
|
|
652
|
-
if (!ctx.claudeAgentSdkTracing) return
|
|
647
|
+
ctx.streamResolved = false
|
|
653
648
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
shimmer.wrap(result, Symbol.asyncIterator, asyncIterator => wrapQueryAsyncIterator(asyncIterator, ctx))
|
|
659
|
-
},
|
|
660
|
-
})
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
return exports
|
|
664
|
-
})
|
|
665
|
-
}
|
|
649
|
+
shimmer.wrap(result, Symbol.asyncIterator, asyncIterator => wrapQueryAsyncIterator(asyncIterator, ctx))
|
|
650
|
+
},
|
|
651
|
+
})
|
|
@@ -102,7 +102,7 @@ const efdRetryCountByPickleId = new Map()
|
|
|
102
102
|
const efdSlowAbortedPickleIds = new Set()
|
|
103
103
|
const finishedParallelSuites = new Set()
|
|
104
104
|
const numAttemptToCtx = new Map()
|
|
105
|
-
const
|
|
105
|
+
const efdStatusesByPickleId = new Map()
|
|
106
106
|
const attemptToFixTestsByTestFullname = new Map()
|
|
107
107
|
const modifiedTestsByPickleId = new Map()
|
|
108
108
|
const runnerToRetryState = new WeakMap()
|
|
@@ -200,13 +200,13 @@ function getSuiteStatusFromTestStatuses (testStatuses) {
|
|
|
200
200
|
return 'pass'
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
function publishWorkerEfdRetryCount (pickle, retryCount) {
|
|
203
|
+
function publishWorkerEfdRetryCount (pickle, retryCount, isModified) {
|
|
204
204
|
const message = {
|
|
205
205
|
[DD_EFD_RETRY_COUNT_MESSAGE]: {
|
|
206
206
|
pickleId: pickle.id,
|
|
207
207
|
retryCount,
|
|
208
|
+
isModified,
|
|
208
209
|
testFileAbsolutePath: pickle.uri,
|
|
209
|
-
testName: pickle.name,
|
|
210
210
|
},
|
|
211
211
|
}
|
|
212
212
|
|
|
@@ -220,10 +220,12 @@ function publishWorkerEfdRetryCount (pickle, retryCount) {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
try {
|
|
223
|
-
const { isMainThread, parentPort } = require('node:worker_threads')
|
|
223
|
+
const { isMainThread, parentPort, workerData } = require('node:worker_threads')
|
|
224
224
|
if (isMainThread || !parentPort) return
|
|
225
225
|
|
|
226
|
-
|
|
226
|
+
// Share Cucumber's envelope port so EFD metadata arrives before test results.
|
|
227
|
+
const port = workerData?.port ?? parentPort
|
|
228
|
+
port.postMessage(message)
|
|
227
229
|
} catch {
|
|
228
230
|
// ignore IPC errors
|
|
229
231
|
}
|
|
@@ -385,14 +387,16 @@ function handleParallelTestCaseFinished (pickle, worstTestStepResult, usesNumeri
|
|
|
385
387
|
const testFileAbsolutePath = pickle.uri
|
|
386
388
|
const finished = (pickleResultByFile[testFileAbsolutePath] ||= [])
|
|
387
389
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
390
|
+
const isAttemptToFix = isTestManagementTestsEnabled &&
|
|
391
|
+
getTestProperties(getTestSuitePath(testFileAbsolutePath, process.cwd()), pickle.name).attemptToFix
|
|
392
|
+
|
|
393
|
+
if (!isAttemptToFix && shouldRunEarlyFlakeDetection() && (isNew || modifiedTestsByPickleId.get(pickle.id))) {
|
|
394
|
+
let testStatuses = efdStatusesByPickleId.get(pickle.id)
|
|
391
395
|
if (testStatuses) {
|
|
392
396
|
testStatuses.push(status)
|
|
393
397
|
} else {
|
|
394
398
|
testStatuses = [status]
|
|
395
|
-
|
|
399
|
+
efdStatusesByPickleId.set(pickle.id, testStatuses)
|
|
396
400
|
}
|
|
397
401
|
let efdRetryCount = efdRetryCountByPickleId.get(pickle.id)
|
|
398
402
|
if (efdRetryCount === undefined) {
|
|
@@ -404,11 +408,8 @@ function handleParallelTestCaseFinished (pickle, worstTestStepResult, usesNumeri
|
|
|
404
408
|
efdSlowAbortedPickleIds.add(pickle.id)
|
|
405
409
|
}
|
|
406
410
|
}
|
|
407
|
-
maybeRecordFinalParallelEfdStatus({ pickleId: pickle.id, testFileAbsolutePath
|
|
408
|
-
} else if (
|
|
409
|
-
isTestManagementTestsEnabled &&
|
|
410
|
-
getTestProperties(getTestSuitePath(testFileAbsolutePath, process.cwd()), pickle.name).attemptToFix
|
|
411
|
-
) {
|
|
411
|
+
maybeRecordFinalParallelEfdStatus({ pickleId: pickle.id, testFileAbsolutePath })
|
|
412
|
+
} else if (isAttemptToFix) {
|
|
412
413
|
const testFullname = `${pickle.uri}:${pickle.name}`
|
|
413
414
|
let testStatuses = attemptToFixTestsByTestFullname.get(testFullname)
|
|
414
415
|
if (testStatuses) {
|
|
@@ -495,8 +496,14 @@ function finishParallelSuiteIfDone (testFileAbsolutePath) {
|
|
|
495
496
|
const finished = pickleResultByFile[testFileAbsolutePath]
|
|
496
497
|
const expectedPickles = pickleByFile[testFileAbsolutePath]
|
|
497
498
|
|
|
498
|
-
if (
|
|
499
|
-
|
|
499
|
+
if (
|
|
500
|
+
!finished ||
|
|
501
|
+
!expectedPickles ||
|
|
502
|
+
finished.length !== expectedPickles.length ||
|
|
503
|
+
finishedParallelSuites.has(testFileAbsolutePath)
|
|
504
|
+
) {
|
|
505
|
+
return
|
|
506
|
+
}
|
|
500
507
|
|
|
501
508
|
finishedParallelSuites.add(testFileAbsolutePath)
|
|
502
509
|
testSuiteFinishCh.publish({
|
|
@@ -505,29 +512,30 @@ function finishParallelSuiteIfDone (testFileAbsolutePath) {
|
|
|
505
512
|
})
|
|
506
513
|
}
|
|
507
514
|
|
|
508
|
-
function maybeRecordFinalParallelEfdStatus ({ pickleId, testFileAbsolutePath
|
|
515
|
+
function maybeRecordFinalParallelEfdStatus ({ pickleId, testFileAbsolutePath }) {
|
|
509
516
|
const efdRetryCount = efdRetryCountByPickleId.get(pickleId)
|
|
510
|
-
const testStatuses =
|
|
517
|
+
const testStatuses = efdStatusesByPickleId.get(pickleId)
|
|
511
518
|
const finished = pickleResultByFile[testFileAbsolutePath]
|
|
512
519
|
|
|
513
|
-
if (efdRetryCount === undefined || !testStatuses || !finished) return
|
|
514
|
-
if (testStatuses.length !== efdRetryCount + 1) return
|
|
520
|
+
if (efdRetryCount === undefined || !testStatuses || !finished || testStatuses.length !== efdRetryCount + 1) return
|
|
515
521
|
|
|
516
|
-
finished.push(getTestStatusFromRetries(testStatuses))
|
|
517
|
-
|
|
522
|
+
finished.push(efdRetryCount === 0 ? testStatuses[0] : getTestStatusFromRetries(testStatuses))
|
|
523
|
+
efdStatusesByPickleId.delete(pickleId)
|
|
518
524
|
finishParallelSuiteIfDone(testFileAbsolutePath)
|
|
519
525
|
}
|
|
520
526
|
|
|
521
527
|
function handleEfdRetryCountMessage (message) {
|
|
522
|
-
const { pickleId, retryCount,
|
|
528
|
+
const { pickleId, retryCount, isModified, testFileAbsolutePath } = message
|
|
523
529
|
|
|
524
|
-
if (!pickleId ||
|
|
530
|
+
if (!pickleId || !testFileAbsolutePath) return
|
|
531
|
+
|
|
532
|
+
if (isModified) modifiedTestsByPickleId.set(pickleId, true)
|
|
533
|
+
if (typeof retryCount !== 'number') return
|
|
525
534
|
|
|
526
535
|
efdRetryCountByPickleId.set(pickleId, retryCount)
|
|
527
536
|
maybeRecordFinalParallelEfdStatus({
|
|
528
537
|
pickleId,
|
|
529
538
|
testFileAbsolutePath,
|
|
530
|
-
testFullname: `${testFileAbsolutePath}:${testName}`,
|
|
531
539
|
})
|
|
532
540
|
}
|
|
533
541
|
|
|
@@ -912,12 +920,13 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
912
920
|
isNew = newTestPickleIds.has(this.pickle.id)
|
|
913
921
|
}
|
|
914
922
|
|
|
915
|
-
if (isNew || isModified) {
|
|
923
|
+
if (!isAttemptToFix && (isNew || isModified)) {
|
|
916
924
|
isEfdRetry = numRetries > 0
|
|
917
925
|
}
|
|
918
926
|
|
|
919
927
|
if (
|
|
920
928
|
shouldRunEarlyFlakeDetection() &&
|
|
929
|
+
!isAttemptToFix &&
|
|
921
930
|
status !== 'skip' &&
|
|
922
931
|
(isNew || isModified) &&
|
|
923
932
|
!isEfdRetry &&
|
|
@@ -1265,7 +1274,8 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1265
1274
|
efdRetryCountByPickleId.clear()
|
|
1266
1275
|
efdSlowAbortedPickleIds.clear()
|
|
1267
1276
|
finishedParallelSuites.clear()
|
|
1268
|
-
|
|
1277
|
+
efdStatusesByPickleId.clear()
|
|
1278
|
+
modifiedTestsByPickleId.clear()
|
|
1269
1279
|
sessionStartCh.publish({ command, frameworkVersion })
|
|
1270
1280
|
|
|
1271
1281
|
if (!errorSkippableRequest && skippedSuites.length) {
|
|
@@ -1478,10 +1488,15 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1478
1488
|
}
|
|
1479
1489
|
}
|
|
1480
1490
|
const originalRetry = this.options.retry
|
|
1481
|
-
const
|
|
1491
|
+
const isEfdTest = !isAttemptToFix && shouldRunEarlyFlakeDetection() && (isNew || isModified)
|
|
1492
|
+
const isManagedRetry = isAttemptToFix || isEfdTest
|
|
1482
1493
|
if (isManagedRetry) {
|
|
1483
1494
|
this.options.retry = 0
|
|
1484
1495
|
}
|
|
1496
|
+
if (isWorker && isModified && isEfdTest) {
|
|
1497
|
+
// The coordinator must recognize modified EFD tests before their first result arrives.
|
|
1498
|
+
publishWorkerEfdRetryCount(pickle, undefined, true)
|
|
1499
|
+
}
|
|
1485
1500
|
// TODO: for >=11 we could use `runTestCaseResult` instead of accumulating results in `lastStatusByPickleId`
|
|
1486
1501
|
const firstExecutionStart = performance.now()
|
|
1487
1502
|
let runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
|
|
@@ -1493,7 +1508,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1493
1508
|
const testStatuses = lastStatusByPickleId.get(pickle.id)
|
|
1494
1509
|
const lastTestStatus = testStatuses.at(-1)
|
|
1495
1510
|
|
|
1496
|
-
//
|
|
1511
|
+
// Attempt to Fix owns retries for managed tests, including modified tests.
|
|
1497
1512
|
if (isAttemptToFix && lastTestStatus !== 'skip') {
|
|
1498
1513
|
for (let retryIndex = 0; retryIndex < testManagementAttemptToFixRetries; retryIndex++) {
|
|
1499
1514
|
numRetriesByPickleId.set(pickle.id, retryIndex + 1)
|
|
@@ -1502,8 +1517,8 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1502
1517
|
}
|
|
1503
1518
|
}
|
|
1504
1519
|
|
|
1505
|
-
//
|
|
1506
|
-
if (
|
|
1520
|
+
// Retry eligible new or modified tests unless their first attempt was skipped.
|
|
1521
|
+
if (isEfdTest && lastTestStatus !== 'skip') {
|
|
1507
1522
|
let efdRetryCount = efdRetryCountByPickleId.get(pickle.id)
|
|
1508
1523
|
if (efdRetryCount === undefined) {
|
|
1509
1524
|
efdRetryCount = getEfdRetryCountForDuration(firstExecutionDurationMs, earlyFlakeDetectionRetryPolicy)
|
|
@@ -1525,7 +1540,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1525
1540
|
let shouldBePassedByEFD = false
|
|
1526
1541
|
let shouldBePassedByTestManagement = false
|
|
1527
1542
|
let shouldBeFailedByAttemptToFix = false
|
|
1528
|
-
if (
|
|
1543
|
+
if (isEfdTest) {
|
|
1529
1544
|
/**
|
|
1530
1545
|
* If Early Flake Detection (EFD) is enabled the logic is as follows:
|
|
1531
1546
|
* - If all attempts for a test are failing, the test has failed and we will let the test process fail.
|
|
@@ -1587,7 +1602,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1587
1602
|
return shouldBePassedByTestManagement
|
|
1588
1603
|
}
|
|
1589
1604
|
|
|
1590
|
-
if (isNewerCucumberVersion &&
|
|
1605
|
+
if (isNewerCucumberVersion && isEfdTest) {
|
|
1591
1606
|
return shouldBePassedByEFD
|
|
1592
1607
|
}
|
|
1593
1608
|
|