dd-trace 6.7.0 → 6.9.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 +27 -25
- package/ci/init.js +6 -6
- package/ci/runbook.md +114 -20
- package/ci/test-optimization-validation/approval-artifacts.js +36 -3
- package/ci/test-optimization-validation/approval.js +78 -22
- package/ci/test-optimization-validation/blocker-category.js +24 -0
- package/ci/test-optimization-validation/ci-discovery.js +23 -17
- package/ci/test-optimization-validation/ci-package-scripts.js +34 -6
- package/ci/test-optimization-validation/ci-remediation.js +1 -1
- package/ci/test-optimization-validation/cli.js +280 -52
- package/ci/test-optimization-validation/command-blocker.js +159 -20
- package/ci/test-optimization-validation/command-output-policy.js +14 -8
- package/ci/test-optimization-validation/command-runner.js +9 -7
- package/ci/test-optimization-validation/environment.js +4 -2
- package/ci/test-optimization-validation/executable.js +15 -13
- package/ci/test-optimization-validation/execution-lock.js +70 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber-validation.json +3 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +657 -5
- package/ci/test-optimization-validation/framework-adapters/playwright.js +5 -5
- package/ci/test-optimization-validation/framework-adapters/vitest.js +517 -0
- package/ci/test-optimization-validation/generated-files.js +47 -37
- package/ci/test-optimization-validation/generated-test-contract.js +9 -7
- package/ci/test-optimization-validation/generated-verifier.js +24 -17
- package/ci/test-optimization-validation/literal-glob.js +52 -0
- package/ci/test-optimization-validation/manifest-loader.js +3 -0
- package/ci/test-optimization-validation/manifest-scaffold.js +301 -52
- package/ci/test-optimization-validation/manifest-schema.js +80 -17
- package/ci/test-optimization-validation/offline-fixtures.js +13 -4
- package/ci/test-optimization-validation/offline-output.js +6 -6
- package/ci/test-optimization-validation/package-check.js +94 -0
- package/ci/test-optimization-validation/plan-writer.js +183 -10
- package/ci/test-optimization-validation/preflight-runner.js +110 -31
- package/ci/test-optimization-validation/project-build-artifact.js +31 -0
- package/ci/test-optimization-validation/redaction.js +18 -27
- package/ci/test-optimization-validation/report-writer.js +182 -48
- package/ci/test-optimization-validation/result-semantics.js +20 -3
- package/ci/test-optimization-validation/runner-command.js +41 -21
- package/ci/test-optimization-validation/runner-contract.js +79 -43
- package/ci/test-optimization-validation/safe-files.js +4 -4
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +60 -6
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +141 -35
- package/ci/test-optimization-validation/scenarios/helpers.js +30 -6
- package/ci/test-optimization-validation/scenarios/test-management.js +2 -2
- package/ci/test-optimization-validation/static-diagnosis.js +10 -3
- package/ci/test-optimization-validation/test-output.js +2 -1
- package/ci/test-optimization-validation/validation-blocker.js +21 -0
- package/ci/vitest-no-worker-init-setup.mjs +377 -84
- package/index.d.ts +175 -14
- package/init.js +1 -17
- package/initialize.mjs +11 -0
- package/loader-hook.mjs +6 -4
- package/package.json +12 -4
- package/packages/datadog-core/src/utils/src/kebabcase.js +8 -2
- package/packages/datadog-core/src/utils/src/parse-tags.js +0 -1
- package/packages/datadog-esbuild/index.js +4 -2
- package/packages/datadog-esbuild/src/utils.js +17 -2
- package/packages/datadog-instrumentations/src/ai.js +61 -34
- package/packages/datadog-instrumentations/src/bluebird.js +6 -6
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +85 -9
- package/packages/datadog-instrumentations/src/cucumber.js +131 -51
- package/packages/datadog-instrumentations/src/dns.js +21 -2
- package/packages/datadog-instrumentations/src/electron.js +1 -0
- package/packages/datadog-instrumentations/src/fastify.js +3 -1
- package/packages/datadog-instrumentations/src/grpc/client.js +4 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +3 -1
- package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +10 -0
- package/packages/datadog-instrumentations/src/helpers/hook.js +19 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +9 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +34 -9
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +175 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +20 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +32 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +61 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +50 -18
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +38 -7
- package/packages/datadog-instrumentations/src/helpers/shared-utils.js +39 -0
- package/packages/datadog-instrumentations/src/http/client.js +1 -3
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +986 -246
- package/packages/datadog-instrumentations/src/mocha/common.js +1 -3
- package/packages/datadog-instrumentations/src/mocha/main.js +109 -51
- package/packages/datadog-instrumentations/src/mocha/utils.js +120 -32
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +44 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +441 -43
- package/packages/datadog-instrumentations/src/moleculer/client.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +155 -23
- package/packages/datadog-instrumentations/src/openai.js +14 -0
- package/packages/datadog-instrumentations/src/pg.js +180 -6
- package/packages/datadog-instrumentations/src/playwright.js +176 -81
- package/packages/datadog-instrumentations/src/promise-js.js +4 -4
- package/packages/datadog-instrumentations/src/promise.js +3 -3
- package/packages/datadog-instrumentations/src/rhea.js +1 -1
- package/packages/datadog-instrumentations/src/router.js +195 -19
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +567 -65
- package/packages/datadog-instrumentations/src/vitest-main.js +438 -54
- package/packages/datadog-instrumentations/src/vitest-util.js +42 -7
- package/packages/datadog-instrumentations/src/vitest-worker.js +234 -17
- package/packages/datadog-instrumentations/src/webdriverio.js +1090 -0
- package/packages/datadog-instrumentations/src/when.js +3 -3
- package/packages/datadog-instrumentations/src/ws.js +5 -1
- package/packages/datadog-plugin-aerospike/src/index.js +1 -3
- package/packages/datadog-plugin-amqplib/src/client.js +1 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +59 -48
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +2 -2
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +1 -3
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +5 -3
- package/packages/datadog-plugin-bullmq/src/producer.js +3 -3
- package/packages/datadog-plugin-child_process/src/index.js +3 -3
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -11
- package/packages/datadog-plugin-cucumber/src/index.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +50 -46
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -1
- package/packages/datadog-plugin-cypress/src/support.js +7 -4
- package/packages/datadog-plugin-electron/src/net.js +10 -4
- package/packages/datadog-plugin-fastify/src/tracing.js +1 -1
- package/packages/datadog-plugin-fs/src/index.js +0 -4
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +14 -7
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +19 -10
- package/packages/datadog-plugin-graphql/src/execute.js +1 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -1
- package/packages/datadog-plugin-http/src/client.js +3 -2
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +3 -21
- package/packages/datadog-plugin-jest/src/util.js +4 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +2 -1
- package/packages/datadog-plugin-langchain/src/tokens.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +342 -6
- package/packages/datadog-plugin-next/src/index.js +57 -9
- package/packages/datadog-plugin-openai/src/tracing.js +4 -0
- package/packages/datadog-plugin-pg/src/index.js +65 -1
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-prisma/src/index.js +5 -1
- package/packages/datadog-plugin-rhea/src/consumer.js +16 -13
- package/packages/datadog-plugin-rhea/src/producer.js +1 -1
- package/packages/datadog-plugin-undici/src/index.js +2 -1
- package/packages/datadog-plugin-vitest/src/index.js +179 -18
- package/packages/datadog-shimmer/src/shimmer.js +6 -2
- package/packages/datadog-webpack/index.js +2 -2
- package/packages/dd-trace/src/aiguard/sdk.js +3 -0
- package/packages/dd-trace/src/appsec/{blocking.js → blocking/index.js} +26 -6
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -1
- package/packages/dd-trace/src/appsec/handlers/auth.js +62 -0
- package/packages/dd-trace/src/appsec/handlers/http-request.js +215 -0
- package/packages/dd-trace/src/appsec/handlers/http-response.js +78 -0
- package/packages/dd-trace/src/appsec/handlers/http-shared.js +24 -0
- package/packages/dd-trace/src/appsec/handlers/payments.js +104 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-base-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +2 -2
- package/packages/dd-trace/src/appsec/index.js +48 -476
- package/packages/dd-trace/src/appsec/sdk/track_event.js +10 -1
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +1 -1
- package/packages/dd-trace/src/ci-visibility/coverage-report-discovery.js +46 -14
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +89 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +7 -6
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +29 -15
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +19 -1
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +25 -1
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/webdriverio.js +26 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +22 -7
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +9 -14
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -3
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +21 -5
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +2 -2
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +5 -1
- package/packages/dd-trace/src/config/defaults.js +14 -6
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -2
- package/packages/dd-trace/src/config/helper.js +2 -0
- package/packages/dd-trace/src/config/index.js +31 -5
- package/packages/dd-trace/src/config/parsers.js +19 -1
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +13 -6
- package/packages/dd-trace/src/datastreams/encoding.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/log.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +1 -4
- package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +16 -2
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
- package/packages/dd-trace/src/encode/tags-processors.js +2 -2
- package/packages/dd-trace/src/exporters/common/url.js +3 -5
- package/packages/dd-trace/src/exporters/electron/index.js +4 -1
- package/packages/dd-trace/src/external-logger/src/index.js +1 -2
- package/packages/dd-trace/src/flare/index.js +2 -2
- package/packages/dd-trace/src/guardrails/apply-pm2-env.js +16 -0
- package/packages/dd-trace/src/guardrails/log.js +1 -10
- package/packages/dd-trace/src/id.js +1 -1
- package/packages/dd-trace/src/llmobs/constants/tags.js +1 -1
- package/packages/dd-trace/src/llmobs/eval-metric.js +249 -0
- package/packages/dd-trace/src/llmobs/experiments/client.js +4 -2
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +66 -14
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +289 -95
- package/packages/dd-trace/src/llmobs/experiments/index.js +66 -19
- package/packages/dd-trace/src/llmobs/experiments/noop.js +95 -10
- package/packages/dd-trace/src/llmobs/experiments/result.js +13 -2
- package/packages/dd-trace/src/llmobs/experiments/util.js +220 -0
- package/packages/dd-trace/src/llmobs/noop.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +5 -5
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +152 -78
- package/packages/dd-trace/src/llmobs/span_processor.js +9 -7
- package/packages/dd-trace/src/llmobs/tagger.js +1 -2
- package/packages/dd-trace/src/llmobs/telemetry.js +18 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +3 -0
- package/packages/dd-trace/src/llmobs/writers/spans.js +12 -6
- package/packages/dd-trace/src/llmobs/writers/util.js +2 -0
- package/packages/dd-trace/src/log/channels.js +1 -9
- package/packages/dd-trace/src/log/levels.js +12 -0
- package/packages/dd-trace/src/noop/proxy.js +2 -2
- package/packages/dd-trace/src/openfeature/writers/exposures.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/meter.js +8 -4
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +3 -2
- package/packages/dd-trace/src/opentelemetry/span.js +4 -0
- package/packages/dd-trace/src/opentracing/span.js +1 -1
- package/packages/dd-trace/src/opentracing/span_context.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +124 -23
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/tracing.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -6
- package/packages/dd-trace/src/plugins/util/git.js +7 -5
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +3 -3
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/llm.js +2 -2
- package/packages/dd-trace/src/plugins/util/stacktrace.js +3 -0
- package/packages/dd-trace/src/plugins/util/tags.js +2 -0
- package/packages/dd-trace/src/plugins/util/test.js +356 -86
- package/packages/dd-trace/src/plugins/util/url.js +5 -5
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +24 -2
- package/packages/dd-trace/src/priority_sampler.js +6 -3
- package/packages/dd-trace/src/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +2 -2
- package/packages/dd-trace/src/profiling/profilers/poisson.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/shared.js +2 -2
- package/packages/dd-trace/src/proxy.js +1 -0
- package/packages/dd-trace/src/ritm.js +10 -20
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +4 -2
- package/packages/dd-trace/src/sampling_rule.js +4 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +1 -1
- package/packages/dd-trace/src/startup-log.js +3 -0
- package/packages/dd-trace/src/telemetry/logs/index.js +3 -0
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +3 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +1 -1
- package/packages/dd-trace/src/util.js +16 -0
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +12 -12
- package/vendor/dist/pprof-format/index.js +1 -1
- package/vendor/dist/source-map/index.js +1 -1
- package/version.js +10 -8
- /package/packages/dd-trace/src/appsec/{blocked_templates.js → blocking/templates.js} +0 -0
|
@@ -13,6 +13,66 @@ const LOCAL_LIFECYCLE_LOOKAHEAD = 4
|
|
|
13
13
|
|
|
14
14
|
const chunkEmitTimes = new WeakMap()
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {{ session_id?: string } & Record<string, unknown>} Chunk
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {{
|
|
22
|
+
* id: string,
|
|
23
|
+
* name?: string,
|
|
24
|
+
* input?: unknown,
|
|
25
|
+
* output?: unknown,
|
|
26
|
+
* error?: unknown,
|
|
27
|
+
* isInterrupt?: boolean,
|
|
28
|
+
* sessionId?: string,
|
|
29
|
+
* hookStartTime?: number,
|
|
30
|
+
* hookFinishTime?: number,
|
|
31
|
+
* }} ToolState
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {{ taskStartedChunk?: Chunk, toolResultIndex?: number }} ToolLifecycle
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {(startIndex: number, toolUseId: string) => ToolLifecycle} GetLifecycle
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {{
|
|
44
|
+
* tools: Map<string, ToolState>,
|
|
45
|
+
* subagents: Map<string, Record<string, unknown>>,
|
|
46
|
+
* prompt?: string,
|
|
47
|
+
* model?: string,
|
|
48
|
+
* resume?: string,
|
|
49
|
+
* maxTurns?: number,
|
|
50
|
+
* permissionMode?: string,
|
|
51
|
+
* sessionId?: string,
|
|
52
|
+
* source?: string,
|
|
53
|
+
* cwd?: string,
|
|
54
|
+
* transcriptPath?: string,
|
|
55
|
+
* agentType?: string,
|
|
56
|
+
* endReason?: string,
|
|
57
|
+
* stopReason?: string,
|
|
58
|
+
* lastAssistantMessage?: string,
|
|
59
|
+
* }} SessionContext
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @typedef {{
|
|
64
|
+
* stepIndex: number,
|
|
65
|
+
* startTime?: number,
|
|
66
|
+
* finishTime?: number,
|
|
67
|
+
* parentToolUseId?: string,
|
|
68
|
+
* sessionId?: string,
|
|
69
|
+
* chunks?: Chunk[],
|
|
70
|
+
* llmStartIdx?: number,
|
|
71
|
+
* llmEndIdx?: number,
|
|
72
|
+
* toolOutputs?: unknown[],
|
|
73
|
+
* }} StepContext
|
|
74
|
+
*/
|
|
75
|
+
|
|
16
76
|
function hasDownstreamSubscribers () {
|
|
17
77
|
return queryChannel.asyncEnd.hasSubscribers ||
|
|
18
78
|
queryChannel.error.hasSubscribers ||
|
|
@@ -54,7 +114,7 @@ function buildTracerHooks (sessionCtx) {
|
|
|
54
114
|
sessionCtx.cwd = input.cwd
|
|
55
115
|
sessionCtx.transcriptPath = input.transcript_path
|
|
56
116
|
sessionCtx.agentType = input.agent_type
|
|
57
|
-
sessionCtx.permissionMode
|
|
117
|
+
sessionCtx.permissionMode ||= input.permission_mode
|
|
58
118
|
return {}
|
|
59
119
|
}
|
|
60
120
|
|
|
@@ -64,8 +124,8 @@ function buildTracerHooks (sessionCtx) {
|
|
|
64
124
|
}
|
|
65
125
|
|
|
66
126
|
function onUserPromptSubmit (input) {
|
|
67
|
-
sessionCtx.sessionId
|
|
68
|
-
sessionCtx.prompt
|
|
127
|
+
sessionCtx.sessionId ||= input.session_id
|
|
128
|
+
sessionCtx.prompt ||= input.prompt
|
|
69
129
|
return {}
|
|
70
130
|
}
|
|
71
131
|
|
|
@@ -254,7 +314,7 @@ function createStreamLookup (chunks) {
|
|
|
254
314
|
scanLocalLifecycle(chunks, startIndex, toolUseId, localLifecycle)
|
|
255
315
|
if (localLifecycle.toolResultIndex !== undefined) return localLifecycle
|
|
256
316
|
|
|
257
|
-
streamIndex
|
|
317
|
+
streamIndex ||= buildStreamIndex(chunks)
|
|
258
318
|
const indexedLifecycle = streamIndex.get(toolUseId)
|
|
259
319
|
return {
|
|
260
320
|
taskStartedChunk: localLifecycle.taskStartedChunk || indexedLifecycle?.taskStartedChunk,
|
|
@@ -287,10 +347,12 @@ function getToolResultContent (chunk, toolUseId) {
|
|
|
287
347
|
}
|
|
288
348
|
|
|
289
349
|
/**
|
|
290
|
-
*
|
|
291
|
-
* @param {Array<Record<string, unknown>>} chunks
|
|
350
|
+
* @param {Chunk[]} chunks
|
|
292
351
|
* @param {number} startIndex
|
|
293
352
|
* @param {string} toolUseId
|
|
353
|
+
* @param {SessionContext | null | undefined} sessionCtx
|
|
354
|
+
* @param {GetLifecycle} getLifecycle
|
|
355
|
+
* @param {ToolLifecycle} lifecycle
|
|
294
356
|
* @returns {number} index in chunks where the next step should start iteration
|
|
295
357
|
*/
|
|
296
358
|
function processTool (chunks, startIndex, toolUseId, sessionCtx, getLifecycle, lifecycle) {
|
|
@@ -342,9 +404,14 @@ function processTool (chunks, startIndex, toolUseId, sessionCtx, getLifecycle, l
|
|
|
342
404
|
}
|
|
343
405
|
|
|
344
406
|
/**
|
|
345
|
-
*
|
|
346
|
-
* @param {Array<Record<string, unknown>>} chunks
|
|
407
|
+
* @param {Chunk[]} chunks
|
|
347
408
|
* @param {number} startIndex
|
|
409
|
+
* @param {number | undefined} stepStartTime
|
|
410
|
+
* @param {string | null | undefined} parentToolUseId
|
|
411
|
+
* @param {string | undefined} initialPrompt
|
|
412
|
+
* @param {StepContext | null | undefined} stepCtx
|
|
413
|
+
* @param {SessionContext | null | undefined} sessionCtx
|
|
414
|
+
* @param {GetLifecycle} getLifecycle
|
|
348
415
|
* @returns {number} index in chunks where the next step should start iteration
|
|
349
416
|
*/
|
|
350
417
|
function processStep (
|
|
@@ -447,7 +514,16 @@ function processStep (
|
|
|
447
514
|
}
|
|
448
515
|
|
|
449
516
|
/**
|
|
450
|
-
* @param {
|
|
517
|
+
* @param {Chunk[]} chunks
|
|
518
|
+
* @param {{
|
|
519
|
+
* sessionCtx?: SessionContext,
|
|
520
|
+
* session_id?: string,
|
|
521
|
+
* cwd?: string,
|
|
522
|
+
* permissionMode?: string,
|
|
523
|
+
* output?: unknown,
|
|
524
|
+
* arguments?: Array<{ prompt?: string }>,
|
|
525
|
+
* runInContext?: (fn: () => number) => number,
|
|
526
|
+
* }} agentCtx
|
|
451
527
|
*/
|
|
452
528
|
function processChunks (chunks, agentCtx) {
|
|
453
529
|
let chunkIndex = 0
|
|
@@ -6,6 +6,12 @@ const { createCoverageMap } = require('../../../vendor/dist/istanbul-lib-coverag
|
|
|
6
6
|
const shimmer = require('../../datadog-shimmer')
|
|
7
7
|
const log = require('../../dd-trace/src/log')
|
|
8
8
|
const { getEnvironmentVariable } = require('../../dd-trace/src/config/helper')
|
|
9
|
+
const { getSegment } = require('../../dd-trace/src/util')
|
|
10
|
+
const {
|
|
11
|
+
EMPTY_EFD_RETRY_POLICY,
|
|
12
|
+
getEfdRetryCountForDuration,
|
|
13
|
+
hasEfdRetries,
|
|
14
|
+
} = require('../../dd-trace/src/ci-visibility/efd-retry-policy')
|
|
9
15
|
const {
|
|
10
16
|
getCoveredFilesFromCoverage,
|
|
11
17
|
getExecutableFilesFromCoverage,
|
|
@@ -15,15 +21,16 @@ const {
|
|
|
15
21
|
getTestSuitePath,
|
|
16
22
|
getRelativeCoverageFiles,
|
|
17
23
|
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
|
|
24
|
+
CUCUMBER_WORKER_TELEMETRY_PAYLOAD_CODE,
|
|
18
25
|
getIsFaultyEarlyFlakeDetection,
|
|
19
|
-
getEfdRetryCount,
|
|
20
|
-
getMaxEfdRetryCount,
|
|
21
26
|
applySkippedCoverageToCoverage,
|
|
22
27
|
getTestCoverageLinesPercentage,
|
|
28
|
+
recordTestManagementExecution,
|
|
23
29
|
recordAttemptToFixExecution,
|
|
24
|
-
|
|
30
|
+
collectTestOptimizationSummariesFromTraces,
|
|
25
31
|
logAttemptToFixTestExecution,
|
|
26
32
|
logTestOptimizationSummary,
|
|
33
|
+
TEST_IMPACT_ANALYSIS_ALL_TESTS_SKIPPED_MESSAGE,
|
|
27
34
|
getTestOptimizationRequestResults,
|
|
28
35
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
29
36
|
const { writeCoverageBackfillToCache } = require('../../dd-trace/src/ci-visibility/test-optimization-cache')
|
|
@@ -56,12 +63,25 @@ const modifiedFilesCh = channel('ci:cucumber:modified-files')
|
|
|
56
63
|
const isModifiedCh = channel('ci:cucumber:is-modified-test')
|
|
57
64
|
|
|
58
65
|
const workerReportTraceCh = channel('ci:cucumber:worker-report:trace')
|
|
66
|
+
const workerReportTelemetryCh = channel('ci:cucumber:worker-report:telemetry')
|
|
59
67
|
|
|
60
68
|
const itrSkippedSuitesCh = channel('ci:cucumber:itr:skipped-suites')
|
|
61
69
|
|
|
62
70
|
const getCodeCoverageCh = channel('ci:nyc:get-coverage')
|
|
63
71
|
|
|
64
72
|
const DD_EFD_RETRY_COUNT_MESSAGE = '_ddEfdRetryCount'
|
|
73
|
+
const CUCUMBER_RETRY_NAME_SUFFIX = / ?\(attempt \d+(?:, retried)?\) ?$/
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Removes Cucumber's generated retry suffix without changing literal scenario names.
|
|
77
|
+
*
|
|
78
|
+
* @param {string} testName
|
|
79
|
+
* @param {boolean} isRetry
|
|
80
|
+
* @returns {string}
|
|
81
|
+
*/
|
|
82
|
+
function getCucumberTestName (testName, isRetry) {
|
|
83
|
+
return isRetry ? testName.replace(CUCUMBER_RETRY_NAME_SUFFIX, '') : testName
|
|
84
|
+
}
|
|
65
85
|
|
|
66
86
|
const isMarkedAsUnskippable = (pickle) => {
|
|
67
87
|
return pickle.tags.some(tag => tag.name === '@datadog:unskippable')
|
|
@@ -105,8 +125,7 @@ let isItrEnabled = false
|
|
|
105
125
|
let isSuitesSkippingEnabled = false
|
|
106
126
|
let isCoverageReportUploadEnabled = false
|
|
107
127
|
let isEarlyFlakeDetectionEnabled = false
|
|
108
|
-
let
|
|
109
|
-
let earlyFlakeDetectionSlowTestRetries = {}
|
|
128
|
+
let earlyFlakeDetectionRetryPolicy = EMPTY_EFD_RETRY_POLICY
|
|
110
129
|
let earlyFlakeDetectionFaultyThreshold = 0
|
|
111
130
|
let isEarlyFlakeDetectionFaulty = false
|
|
112
131
|
let isFlakyTestRetriesEnabled = false
|
|
@@ -120,8 +139,16 @@ let numTestRetries = 0
|
|
|
120
139
|
let knownTests = {}
|
|
121
140
|
let skippedSuites = []
|
|
122
141
|
let isSuitesSkipped = false
|
|
142
|
+
let areAllSuitesSkipped = false
|
|
123
143
|
let repositoryRoot
|
|
124
144
|
|
|
145
|
+
/**
|
|
146
|
+
* @returns {boolean}
|
|
147
|
+
*/
|
|
148
|
+
function shouldRunEarlyFlakeDetection () {
|
|
149
|
+
return isEarlyFlakeDetectionEnabled && hasEfdRetries(earlyFlakeDetectionRetryPolicy)
|
|
150
|
+
}
|
|
151
|
+
|
|
125
152
|
function isValidKnownTests (receivedKnownTests) {
|
|
126
153
|
return !!receivedKnownTests.cucumber
|
|
127
154
|
}
|
|
@@ -165,6 +192,7 @@ function resetSuiteSkippingRunState () {
|
|
|
165
192
|
skippedSuitesCoverage = {}
|
|
166
193
|
skippedSuites = []
|
|
167
194
|
isSuitesSkipped = false
|
|
195
|
+
areAllSuitesSkipped = false
|
|
168
196
|
repositoryRoot = undefined
|
|
169
197
|
writeCoverageBackfillToCache({})
|
|
170
198
|
}
|
|
@@ -179,11 +207,6 @@ function getSuiteStatusFromTestStatuses (testStatuses) {
|
|
|
179
207
|
return 'pass'
|
|
180
208
|
}
|
|
181
209
|
|
|
182
|
-
function getConfiguredEfdRetryCount () {
|
|
183
|
-
const maxSlowTestRetryCount = getMaxEfdRetryCount(earlyFlakeDetectionSlowTestRetries)
|
|
184
|
-
return maxSlowTestRetryCount ?? earlyFlakeDetectionNumRetries
|
|
185
|
-
}
|
|
186
|
-
|
|
187
210
|
function publishWorkerEfdRetryCount (pickle, retryCount) {
|
|
188
211
|
const message = {
|
|
189
212
|
[DD_EFD_RETRY_COUNT_MESSAGE]: {
|
|
@@ -220,15 +243,13 @@ function configureParallelWorkerWorldParameters (options) {
|
|
|
220
243
|
options.worldParameters._ddIsKnownTestsEnabled = true
|
|
221
244
|
options.worldParameters._ddIsEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
|
|
222
245
|
options.worldParameters._ddKnownTests = knownTests
|
|
223
|
-
options.worldParameters.
|
|
224
|
-
options.worldParameters._ddEarlyFlakeDetectionSlowTestRetries = earlyFlakeDetectionSlowTestRetries
|
|
246
|
+
options.worldParameters._ddEarlyFlakeDetectionRetryPolicy = earlyFlakeDetectionRetryPolicy
|
|
225
247
|
} else {
|
|
226
248
|
isEarlyFlakeDetectionEnabled = false
|
|
227
249
|
isKnownTestsEnabled = false
|
|
228
250
|
options.worldParameters._ddIsEarlyFlakeDetectionEnabled = false
|
|
229
251
|
options.worldParameters._ddIsKnownTestsEnabled = false
|
|
230
|
-
options.worldParameters.
|
|
231
|
-
options.worldParameters._ddEarlyFlakeDetectionSlowTestRetries = {}
|
|
252
|
+
options.worldParameters._ddEarlyFlakeDetectionRetryPolicy = EMPTY_EFD_RETRY_POLICY
|
|
232
253
|
}
|
|
233
254
|
|
|
234
255
|
if (isImpactedTestsEnabled) {
|
|
@@ -260,10 +281,9 @@ function readParallelWorkerWorldParameters (options) {
|
|
|
260
281
|
}
|
|
261
282
|
}
|
|
262
283
|
isEarlyFlakeDetectionEnabled = !!worldParameters._ddIsEarlyFlakeDetectionEnabled
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
284
|
+
earlyFlakeDetectionRetryPolicy = isEarlyFlakeDetectionEnabled
|
|
285
|
+
? worldParameters._ddEarlyFlakeDetectionRetryPolicy ?? EMPTY_EFD_RETRY_POLICY
|
|
286
|
+
: EMPTY_EFD_RETRY_POLICY
|
|
267
287
|
isImpactedTestsEnabled = !!worldParameters._ddImpactedTestsEnabled
|
|
268
288
|
if (isImpactedTestsEnabled) {
|
|
269
289
|
modifiedFiles = worldParameters._ddModifiedFiles
|
|
@@ -281,10 +301,14 @@ function handleDdWorkerMessage (message) {
|
|
|
281
301
|
if (Array.isArray(message)) {
|
|
282
302
|
const [messageCode, payload] = message
|
|
283
303
|
if (messageCode === CUCUMBER_WORKER_TRACE_PAYLOAD_CODE) {
|
|
284
|
-
|
|
304
|
+
collectTestOptimizationSummariesFromTraces(payload, { attemptToFixExecutions })
|
|
285
305
|
workerReportTraceCh.publish(payload)
|
|
286
306
|
return true
|
|
287
307
|
}
|
|
308
|
+
if (messageCode === CUCUMBER_WORKER_TELEMETRY_PAYLOAD_CODE) {
|
|
309
|
+
workerReportTelemetryCh.publish(payload)
|
|
310
|
+
return true
|
|
311
|
+
}
|
|
288
312
|
}
|
|
289
313
|
|
|
290
314
|
if (message?.[DD_EFD_RETRY_COUNT_MESSAGE]) {
|
|
@@ -333,8 +357,10 @@ function maybeStartParallelSuite (pickle) {
|
|
|
333
357
|
})
|
|
334
358
|
}
|
|
335
359
|
|
|
336
|
-
function handleParallelTestCaseFinished (pickle, worstTestStepResult) {
|
|
337
|
-
const { status } =
|
|
360
|
+
function handleParallelTestCaseFinished (pickle, worstTestStepResult, usesNumericStatus = false) {
|
|
361
|
+
const { status } = usesNumericStatus
|
|
362
|
+
? getStatusFromResult(worstTestStepResult)
|
|
363
|
+
: getStatusFromResultLatest(worstTestStepResult)
|
|
338
364
|
let isNew = false
|
|
339
365
|
|
|
340
366
|
if (isKnownTestsEnabled) {
|
|
@@ -342,9 +368,9 @@ function handleParallelTestCaseFinished (pickle, worstTestStepResult) {
|
|
|
342
368
|
}
|
|
343
369
|
|
|
344
370
|
const testFileAbsolutePath = pickle.uri
|
|
345
|
-
const finished =
|
|
371
|
+
const finished = (pickleResultByFile[testFileAbsolutePath] ||= [])
|
|
346
372
|
|
|
347
|
-
if (
|
|
373
|
+
if (shouldRunEarlyFlakeDetection() && isNew) {
|
|
348
374
|
const testFullname = `${pickle.uri}:${pickle.name}`
|
|
349
375
|
let testStatuses = newTestsByTestFullname.get(testFullname)
|
|
350
376
|
if (testStatuses) {
|
|
@@ -357,7 +383,7 @@ function handleParallelTestCaseFinished (pickle, worstTestStepResult) {
|
|
|
357
383
|
if (efdRetryCount === undefined) {
|
|
358
384
|
efdRetryCount = status === 'skip'
|
|
359
385
|
? 0
|
|
360
|
-
:
|
|
386
|
+
: earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
361
387
|
efdRetryCountByPickleId.set(pickle.id, efdRetryCount)
|
|
362
388
|
if (efdRetryCount === 0 && status !== 'skip') {
|
|
363
389
|
efdSlowAbortedPickleIds.add(pickle.id)
|
|
@@ -555,8 +581,7 @@ function getErrorFromCucumberResult (cucumberResult) {
|
|
|
555
581
|
return
|
|
556
582
|
}
|
|
557
583
|
|
|
558
|
-
const
|
|
559
|
-
const error = new Error(message)
|
|
584
|
+
const error = new Error(getSegment(cucumberResult.message, '\n', 0))
|
|
560
585
|
if (cucumberResult.exception) {
|
|
561
586
|
error.type = cucumberResult.exception.type
|
|
562
587
|
}
|
|
@@ -696,7 +721,7 @@ function publishRetriedAttempt (runner, state) {
|
|
|
696
721
|
|
|
697
722
|
// ATR: record this attempt as failed so when run().finally runs (after retry) we have all statuses
|
|
698
723
|
if (isFlakyTestRetriesEnabled) {
|
|
699
|
-
const nameForKey = runner.pickle.name
|
|
724
|
+
const nameForKey = getCucumberTestName(runner.pickle.name, currentAttempt > 0)
|
|
700
725
|
const atrKey = `${runner.pickle.uri}:${nameForKey}`
|
|
701
726
|
if (atrStatusesByScenarioKey.has(atrKey)) {
|
|
702
727
|
atrStatusesByScenarioKey.get(atrKey).push('fail')
|
|
@@ -793,7 +818,7 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
793
818
|
testFnCh.runStores(ctx, () => {
|
|
794
819
|
promise = run.apply(this, args)
|
|
795
820
|
})
|
|
796
|
-
|
|
821
|
+
const finalize = async () => {
|
|
797
822
|
if (!canAwaitRetries) {
|
|
798
823
|
this.eventBroadcaster.removeListener('envelope', onEnvelope)
|
|
799
824
|
}
|
|
@@ -802,6 +827,7 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
802
827
|
const { status, skipReason } = isLatestVersion
|
|
803
828
|
? getStatusFromResultLatest(result)
|
|
804
829
|
: getStatusFromResult(result)
|
|
830
|
+
const testName = getCucumberTestName(this.pickle.name, state.numAttempt > 0)
|
|
805
831
|
|
|
806
832
|
if (lastStatusByPickleId.has(this.pickle.id)) {
|
|
807
833
|
lastStatusByPickleId.get(this.pickle.id).push(status)
|
|
@@ -821,7 +847,7 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
821
847
|
|
|
822
848
|
if (isTestManagementTestsEnabled) {
|
|
823
849
|
const testSuitePath = getTestSuitePath(testFileAbsolutePath, process.cwd())
|
|
824
|
-
const testProperties = getTestProperties(testSuitePath,
|
|
850
|
+
const testProperties = getTestProperties(testSuitePath, testName)
|
|
825
851
|
const numRetries = numRetriesByPickleId.get(this.pickle.id)
|
|
826
852
|
isAttemptToFix = testProperties.attemptToFix
|
|
827
853
|
isAttemptToFixRetry = isAttemptToFix && numRetries > 0
|
|
@@ -857,20 +883,24 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
857
883
|
}
|
|
858
884
|
|
|
859
885
|
if (
|
|
860
|
-
|
|
886
|
+
shouldRunEarlyFlakeDetection() &&
|
|
861
887
|
status !== 'skip' &&
|
|
862
888
|
(isNew || isModified) &&
|
|
863
889
|
!isEfdRetry &&
|
|
864
890
|
!efdRetryCountByPickleId.has(this.pickle.id)
|
|
865
891
|
) {
|
|
866
|
-
const retryCount =
|
|
892
|
+
const retryCount = getEfdRetryCountForDuration(
|
|
893
|
+
performance.now() - executionStart,
|
|
894
|
+
earlyFlakeDetectionRetryPolicy
|
|
895
|
+
)
|
|
867
896
|
efdRetryCountByPickleId.set(this.pickle.id, retryCount)
|
|
868
897
|
if (retryCount === 0) {
|
|
869
898
|
efdSlowAbortedPickleIds.add(this.pickle.id)
|
|
870
899
|
}
|
|
871
900
|
}
|
|
872
901
|
|
|
873
|
-
const efdRetryCount = efdRetryCountByPickleId.get(this.pickle.id) ??
|
|
902
|
+
const efdRetryCount = efdRetryCountByPickleId.get(this.pickle.id) ??
|
|
903
|
+
earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
874
904
|
|
|
875
905
|
// Check if all EFD retries failed
|
|
876
906
|
if (isEfdRetry && (isNew || isModified)) {
|
|
@@ -889,8 +919,7 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
889
919
|
// ATR: accumulate statuses by stable scenario key (uri:name) so retries are grouped.
|
|
890
920
|
// Cucumber appends " (attempt N)" or " (attempt N, retried)" to the scenario name; normalize for keying.
|
|
891
921
|
if (isFlakyTestRetriesEnabled && !isAttemptToFix && !isEfdRetry && numTestRetries > 0) {
|
|
892
|
-
const
|
|
893
|
-
const atrKey = `${this.pickle.uri}:${nameForKey}`
|
|
922
|
+
const atrKey = `${this.pickle.uri}:${testName}`
|
|
894
923
|
if (atrStatusesByScenarioKey.has(atrKey)) {
|
|
895
924
|
atrStatusesByScenarioKey.get(atrKey).push(status)
|
|
896
925
|
} else {
|
|
@@ -909,10 +938,21 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
909
938
|
|
|
910
939
|
const error = getErrorFromCucumberResult(result)
|
|
911
940
|
|
|
941
|
+
if (!testStartPayload.isParallel) {
|
|
942
|
+
recordTestManagementExecution({
|
|
943
|
+
testSuite: testSuitePath,
|
|
944
|
+
testName,
|
|
945
|
+
status,
|
|
946
|
+
isAttemptToFix,
|
|
947
|
+
isDisabled,
|
|
948
|
+
isQuarantined,
|
|
949
|
+
})
|
|
950
|
+
}
|
|
951
|
+
|
|
912
952
|
if (isAttemptToFix) {
|
|
913
953
|
recordAttemptToFixExecution(attemptToFixExecutions, {
|
|
914
954
|
testSuite: testSuitePath,
|
|
915
|
-
testName
|
|
955
|
+
testName,
|
|
916
956
|
status,
|
|
917
957
|
isDisabled,
|
|
918
958
|
isQuarantined,
|
|
@@ -953,7 +993,8 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
953
993
|
error,
|
|
954
994
|
isNew,
|
|
955
995
|
isEfdRetry,
|
|
956
|
-
isFlakyRetry: state.numAttempt > 0,
|
|
996
|
+
isFlakyRetry: state.numAttempt > 0 && isFlakyTestRetriesEnabled,
|
|
997
|
+
isExternalRetry: state.numAttempt > 0 && !isFlakyTestRetriesEnabled,
|
|
957
998
|
isAttemptToFix,
|
|
958
999
|
isAttemptToFixRetry,
|
|
959
1000
|
hasFailedAllRetries,
|
|
@@ -966,6 +1007,9 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
966
1007
|
...attemptCtx.currentStore,
|
|
967
1008
|
finalStatus,
|
|
968
1009
|
})
|
|
1010
|
+
}
|
|
1011
|
+
promise.then(finalize, finalize).catch(error => {
|
|
1012
|
+
log.error('Cucumber test finalization error', error)
|
|
969
1013
|
})
|
|
970
1014
|
return promise
|
|
971
1015
|
} catch (err) {
|
|
@@ -1056,8 +1100,8 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1056
1100
|
repositoryRoot = configurationResponse.repositoryRoot
|
|
1057
1101
|
isItrEnabled = configurationResponse.libraryConfig?.isItrEnabled
|
|
1058
1102
|
isEarlyFlakeDetectionEnabled = configurationResponse.libraryConfig?.isEarlyFlakeDetectionEnabled
|
|
1059
|
-
|
|
1060
|
-
|
|
1103
|
+
earlyFlakeDetectionRetryPolicy = configurationResponse.libraryConfig?.earlyFlakeDetectionRetryPolicy ??
|
|
1104
|
+
EMPTY_EFD_RETRY_POLICY
|
|
1061
1105
|
earlyFlakeDetectionFaultyThreshold = configurationResponse.libraryConfig?.earlyFlakeDetectionFaultyThreshold
|
|
1062
1106
|
isSuitesSkippingEnabled = isItrEnabled && configurationResponse.libraryConfig?.isSuitesSkippingEnabled
|
|
1063
1107
|
isCoverageReportUploadEnabled = configurationResponse.libraryConfig?.isCoverageReportUploadEnabled
|
|
@@ -1110,6 +1154,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1110
1154
|
const oldPickles = isCoordinator ? this.sourcedPickles : this.pickleIds
|
|
1111
1155
|
|
|
1112
1156
|
isSuitesSkipped = picklesToRun.length !== oldPickles.length
|
|
1157
|
+
areAllSuitesSkipped = oldPickles.length > 0 && picklesToRun.length === 0
|
|
1113
1158
|
|
|
1114
1159
|
log.debug('%s out of %s suites are going to run.', picklesToRun.length, oldPickles.length)
|
|
1115
1160
|
|
|
@@ -1226,7 +1271,10 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1226
1271
|
isParallel,
|
|
1227
1272
|
})
|
|
1228
1273
|
|
|
1229
|
-
logTestOptimizationSummary({
|
|
1274
|
+
logTestOptimizationSummary({
|
|
1275
|
+
attemptToFixExecutions,
|
|
1276
|
+
extraSections: areAllSuitesSkipped ? [TEST_IMPACT_ANALYSIS_ALL_TESTS_SKIPPED_MESSAGE] : [],
|
|
1277
|
+
})
|
|
1230
1278
|
loggedAttemptToFixTests.clear()
|
|
1231
1279
|
eventDataCollector = null
|
|
1232
1280
|
await flushPromise
|
|
@@ -1314,7 +1362,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1314
1362
|
}
|
|
1315
1363
|
}
|
|
1316
1364
|
const originalRetry = this.options.retry
|
|
1317
|
-
const isManagedRetry = isAttemptToFix || (
|
|
1365
|
+
const isManagedRetry = isAttemptToFix || (shouldRunEarlyFlakeDetection() && (isNew || isModified))
|
|
1318
1366
|
if (isManagedRetry) {
|
|
1319
1367
|
this.options.retry = 0
|
|
1320
1368
|
}
|
|
@@ -1339,10 +1387,10 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1339
1387
|
}
|
|
1340
1388
|
|
|
1341
1389
|
// If it's a new test and it hasn't been skipped, we run it again
|
|
1342
|
-
if (
|
|
1390
|
+
if (shouldRunEarlyFlakeDetection() && lastTestStatus !== 'skip' && (isNew || isModified)) {
|
|
1343
1391
|
let efdRetryCount = efdRetryCountByPickleId.get(pickle.id)
|
|
1344
1392
|
if (efdRetryCount === undefined) {
|
|
1345
|
-
efdRetryCount =
|
|
1393
|
+
efdRetryCount = getEfdRetryCountForDuration(firstExecutionDurationMs, earlyFlakeDetectionRetryPolicy)
|
|
1346
1394
|
efdRetryCountByPickleId.set(pickle.id, efdRetryCount)
|
|
1347
1395
|
if (efdRetryCount === 0) {
|
|
1348
1396
|
efdSlowAbortedPickleIds.add(pickle.id)
|
|
@@ -1361,7 +1409,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1361
1409
|
let shouldBePassedByEFD = false
|
|
1362
1410
|
let shouldBePassedByTestManagement = false
|
|
1363
1411
|
let shouldBeFailedByAttemptToFix = false
|
|
1364
|
-
if ((isNew || isModified) &&
|
|
1412
|
+
if ((isNew || isModified) && shouldRunEarlyFlakeDetection()) {
|
|
1365
1413
|
/**
|
|
1366
1414
|
* If Early Flake Detection (EFD) is enabled the logic is as follows:
|
|
1367
1415
|
* - If all attempts for a test are failing, the test has failed and we will let the test process fail.
|
|
@@ -1419,7 +1467,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1419
1467
|
|
|
1420
1468
|
this.options.retry = originalRetry
|
|
1421
1469
|
|
|
1422
|
-
if (isNewerCucumberVersion &&
|
|
1470
|
+
if (isNewerCucumberVersion && shouldRunEarlyFlakeDetection() && (isNew || isModified)) {
|
|
1423
1471
|
return shouldBePassedByEFD
|
|
1424
1472
|
}
|
|
1425
1473
|
|
|
@@ -1448,7 +1496,7 @@ function patchCucumberWorkerRunTestCase (runtimeExecutorPackage, isWorker) {
|
|
|
1448
1496
|
)
|
|
1449
1497
|
}
|
|
1450
1498
|
|
|
1451
|
-
function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion) {
|
|
1499
|
+
function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion, usesNumericStatus = false) {
|
|
1452
1500
|
return function (worker, message) {
|
|
1453
1501
|
if (!testSuiteFinishCh.hasSubscribers) {
|
|
1454
1502
|
return parseWorkerMessageFunction.apply(this, arguments)
|
|
@@ -1499,13 +1547,31 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
|
|
|
1499
1547
|
pickle = testCase.pickle
|
|
1500
1548
|
}
|
|
1501
1549
|
|
|
1502
|
-
handleParallelTestCaseFinished(pickle, worstTestStepResult)
|
|
1550
|
+
handleParallelTestCaseFinished(pickle, worstTestStepResult, usesNumericStatus)
|
|
1503
1551
|
}
|
|
1504
1552
|
|
|
1505
1553
|
return parseWorkerResponse
|
|
1506
1554
|
}
|
|
1507
1555
|
}
|
|
1508
1556
|
|
|
1557
|
+
/**
|
|
1558
|
+
* Adapts Cucumber 7's callback-based parallel coordinator to the Promise contract used by getWrappedStart.
|
|
1559
|
+
*
|
|
1560
|
+
* @param {Function} run
|
|
1561
|
+
* @param {string} frameworkVersion
|
|
1562
|
+
* @returns {Function}
|
|
1563
|
+
*/
|
|
1564
|
+
function getWrappedCoordinatorRun (run, frameworkVersion) {
|
|
1565
|
+
const runAsPromise = function (numberOfWorkers) {
|
|
1566
|
+
return new Promise(resolve => run.call(this, numberOfWorkers, resolve))
|
|
1567
|
+
}
|
|
1568
|
+
const wrappedStart = getWrappedStart(runAsPromise, frameworkVersion, true)
|
|
1569
|
+
|
|
1570
|
+
return function (numberOfWorkers, done) {
|
|
1571
|
+
return wrappedStart.call(this, numberOfWorkers).then(done)
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1509
1575
|
module.exports.patchCucumberWorkerRunTestCase = patchCucumberWorkerRunTestCase
|
|
1510
1576
|
|
|
1511
1577
|
// Test start / finish for older versions. The only hook executed in workers when in parallel mode
|
|
@@ -1553,19 +1619,33 @@ addHook({
|
|
|
1553
1619
|
return runtimePackage
|
|
1554
1620
|
})
|
|
1555
1621
|
|
|
1556
|
-
// Only executed in parallel mode.
|
|
1557
|
-
// `getWrappedStart` generates session start and finish events
|
|
1622
|
+
// Only executed in parallel mode in Cucumber 7 through 10.
|
|
1623
|
+
// `getWrappedCoordinatorRun` or `getWrappedStart` generates session start and finish events
|
|
1558
1624
|
// `getWrappedParseWorkerMessage` generates suite start and finish events
|
|
1625
|
+
// Shimmer is required because the coordinator must be changed before it starts workers and exposes no lifecycle hook.
|
|
1559
1626
|
addHook({
|
|
1560
1627
|
name: '@cucumber/cucumber',
|
|
1561
|
-
versions: ['>=
|
|
1628
|
+
versions: ['>=7.0.0 <11.0.0'],
|
|
1562
1629
|
file: 'lib/runtime/parallel/coordinator.js',
|
|
1563
1630
|
}, (coordinatorPackage, frameworkVersion) => {
|
|
1564
|
-
|
|
1631
|
+
const isCucumber7 = satisfies(frameworkVersion, '<8.0.0')
|
|
1632
|
+
if (isCucumber7) {
|
|
1633
|
+
shimmer.wrap(
|
|
1634
|
+
coordinatorPackage.default.prototype,
|
|
1635
|
+
'run',
|
|
1636
|
+
run => getWrappedCoordinatorRun(run, frameworkVersion)
|
|
1637
|
+
)
|
|
1638
|
+
} else {
|
|
1639
|
+
shimmer.wrap(
|
|
1640
|
+
coordinatorPackage.default.prototype,
|
|
1641
|
+
'start',
|
|
1642
|
+
start => getWrappedStart(start, frameworkVersion, true)
|
|
1643
|
+
)
|
|
1644
|
+
}
|
|
1565
1645
|
shimmer.wrap(
|
|
1566
1646
|
coordinatorPackage.default.prototype,
|
|
1567
1647
|
'parseWorkerMessage',
|
|
1568
|
-
parseWorkerMessage => getWrappedParseWorkerMessage(parseWorkerMessage)
|
|
1648
|
+
parseWorkerMessage => getWrappedParseWorkerMessage(parseWorkerMessage, false, isCucumber7)
|
|
1569
1649
|
)
|
|
1570
1650
|
return coordinatorPackage
|
|
1571
1651
|
})
|
|
@@ -9,6 +9,7 @@ const rrtypes = {
|
|
|
9
9
|
resolveAny: 'ANY',
|
|
10
10
|
resolve4: 'A',
|
|
11
11
|
resolve6: 'AAAA',
|
|
12
|
+
resolveCaa: 'CAA',
|
|
12
13
|
resolveCname: 'CNAME',
|
|
13
14
|
resolveMx: 'MX',
|
|
14
15
|
resolveNs: 'NS',
|
|
@@ -17,6 +18,7 @@ const rrtypes = {
|
|
|
17
18
|
resolvePtr: 'PTR',
|
|
18
19
|
resolveNaptr: 'NAPTR',
|
|
19
20
|
resolveSoa: 'SOA',
|
|
21
|
+
resolveTlsa: 'TLSA',
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
// `dns.promises` and `require('dns/promises')` resolve to the same exports object. Both
|
|
@@ -81,7 +83,7 @@ function buildCallbackArgsContext (rrtype) {
|
|
|
81
83
|
const captured = [...args]
|
|
82
84
|
captured.pop() // remove the callback
|
|
83
85
|
if (rrtype) {
|
|
84
|
-
captured
|
|
86
|
+
insertRrtype(captured, rrtype)
|
|
85
87
|
}
|
|
86
88
|
return { args: captured }
|
|
87
89
|
}
|
|
@@ -91,8 +93,25 @@ function buildPromiseArgsContext (rrtype) {
|
|
|
91
93
|
return function (_, args) {
|
|
92
94
|
const captured = [...args]
|
|
93
95
|
if (rrtype) {
|
|
94
|
-
captured
|
|
96
|
+
insertRrtype(captured, rrtype)
|
|
95
97
|
}
|
|
96
98
|
return { args: captured }
|
|
97
99
|
}
|
|
98
100
|
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @param {unknown[]} captured
|
|
104
|
+
* @param {string} rrtype
|
|
105
|
+
*/
|
|
106
|
+
function insertRrtype (captured, rrtype) {
|
|
107
|
+
if (captured.length === 0) {
|
|
108
|
+
captured.push(rrtype)
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
captured.push(rrtype)
|
|
113
|
+
for (let index = captured.length - 1; index > 1; index--) {
|
|
114
|
+
captured[index] = captured[index - 1]
|
|
115
|
+
}
|
|
116
|
+
captured[1] = rrtype
|
|
117
|
+
}
|
|
@@ -149,6 +149,7 @@ function wrapBrowserWindow (electron) {
|
|
|
149
149
|
|
|
150
150
|
// BrowserWindow doesn't support subclassing because it's all native code
|
|
151
151
|
// so we return an instance of it instead of the subclass.
|
|
152
|
+
// eslint-disable-next-line no-constructor-return
|
|
152
153
|
return win
|
|
153
154
|
}
|
|
154
155
|
}
|
|
@@ -25,6 +25,8 @@ const bodyPublished = new WeakSet()
|
|
|
25
25
|
let lastPublishedError
|
|
26
26
|
let lastPublishedReq
|
|
27
27
|
|
|
28
|
+
/** @typedef {{ length: number, [index: number]: unknown } & Iterable<unknown>} ArgumentsLike */
|
|
29
|
+
|
|
28
30
|
function wrapFastify (fastify, hasParsingEvents) {
|
|
29
31
|
if (typeof fastify !== 'function') return fastify
|
|
30
32
|
|
|
@@ -81,7 +83,7 @@ function wrapAddHook (addHook) {
|
|
|
81
83
|
* @param {string} name Lifecycle phase the hook was registered against.
|
|
82
84
|
* @param {Function} fn User-supplied hook.
|
|
83
85
|
* @param {unknown} thisArg `this` Fastify passes to the hook.
|
|
84
|
-
* @param {
|
|
86
|
+
* @param {ArgumentsLike} args Fastify's positional args; the dispatcher always
|
|
85
87
|
* places `done` as the trailing positional (see fastify/lib/hooks.js hookIterator,
|
|
86
88
|
* onSendHookRunner, preParsingHookRunner, onRequestAbortHookRunner).
|
|
87
89
|
*/
|