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
|
@@ -1,28 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { relative } from 'node:path'
|
|
3
|
-
import { performance } from 'node:perf_hooks'
|
|
1
|
+
import { afterEach, beforeAll, beforeEach, inject } from 'vitest'
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// Instrumentation-less worker setup for DD_EXPERIMENTAL_TEST_OPT_VITEST_NO_WORKER_INIT.
|
|
8
|
-
// It applies Test Optimization execution changes without initializing dd-trace in Vitest workers.
|
|
3
|
+
// Instrumentation-less setup for DD_EXPERIMENTAL_TEST_OPT_VITEST_NO_WORKER_INIT.
|
|
4
|
+
// It applies Test Optimization execution changes without initializing dd-trace and also supports Browser Mode.
|
|
9
5
|
const VITEST_NO_WORKER_INIT_ACTIVE_ENV = 'DD_TEST_OPT_VITEST_NO_WORKER_INIT_ACTIVE'
|
|
10
|
-
const
|
|
11
|
-
const
|
|
6
|
+
const providedContext = getProvidedContext()
|
|
7
|
+
const isNoWorkerInitActive = providedContext.isActive ?? getIsNoWorkerInitActive()
|
|
12
8
|
const attemptToFixTests = providedContext.attemptToFixTests || {}
|
|
13
9
|
const attemptToFixRetries = providedContext.attemptToFixRetries || 0
|
|
14
10
|
const disabledTests = providedContext.disabledTests || {}
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const hasEarlyFlakeDetectionSlowRetries = Object.keys(earlyFlakeDetectionSlowRetries).length > 0
|
|
11
|
+
const earlyFlakeDetectionRetryPolicy = providedContext.earlyFlakeDetectionRetryPolicy || {
|
|
12
|
+
durationRetryCounts: [],
|
|
13
|
+
schedulingRetryCount: 0,
|
|
14
|
+
}
|
|
15
|
+
const earlyFlakeDetectionRetries = earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
21
16
|
const isEarlyFlakeDetectionEnabled = providedContext.isEarlyFlakeDetectionEnabled === true
|
|
22
17
|
const knownTests = providedContext.knownTests || {}
|
|
23
18
|
const modifiedFiles = providedContext.modifiedFiles || {}
|
|
24
19
|
const quarantinedTests = providedContext.quarantinedTests || {}
|
|
25
|
-
const
|
|
20
|
+
const isRumCorrelationEnabled = providedContext.isRumCorrelationEnabled !== false
|
|
21
|
+
const rumTestExecutionIdCookieName = providedContext.rumTestExecutionIdCookieName
|
|
22
|
+
const testPropertiesByFilepath = providedContext.testPropertiesByFilepath || {}
|
|
26
23
|
let setVitestTaskFn
|
|
27
24
|
if (isNoWorkerInitActive) {
|
|
28
25
|
try {
|
|
@@ -35,7 +32,21 @@ const earlyFlakeDetectionRetriesByTask = new WeakMap()
|
|
|
35
32
|
const earlyFlakeDetectionSkippedResults = new WeakMap()
|
|
36
33
|
const earlyFlakeDetectionStartByTask = new WeakMap()
|
|
37
34
|
const nextAttemptIndexByTask = new WeakMap()
|
|
38
|
-
const
|
|
35
|
+
const retryAttemptIndexByTask = new WeakMap()
|
|
36
|
+
const usedRumTestExecutionIds = new Set()
|
|
37
|
+
let now
|
|
38
|
+
let timeOrigin
|
|
39
|
+
// Use an unfaked monotonic clock in Node and Vitest's parent frame in Browser Mode.
|
|
40
|
+
if (typeof globalThis.process?.uptime === 'function') {
|
|
41
|
+
now = () => globalThis.process.uptime() * 1000
|
|
42
|
+
timeOrigin = Date.now() - now()
|
|
43
|
+
} else {
|
|
44
|
+
const clock = globalThis.window?.parent && globalThis.window.parent !== globalThis.window
|
|
45
|
+
? globalThis.window.parent.performance
|
|
46
|
+
: globalThis.performance
|
|
47
|
+
now = clock ? clock.now.bind(clock) : Date.now
|
|
48
|
+
timeOrigin = Number.isFinite(clock?.timeOrigin) ? clock.timeOrigin : Date.now() - now()
|
|
49
|
+
}
|
|
39
50
|
|
|
40
51
|
if (isNoWorkerInitActive) {
|
|
41
52
|
// eslint-disable-next-line no-empty-pattern
|
|
@@ -51,11 +62,12 @@ if (isNoWorkerInitActive) {
|
|
|
51
62
|
const isEarlyFlakeDetectionTestAttempt = isEarlyFlakeDetectionTest(testSuite, testName)
|
|
52
63
|
const isQuarantinedTest = quarantinedTests[testSuite]?.[testName] && !isAttemptToFixTest
|
|
53
64
|
const attemptIndex = getNextAttemptIndex(task)
|
|
65
|
+
const attemptStart = now()
|
|
54
66
|
if (attemptIndex > 0) {
|
|
55
67
|
recordTestOptimizationStatus(task, attemptIndex - 1)
|
|
56
68
|
}
|
|
57
69
|
|
|
58
|
-
if (disabledTests[testSuite]?.[testName]
|
|
70
|
+
if (!isAttemptToFixTest && disabledTests[testSuite]?.[testName]) {
|
|
59
71
|
skip('Skipped by Datadog Test Optimization')
|
|
60
72
|
} else if (isAttemptToFixTest && attemptIndex > 0) {
|
|
61
73
|
task.result.state = 'run'
|
|
@@ -66,49 +78,59 @@ if (isNoWorkerInitActive) {
|
|
|
66
78
|
}
|
|
67
79
|
}
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
prepareRumCorrelation(task, attemptIndex)
|
|
82
|
+
|
|
83
|
+
onTestFinished(() => {
|
|
84
|
+
recordTestAttemptTiming(task, attemptIndex, attemptStart)
|
|
85
|
+
recordRetryErrorCount(task)
|
|
86
|
+
if (
|
|
87
|
+
(isAttemptToFixTest || isEarlyFlakeDetectionTestAttempt || isQuarantinedTest) &&
|
|
88
|
+
attemptIndex === getFinalAttemptIndex(task)
|
|
89
|
+
) {
|
|
90
|
+
if (isAttemptToFixTest || isEarlyFlakeDetectionTestAttempt) {
|
|
91
|
+
recordTestOptimizationStatus(task, attemptIndex, true)
|
|
76
92
|
}
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
switchQuarantinedFinalFailure(task, attemptIndex)
|
|
94
|
+
}
|
|
95
|
+
finishRumCorrelation(task, attemptIndex)
|
|
96
|
+
})
|
|
79
97
|
})
|
|
80
98
|
|
|
81
99
|
afterEach(function ({ task }) {
|
|
82
100
|
const attemptIndex = task.meta.__ddTestOptCurrentAttemptIndex
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
if (attemptIndex === getFinalAttemptIndex(task)) {
|
|
101
|
+
const restoredEarlyFlakeDetectionResult = restoreEarlyFlakeDetectionSkippedResult(task)
|
|
102
|
+
if (!restoredEarlyFlakeDetectionResult && attemptIndex === getFinalAttemptIndex(task)) {
|
|
87
103
|
recordTestOptimizationStatus(task, attemptIndex)
|
|
88
104
|
}
|
|
89
|
-
|
|
105
|
+
if (!restoredEarlyFlakeDetectionResult) {
|
|
106
|
+
switchQuarantinedFinalFailure(task, attemptIndex)
|
|
107
|
+
}
|
|
90
108
|
})
|
|
91
109
|
}
|
|
92
110
|
|
|
93
111
|
function applyExecutionChanges (suite) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
112
|
+
const tasks = suite?.tasks
|
|
113
|
+
if (tasks) {
|
|
114
|
+
for (const task of tasks) {
|
|
115
|
+
if (task.type === 'suite') {
|
|
116
|
+
applyExecutionChanges(task)
|
|
117
|
+
continue
|
|
118
|
+
}
|
|
99
119
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
120
|
+
const testSuite = getTestSuite(task)
|
|
121
|
+
const testName = getTestName(task)
|
|
122
|
+
if (attemptToFixTests[testSuite]?.[testName]) {
|
|
123
|
+
task.retry = 0
|
|
124
|
+
task.repeats = attemptToFixRetries
|
|
125
|
+
task.meta.__ddTestOptAtfRetries = attemptToFixRetries
|
|
126
|
+
} else if (disabledTests[testSuite]?.[testName]) {
|
|
127
|
+
task.mode = 'skip'
|
|
128
|
+
} else if (isEarlyFlakeDetectionTest(testSuite, testName)) {
|
|
129
|
+
task.retry = 0
|
|
130
|
+
task.repeats = earlyFlakeDetectionRetries
|
|
131
|
+
task.meta.__ddTestOptEfdRetries = earlyFlakeDetectionRetries
|
|
132
|
+
}
|
|
133
|
+
wrapRetryCondition(task)
|
|
112
134
|
}
|
|
113
135
|
}
|
|
114
136
|
}
|
|
@@ -117,9 +139,194 @@ function getNextAttemptIndex (task) {
|
|
|
117
139
|
const attemptIndex = nextAttemptIndexByTask.get(task) || 0
|
|
118
140
|
nextAttemptIndexByTask.set(task, attemptIndex + 1)
|
|
119
141
|
task.meta.__ddTestOptCurrentAttemptIndex = attemptIndex
|
|
142
|
+
|
|
143
|
+
const repeatCount = task.result?.repeatCount || 0
|
|
144
|
+
const retryAttempt = retryAttemptIndexByTask.get(task)
|
|
145
|
+
const retryAttemptIndex = retryAttempt?.repeatCount === repeatCount ? retryAttempt.index + 1 : 0
|
|
146
|
+
retryAttemptIndexByTask.set(task, {
|
|
147
|
+
index: retryAttemptIndex,
|
|
148
|
+
repeatCount,
|
|
149
|
+
})
|
|
150
|
+
|
|
120
151
|
return attemptIndex
|
|
121
152
|
}
|
|
122
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Sets the RUM correlation cookie for a sequential browser test attempt.
|
|
156
|
+
*
|
|
157
|
+
* @param {object} task
|
|
158
|
+
* @param {number} attemptIndex
|
|
159
|
+
* @returns {void}
|
|
160
|
+
*/
|
|
161
|
+
function prepareRumCorrelation (task, attemptIndex) {
|
|
162
|
+
// A per-origin cookie cannot identify overlapping attempts without racing.
|
|
163
|
+
if (!isRumCorrelationEnabled || isConcurrentTask(task)) return
|
|
164
|
+
|
|
165
|
+
if (
|
|
166
|
+
typeof window === 'undefined' ||
|
|
167
|
+
typeof document === 'undefined' ||
|
|
168
|
+
typeof rumTestExecutionIdCookieName !== 'string'
|
|
169
|
+
) {
|
|
170
|
+
return
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const testExecutionId = generateTestExecutionId()
|
|
174
|
+
if (
|
|
175
|
+
!testExecutionId ||
|
|
176
|
+
usedRumTestExecutionIds.has(testExecutionId) ||
|
|
177
|
+
!setRumCorrelationCookie(testExecutionId)
|
|
178
|
+
) {
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
usedRumTestExecutionIds.add(testExecutionId)
|
|
183
|
+
task.meta.__ddTestOptRumTestExecutionIds ||= []
|
|
184
|
+
task.meta.__ddTestOptRumTestExecutionIds[attemptIndex] = testExecutionId
|
|
185
|
+
recordRumActivity(task, attemptIndex)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Records whether RUM was active and clears the attempt cookie.
|
|
190
|
+
*
|
|
191
|
+
* @param {object} task
|
|
192
|
+
* @param {number} attemptIndex
|
|
193
|
+
* @returns {void}
|
|
194
|
+
*/
|
|
195
|
+
function finishRumCorrelation (task, attemptIndex) {
|
|
196
|
+
const testExecutionId = task.meta.__ddTestOptRumTestExecutionIds?.[attemptIndex]
|
|
197
|
+
if (!testExecutionId) return
|
|
198
|
+
|
|
199
|
+
recordRumActivity(task, attemptIndex)
|
|
200
|
+
clearRumCorrelationCookie(testExecutionId)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Retains evidence that RUM was active at any point observed during the attempt.
|
|
205
|
+
*
|
|
206
|
+
* @param {object} task
|
|
207
|
+
* @param {number} attemptIndex
|
|
208
|
+
* @returns {void}
|
|
209
|
+
*/
|
|
210
|
+
function recordRumActivity (task, attemptIndex) {
|
|
211
|
+
if (!getIsRumActive(getRum())) return
|
|
212
|
+
|
|
213
|
+
task.meta.__ddTestOptRumActive ||= []
|
|
214
|
+
task.meta.__ddTestOptRumActive[attemptIndex] = true
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Returns the RUM public API without letting application-defined accessors fail a test.
|
|
219
|
+
*
|
|
220
|
+
* @returns {object|undefined}
|
|
221
|
+
*/
|
|
222
|
+
function getRum () {
|
|
223
|
+
try {
|
|
224
|
+
return window.DD_RUM
|
|
225
|
+
} catch {}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Returns whether the current RUM session is active.
|
|
230
|
+
*
|
|
231
|
+
* @param {object|undefined} rum
|
|
232
|
+
* @returns {boolean}
|
|
233
|
+
*/
|
|
234
|
+
function getIsRumActive (rum) {
|
|
235
|
+
if (!rum) return false
|
|
236
|
+
if (typeof rum.getInternalContext !== 'function') return false
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
return !!rum.getInternalContext()
|
|
240
|
+
} catch {
|
|
241
|
+
return false
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Returns whether a task or any containing suite is concurrent.
|
|
247
|
+
*
|
|
248
|
+
* @param {object} task
|
|
249
|
+
* @returns {boolean}
|
|
250
|
+
*/
|
|
251
|
+
function isConcurrentTask (task) {
|
|
252
|
+
let currentTask = task
|
|
253
|
+
while (currentTask) {
|
|
254
|
+
if (currentTask.concurrent === true) return true
|
|
255
|
+
currentTask = currentTask.suite
|
|
256
|
+
}
|
|
257
|
+
return false
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Generates a positive 63-bit decimal test execution ID.
|
|
262
|
+
*
|
|
263
|
+
* @returns {string|undefined}
|
|
264
|
+
*/
|
|
265
|
+
function generateTestExecutionId () {
|
|
266
|
+
// This setup file executes in a browser even though lint validates it against the package's Node.js target.
|
|
267
|
+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
268
|
+
if (typeof globalThis.crypto?.getRandomValues !== 'function') return
|
|
269
|
+
|
|
270
|
+
const words = new Uint32Array(2)
|
|
271
|
+
try {
|
|
272
|
+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
273
|
+
globalThis.crypto.getRandomValues(words)
|
|
274
|
+
} catch {
|
|
275
|
+
return
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
words[0] &= 0x7F_FF_FF_FF
|
|
279
|
+
if (words[0] === 0 && words[1] === 0) return
|
|
280
|
+
|
|
281
|
+
return ((BigInt(words[0]) << 32n) | BigInt(words[1])).toString(10)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Sets and verifies the RUM correlation cookie for the current origin.
|
|
286
|
+
*
|
|
287
|
+
* @param {string} testExecutionId
|
|
288
|
+
* @returns {boolean}
|
|
289
|
+
*/
|
|
290
|
+
function setRumCorrelationCookie (testExecutionId) {
|
|
291
|
+
try {
|
|
292
|
+
// eslint-disable-next-line unicorn/no-document-cookie
|
|
293
|
+
document.cookie = `${rumTestExecutionIdCookieName}=${testExecutionId}; path=/`
|
|
294
|
+
return getRumCorrelationCookie() === testExecutionId
|
|
295
|
+
} catch {
|
|
296
|
+
return false
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Clears the RUM correlation cookie if it still belongs to this attempt.
|
|
302
|
+
*
|
|
303
|
+
* @param {string} testExecutionId
|
|
304
|
+
* @returns {void}
|
|
305
|
+
*/
|
|
306
|
+
function clearRumCorrelationCookie (testExecutionId) {
|
|
307
|
+
try {
|
|
308
|
+
if (getRumCorrelationCookie() === testExecutionId) {
|
|
309
|
+
// eslint-disable-next-line unicorn/no-document-cookie
|
|
310
|
+
document.cookie = `${rumTestExecutionIdCookieName}=; path=/; max-age=0`
|
|
311
|
+
}
|
|
312
|
+
} catch {}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Returns the current RUM correlation cookie value.
|
|
317
|
+
*
|
|
318
|
+
* @returns {string|undefined}
|
|
319
|
+
*/
|
|
320
|
+
function getRumCorrelationCookie () {
|
|
321
|
+
const prefix = `${rumTestExecutionIdCookieName}=`
|
|
322
|
+
for (const cookie of document.cookie.split(';')) {
|
|
323
|
+
const normalizedCookie = cookie.trim()
|
|
324
|
+
if (normalizedCookie.startsWith(prefix)) {
|
|
325
|
+
return normalizedCookie.slice(prefix.length)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
123
330
|
function recordTestOptimizationStatus (task, attemptIndex = task.result?.repeatCount || 0, onlyIfNewErrors = false) {
|
|
124
331
|
const testSuite = getTestSuite(task)
|
|
125
332
|
const testName = getTestName(task)
|
|
@@ -175,7 +382,7 @@ function recordEarlyFlakeDetectionStatus (task, attemptIndex, onlyIfNewErrors) {
|
|
|
175
382
|
earlyFlakeDetectionRetriesByTask.set(task, retryCount)
|
|
176
383
|
task.repeats = retryCount
|
|
177
384
|
task.meta.__ddTestOptEfdRetries = retryCount
|
|
178
|
-
if (retryCount === 0
|
|
385
|
+
if (retryCount === 0) {
|
|
179
386
|
task.meta.__ddTestOptEfdAbortReason = 'slow'
|
|
180
387
|
}
|
|
181
388
|
}
|
|
@@ -206,6 +413,76 @@ function recordManualRepeatStatus (task, attemptIndex) {
|
|
|
206
413
|
task.meta.__ddTestOptRepeatErrorCounts[attemptIndex] = task.result?.errors?.length || 0
|
|
207
414
|
}
|
|
208
415
|
|
|
416
|
+
/**
|
|
417
|
+
* Records cumulative errors at the end of each configured retry attempt.
|
|
418
|
+
*
|
|
419
|
+
* @param {object} task
|
|
420
|
+
* @returns {void}
|
|
421
|
+
*/
|
|
422
|
+
function recordRetryErrorCount (task) {
|
|
423
|
+
const retryLimit = getRetryLimit(task)
|
|
424
|
+
if (retryLimit <= 0) return
|
|
425
|
+
|
|
426
|
+
const retryCount = task.result?.retryCount || 0
|
|
427
|
+
task.meta.__ddTestOptRetryErrorCounts ||= []
|
|
428
|
+
task.meta.__ddTestOptRetryErrorCounts[retryCount] = task.result?.errors?.length || 0
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Records the wall-clock start and elapsed time for one retry or repeat execution.
|
|
433
|
+
*
|
|
434
|
+
* @param {object} task
|
|
435
|
+
* @param {number} attemptIndex
|
|
436
|
+
* @param {number} attemptStart
|
|
437
|
+
* @returns {void}
|
|
438
|
+
*/
|
|
439
|
+
function recordTestAttemptTiming (task, attemptIndex, attemptStart) {
|
|
440
|
+
task.meta.__ddTestOptAttemptStartTimes ||= []
|
|
441
|
+
task.meta.__ddTestOptAttemptDurations ||= []
|
|
442
|
+
task.meta.__ddTestOptAttemptStartTimes[attemptIndex] = timeOrigin + attemptStart
|
|
443
|
+
task.meta.__ddTestOptAttemptDurations[attemptIndex] = now() - attemptStart
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Returns the configured retry count for numeric and object-form retry options.
|
|
448
|
+
*
|
|
449
|
+
* @param {object} task
|
|
450
|
+
* @returns {number}
|
|
451
|
+
*/
|
|
452
|
+
function getRetryLimit (task) {
|
|
453
|
+
return typeof task.retry === 'number' ? task.retry : task.retry?.count || 0
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Wraps Vitest's retry condition so final-attempt handling follows the condition's actual result.
|
|
458
|
+
*
|
|
459
|
+
* @param {object} task
|
|
460
|
+
* @returns {void}
|
|
461
|
+
*/
|
|
462
|
+
function wrapRetryCondition (task) {
|
|
463
|
+
if (typeof task.retry !== 'object' || !task.retry?.condition || getRetryLimit(task) === 0) return
|
|
464
|
+
|
|
465
|
+
const condition = task.retry.condition
|
|
466
|
+
task.retry = {
|
|
467
|
+
...task.retry,
|
|
468
|
+
condition (error) {
|
|
469
|
+
let shouldRetry = false
|
|
470
|
+
if (condition instanceof RegExp) {
|
|
471
|
+
shouldRetry = condition.test(error?.message || '')
|
|
472
|
+
} else if (typeof condition === 'function') {
|
|
473
|
+
shouldRetry = condition(error)
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
if (!shouldRetry && (task.result?.repeatCount || 0) >= (task.repeats || 0)) {
|
|
477
|
+
const attemptIndex = task.meta.__ddTestOptCurrentAttemptIndex
|
|
478
|
+
recordTestOptimizationStatus(task, attemptIndex)
|
|
479
|
+
markQuarantinedFailure(task)
|
|
480
|
+
}
|
|
481
|
+
return shouldRetry
|
|
482
|
+
},
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
209
486
|
function restoreEarlyFlakeDetectionSkippedResult (task) {
|
|
210
487
|
if (!task.meta.__ddTestOptEfdSkipCurrentAttempt) {
|
|
211
488
|
return false
|
|
@@ -236,7 +513,18 @@ function getFinalAttemptIndex (task) {
|
|
|
236
513
|
if (isEarlyFlakeDetectionTest(testSuite, testName)) {
|
|
237
514
|
return getEarlyFlakeDetectionRetryCountForTask(task)
|
|
238
515
|
}
|
|
239
|
-
|
|
516
|
+
|
|
517
|
+
const attemptIndex = task.meta.__ddTestOptCurrentAttemptIndex
|
|
518
|
+
const repeatCount = task.result?.repeatCount || 0
|
|
519
|
+
const repeatLimit = task.repeats || 0
|
|
520
|
+
const retryAttemptIndex = retryAttemptIndexByTask.get(task)?.index || 0
|
|
521
|
+
const retryLimit = getRetryLimit(task)
|
|
522
|
+
const retriesRemaining = task.result?.state === 'fail' || task.result?.state === 'run'
|
|
523
|
+
? Math.max(retryLimit - retryAttemptIndex, 0)
|
|
524
|
+
: 0
|
|
525
|
+
const repeatsRemaining = Math.max(repeatLimit - repeatCount, 0)
|
|
526
|
+
|
|
527
|
+
return attemptIndex + retriesRemaining + (repeatsRemaining * (retryLimit + 1))
|
|
240
528
|
}
|
|
241
529
|
|
|
242
530
|
function switchQuarantinedFinalFailure (task, attemptIndex) {
|
|
@@ -250,9 +538,27 @@ function switchQuarantinedFinalFailure (task, attemptIndex) {
|
|
|
250
538
|
return
|
|
251
539
|
}
|
|
252
540
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
541
|
+
if (attemptIndex < getFinalAttemptIndex(task)) {
|
|
542
|
+
return
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
markQuarantinedFailure(task)
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Converts a quarantined failure into the passing runner state expected by Vitest.
|
|
550
|
+
*
|
|
551
|
+
* @param {object} task
|
|
552
|
+
* @returns {void}
|
|
553
|
+
*/
|
|
554
|
+
function markQuarantinedFailure (task) {
|
|
555
|
+
const testSuite = getTestSuite(task)
|
|
556
|
+
const testName = getTestName(task)
|
|
557
|
+
if (
|
|
558
|
+
!quarantinedTests[testSuite]?.[testName] ||
|
|
559
|
+
attemptToFixTests[testSuite]?.[testName] ||
|
|
560
|
+
task.result?.state !== 'fail'
|
|
561
|
+
) {
|
|
256
562
|
return
|
|
257
563
|
}
|
|
258
564
|
|
|
@@ -292,7 +598,7 @@ function getPreviousErrorCount (errorCounts, repeatCount) {
|
|
|
292
598
|
|
|
293
599
|
function prepareEarlyFlakeDetectionAttempt (task, attemptIndex) {
|
|
294
600
|
if (attemptIndex === 0) {
|
|
295
|
-
earlyFlakeDetectionStartByTask.set(task,
|
|
601
|
+
earlyFlakeDetectionStartByTask.set(task, now())
|
|
296
602
|
return false
|
|
297
603
|
}
|
|
298
604
|
|
|
@@ -302,18 +608,18 @@ function prepareEarlyFlakeDetectionAttempt (task, attemptIndex) {
|
|
|
302
608
|
earlyFlakeDetectionRetriesByTask.set(task, retryCount)
|
|
303
609
|
task.repeats = retryCount
|
|
304
610
|
task.meta.__ddTestOptEfdRetries = retryCount
|
|
305
|
-
if (retryCount === 0
|
|
611
|
+
if (retryCount === 0) {
|
|
306
612
|
task.meta.__ddTestOptEfdAbortReason = 'slow'
|
|
307
613
|
}
|
|
308
614
|
}
|
|
309
615
|
|
|
310
616
|
if (attemptIndex <= retryCount) {
|
|
311
|
-
earlyFlakeDetectionStartByTask.set(task,
|
|
617
|
+
earlyFlakeDetectionStartByTask.set(task, now())
|
|
312
618
|
return false
|
|
313
619
|
}
|
|
314
620
|
|
|
315
621
|
if (!canReplaceVitestTaskFn()) {
|
|
316
|
-
earlyFlakeDetectionStartByTask.set(task,
|
|
622
|
+
earlyFlakeDetectionStartByTask.set(task, now())
|
|
317
623
|
return false
|
|
318
624
|
}
|
|
319
625
|
|
|
@@ -329,16 +635,10 @@ function prepareEarlyFlakeDetectionAttempt (task, attemptIndex) {
|
|
|
329
635
|
}
|
|
330
636
|
|
|
331
637
|
function getEarlyFlakeDetectionRetryCount (task) {
|
|
332
|
-
if (!hasEarlyFlakeDetectionSlowRetries) {
|
|
333
|
-
return earlyFlakeDetectionRetries
|
|
334
|
-
}
|
|
335
|
-
|
|
336
638
|
const executionStart = earlyFlakeDetectionStartByTask.get(task)
|
|
337
|
-
const duration = executionStart === undefined ? task.result?.duration ?? 0 :
|
|
338
|
-
for (const {
|
|
339
|
-
if (duration <
|
|
340
|
-
return earlyFlakeDetectionSlowRetries[key] ?? 0
|
|
341
|
-
}
|
|
639
|
+
const duration = executionStart === undefined ? task.result?.duration ?? 0 : now() - executionStart
|
|
640
|
+
for (const { durationLimitMs, retryCount } of earlyFlakeDetectionRetryPolicy.durationRetryCounts) {
|
|
641
|
+
if (duration < durationLimitMs) return retryCount
|
|
342
642
|
}
|
|
343
643
|
return 0
|
|
344
644
|
}
|
|
@@ -376,21 +676,10 @@ function isModifiedTest (testSuite) {
|
|
|
376
676
|
}
|
|
377
677
|
|
|
378
678
|
function getTestSuite (task) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
return normalizePath(relative(repositoryRoot, filepath))
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
function realpath (filepath) {
|
|
389
|
-
try {
|
|
390
|
-
return realpathSync(filepath)
|
|
391
|
-
} catch {
|
|
392
|
-
return filepath
|
|
393
|
-
}
|
|
679
|
+
const filepath = task.file.filepath
|
|
680
|
+
return testPropertiesByFilepath[filepath]?.testSuite ||
|
|
681
|
+
testPropertiesByFilepath[normalizePath(filepath)]?.testSuite ||
|
|
682
|
+
normalizePath(filepath)
|
|
394
683
|
}
|
|
395
684
|
|
|
396
685
|
function getTestName (task) {
|
|
@@ -423,8 +712,12 @@ function getIsNoWorkerInitActive () {
|
|
|
423
712
|
|
|
424
713
|
function getProvidedContext () {
|
|
425
714
|
try {
|
|
426
|
-
return
|
|
715
|
+
return inject('_ddVitestWorkerSetup') || {}
|
|
427
716
|
} catch {
|
|
428
|
-
|
|
717
|
+
try {
|
|
718
|
+
return globalThis.__vitest_worker__.providedContext._ddVitestWorkerSetup || {}
|
|
719
|
+
} catch {
|
|
720
|
+
return {}
|
|
721
|
+
}
|
|
429
722
|
}
|
|
430
723
|
}
|