dd-trace 6.16.0 → 6.18.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 +0 -23
- package/ci/test-optimization-validation/approval-artifacts.js +0 -3
- package/ci/test-optimization-validation/approval.js +0 -6
- package/ci/test-optimization-validation/artifact-id.js +0 -1
- package/ci/test-optimization-validation/bounded-json.js +0 -1
- package/ci/test-optimization-validation/cli.js +0 -12
- package/ci/test-optimization-validation/command-output-policy.js +0 -1
- package/ci/test-optimization-validation/command-runner.js +0 -3
- package/ci/test-optimization-validation/environment.js +0 -4
- package/ci/test-optimization-validation/executable-approval.js +0 -1
- package/ci/test-optimization-validation/executable.js +0 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/cypress.js +0 -3
- package/ci/test-optimization-validation/framework-adapters/playwright.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/vitest.js +0 -4
- package/ci/test-optimization-validation/generated-test-contract.js +0 -5
- package/ci/test-optimization-validation/generated-verifier.js +0 -1
- package/ci/test-optimization-validation/literal-environment.js +0 -1
- package/ci/test-optimization-validation/manifest-scaffold.js +0 -17
- package/ci/test-optimization-validation/manifest-schema.js +0 -21
- package/ci/test-optimization-validation/offline-fixtures.js +0 -4
- package/ci/test-optimization-validation/plan-writer.js +0 -11
- package/ci/test-optimization-validation/preflight-runner.js +0 -1
- package/ci/test-optimization-validation/redaction.js +0 -4
- package/ci/test-optimization-validation/report-writer.js +0 -16
- package/ci/test-optimization-validation/runner-command.js +0 -3
- package/ci/test-optimization-validation/runner-contract.js +0 -4
- package/ci/test-optimization-validation/safe-files.js +0 -1
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +0 -1
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +0 -1
- package/ci/test-optimization-validation/source-text.js +0 -3
- package/ci/vitest-no-worker-init-setup.mjs +41 -16
- package/index.d.ts +208 -0
- package/package.json +17 -16
- package/packages/datadog-esbuild/src/utils.js +0 -2
- package/packages/datadog-instrumentations/src/aerospike.js +28 -6
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -2
- package/packages/datadog-instrumentations/src/aws-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/console.js +97 -0
- package/packages/datadog-instrumentations/src/cucumber.js +77 -12
- package/packages/datadog-instrumentations/src/cypress-config.js +27 -38
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +6 -0
- package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -6
- package/packages/datadog-instrumentations/src/helpers/instrumentation-utils.js +0 -3
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +0 -6
- package/packages/datadog-instrumentations/src/helpers/register.js +24 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +111 -26
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +41 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -17
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +55 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +36 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/supabase.js +128 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +13 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +28 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +20 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +388 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +0 -1
- package/packages/datadog-instrumentations/src/jest.js +165 -51
- package/packages/datadog-instrumentations/src/knex.js +0 -1
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +0 -24
- package/packages/datadog-instrumentations/src/mariadb.js +0 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +0 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +25 -26
- package/packages/datadog-instrumentations/src/mocha/utils.js +119 -49
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +0 -6
- package/packages/datadog-instrumentations/src/mocha/worker.js +14 -17
- package/packages/datadog-instrumentations/src/mysql2.js +0 -2
- package/packages/datadog-instrumentations/src/openai-realtime/audio-accumulator.js +241 -0
- package/packages/datadog-instrumentations/src/openai-realtime/events.js +76 -0
- package/packages/datadog-instrumentations/src/openai-realtime/index.js +301 -0
- package/packages/datadog-instrumentations/src/openai-realtime/session.js +998 -0
- package/packages/datadog-instrumentations/src/openai-realtime/turns.js +211 -0
- package/packages/datadog-instrumentations/src/openai.js +51 -12
- package/packages/datadog-instrumentations/src/oracledb.js +9 -3
- package/packages/datadog-instrumentations/src/playwright-reporter.js +6 -20
- package/packages/datadog-instrumentations/src/playwright.js +280 -56
- package/packages/datadog-instrumentations/src/{azure-cosmos.js → postgres.js} +1 -1
- package/packages/datadog-instrumentations/src/router.js +0 -2
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +0 -2
- package/packages/datadog-instrumentations/src/sequelize.js +0 -1
- package/packages/datadog-instrumentations/src/supabase.js +15 -0
- package/packages/datadog-instrumentations/src/undici.js +7 -3
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +18 -18
- package/packages/datadog-instrumentations/src/vitest-main.js +121 -30
- package/packages/datadog-instrumentations/src/vitest-util.js +7 -1
- package/packages/datadog-instrumentations/src/vitest-worker.js +49 -13
- package/packages/datadog-instrumentations/src/webdriverio.js +44 -47
- package/packages/datadog-instrumentations/src/ws.js +41 -2
- package/packages/datadog-plugin-ai/src/utils.js +0 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +0 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +0 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +0 -1
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +0 -1
- package/packages/datadog-plugin-cucumber/src/index.js +9 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +211 -85
- package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
- package/packages/datadog-plugin-cypress/src/index.js +3 -1
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +0 -4
- package/packages/datadog-plugin-cypress/src/support.js +52 -7
- package/packages/datadog-plugin-graphql/src/resolve-error.js +1 -2
- package/packages/datadog-plugin-graphql/src/utils.js +0 -5
- package/packages/datadog-plugin-jest/src/index.js +12 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
- package/packages/datadog-plugin-mocha/src/index.js +38 -11
- package/packages/datadog-plugin-mongodb-core/src/query.js +0 -1
- package/packages/datadog-plugin-openai/src/index.js +16 -1
- package/packages/datadog-plugin-openai/src/realtime.js +144 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +0 -4
- package/packages/datadog-plugin-openai-agents/src/util.js +0 -1
- package/packages/datadog-plugin-playwright/src/index.js +81 -9
- package/packages/datadog-plugin-postgres/src/index.js +167 -0
- package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +0 -1
- package/packages/datadog-plugin-redis/src/index.js +15 -1
- package/packages/datadog-plugin-supabase/src/error.js +18 -0
- package/packages/datadog-plugin-supabase/src/index.js +21 -0
- package/packages/datadog-plugin-supabase/src/supabase-auth-js-gotrueclient-getuser.js +69 -0
- package/packages/datadog-plugin-supabase/src/supabase-functions-js-functionsclient-invoke.js +70 -0
- package/packages/datadog-plugin-supabase/src/supabase-postgrest-js-postgrestbuilder-then.js +122 -0
- package/packages/datadog-plugin-supabase/src/supabase-realtime-js-realtimechannel-send.js +66 -0
- package/packages/datadog-plugin-supabase/src/supabase-storage-js-handle-request.js +93 -0
- package/packages/datadog-plugin-supabase/src/url.js +17 -0
- package/packages/datadog-plugin-vitest/src/index.js +9 -0
- package/packages/datadog-plugin-ws/src/producer.js +1 -1
- package/packages/datadog-plugin-ws/src/util.js +0 -4
- package/packages/datadog-shimmer/src/shimmer.js +14 -10
- package/packages/datadog-turbopack/index.js +4 -7
- package/packages/datadog-turbopack/src/loader.js +6 -18
- package/packages/datadog-webpack/src/loader.js +0 -1
- package/packages/dd-trace/src/agent/info.js +5 -4
- package/packages/dd-trace/src/aiguard/client.js +2 -3
- package/packages/dd-trace/src/aiguard/evaluation.js +6 -12
- package/packages/dd-trace/src/aiguard/index.js +2 -2
- package/packages/dd-trace/src/aiguard/integrations/index.js +1 -1
- package/packages/dd-trace/src/aiguard/integrations/openai.js +81 -7
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +0 -2
- package/packages/dd-trace/src/aiguard/messages/openai.js +64 -1
- package/packages/dd-trace/src/aiguard/messages/utils.js +0 -1
- package/packages/dd-trace/src/aiguard/redaction.js +0 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/activation.js +1 -1
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +0 -5
- package/packages/dd-trace/src/appsec/api_security/sampler.js +0 -4
- package/packages/dd-trace/src/appsec/blocking/index.js +3 -3
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -4
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +5 -5
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +8 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +4 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -7
- package/packages/dd-trace/src/appsec/index.js +2 -2
- package/packages/dd-trace/src/appsec/lambda.js +71 -2
- package/packages/dd-trace/src/appsec/rasp/utils.js +5 -1
- package/packages/dd-trace/src/appsec/remote_config.js +8 -6
- package/packages/dd-trace/src/appsec/reporter.js +10 -6
- package/packages/dd-trace/src/appsec/rule_manager.js +3 -3
- package/packages/dd-trace/src/appsec/sdk/track_event.js +0 -2
- package/packages/dd-trace/src/appsec/waf/index.js +2 -2
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +8 -5
- package/packages/dd-trace/src/carrier.js +0 -5
- package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +104 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +0 -2
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +34 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +0 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +0 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +37 -15
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -3
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +0 -11
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +0 -6
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -2
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +0 -5
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +0 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +13 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +0 -1
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +0 -2
- package/packages/dd-trace/src/ci-visibility/test-video.js +0 -1
- package/packages/dd-trace/src/config/defaults.js +3 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +88 -82
- package/packages/dd-trace/src/config/helper.js +0 -1
- package/packages/dd-trace/src/config/index.js +31 -30
- package/packages/dd-trace/src/config/parsers.js +34 -6
- package/packages/dd-trace/src/config/remote_config.js +25 -109
- package/packages/dd-trace/src/config/supported-configurations.json +150 -10
- package/packages/dd-trace/src/datastreams/encoding.js +0 -1
- package/packages/dd-trace/src/datastreams/pathway.js +0 -1
- package/packages/dd-trace/src/debugger/constants.js +10 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +62 -10
- package/packages/dd-trace/src/debugger/devtools_client/config.js +4 -1
- package/packages/dd-trace/src/debugger/devtools_client/guardrail-metrics.js +15 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +103 -27
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +50 -7
- package/packages/dd-trace/src/debugger/devtools_client/log.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +21 -8
- package/packages/dd-trace/src/debugger/devtools_client/send.js +41 -15
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +53 -13
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +118 -71
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +5 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +0 -3
- package/packages/dd-trace/src/debugger/devtools_client/status.js +21 -7
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
- package/packages/dd-trace/src/debugger/index.js +51 -3
- package/packages/dd-trace/src/debugger/inspect-segment.js +0 -3
- package/packages/dd-trace/src/debugger/probe_sampler.js +133 -9
- package/packages/dd-trace/src/debugger/probe_sampler_constants.js +31 -1
- package/packages/dd-trace/src/dogstatsd.js +0 -23
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +0 -3
- package/packages/dd-trace/src/encode/0.4.js +0 -7
- package/packages/dd-trace/src/encode/0.5.js +0 -2
- package/packages/dd-trace/src/encode/tags-processors.js +0 -1
- package/packages/dd-trace/src/evp_proxy/constants.js +2 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +17 -13
- package/packages/dd-trace/src/evp_proxy/discovery.js +14 -11
- package/packages/dd-trace/src/evp_proxy/path.js +21 -9
- package/packages/dd-trace/src/exporters/agent/writer.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/intake.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/writer.js +0 -3
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +0 -6
- package/packages/dd-trace/src/exporters/common/request.js +1 -0
- package/packages/dd-trace/src/exporters/common/url.js +33 -4
- package/packages/dd-trace/src/exporters/common/writer.js +0 -2
- package/packages/dd-trace/src/id.js +0 -11
- package/packages/dd-trace/src/llmobs/audio-codec.js +192 -0
- package/packages/dd-trace/src/llmobs/audio-utils.js +121 -0
- package/packages/dd-trace/src/llmobs/constants/audio.js +35 -0
- package/packages/dd-trace/src/llmobs/constants/prompts.js +14 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +17 -0
- package/packages/dd-trace/src/llmobs/eval-metric.js +0 -6
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +0 -4
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +0 -3
- package/packages/dd-trace/src/llmobs/experiments/index.js +7 -6
- package/packages/dd-trace/src/llmobs/experiments/util.js +1 -11
- package/packages/dd-trace/src/llmobs/index.js +1 -3
- package/packages/dd-trace/src/llmobs/noop.js +10 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +0 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +4 -6
- package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +285 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +16 -3
- package/packages/dd-trace/src/llmobs/prompts/cache.js +272 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +647 -0
- package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +158 -0
- package/packages/dd-trace/src/llmobs/sdk.js +21 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +81 -2
- package/packages/dd-trace/src/llmobs/tagger.js +39 -11
- package/packages/dd-trace/src/llmobs/telemetry.js +36 -4
- package/packages/dd-trace/src/llmobs/util.js +0 -34
- package/packages/dd-trace/src/llmobs/writers/base.js +0 -1
- package/packages/dd-trace/src/llmobs/writers/util.js +1 -2
- package/packages/dd-trace/src/log/channels.js +3 -0
- package/packages/dd-trace/src/log/index.js +23 -5
- package/packages/dd-trace/src/log-submission/log-submission-plugin.js +74 -6
- package/packages/dd-trace/src/msgpack/chunk.js +0 -1
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +0 -12
- package/packages/dd-trace/src/openfeature/configuration_source.js +4 -1
- package/packages/dd-trace/src/openfeature/encoding.js +0 -2
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -3
- package/packages/dd-trace/src/openfeature/index.js +6 -6
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/span-enrichment.js +0 -4
- package/packages/dd-trace/src/openfeature/writers/base.js +90 -23
- package/packages/dd-trace/src/openfeature/writers/exposures.js +4 -5
- package/packages/dd-trace/src/openfeature/writers/util.js +104 -37
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +0 -2
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -14
- package/packages/dd-trace/src/opentelemetry/metrics/time.js +0 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +30 -13
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +0 -1
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +0 -3
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -6
- package/packages/dd-trace/src/opentracing/span_context.js +0 -1
- package/packages/dd-trace/src/opentracing/tracer.js +3 -3
- package/packages/dd-trace/src/otel-thread-ctx.js +38 -11
- package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
- package/packages/dd-trace/src/plugin_manager.js +27 -8
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -2
- package/packages/dd-trace/src/plugins/database.js +2 -6
- package/packages/dd-trace/src/plugins/index.js +7 -0
- package/packages/dd-trace/src/plugins/plugin.js +0 -4
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/git.js +1 -3
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +0 -1
- package/packages/dd-trace/src/plugins/util/llm.js +0 -2
- package/packages/dd-trace/src/plugins/util/status-validator.js +0 -1
- package/packages/dd-trace/src/plugins/util/test.js +26 -20
- package/packages/dd-trace/src/plugins/util/url.js +0 -5
- package/packages/dd-trace/src/priority_sampler.js +0 -6
- package/packages/dd-trace/src/process-tags/index.js +0 -1
- package/packages/dd-trace/src/profiler.js +132 -35
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +0 -1
- package/packages/dd-trace/src/profiling/profiler.js +101 -41
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +29 -15
- package/packages/dd-trace/src/propagation-hash/index.js +0 -1
- package/packages/dd-trace/src/proxy.js +23 -47
- package/packages/dd-trace/src/random_sampler.js +0 -4
- package/packages/dd-trace/src/rate_limiter.js +0 -4
- package/packages/dd-trace/src/remote_config/capabilities.js +1 -9
- package/packages/dd-trace/src/remote_config/index.js +0 -1
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +0 -3
- package/packages/dd-trace/src/sampler.js +0 -4
- package/packages/dd-trace/src/sampling_rule.js +0 -7
- package/packages/dd-trace/src/serverless/vercel.js +0 -1
- package/packages/dd-trace/src/serverless.js +0 -1
- package/packages/dd-trace/src/service-naming/index.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +7 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +5 -0
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/span_sampler.js +0 -1
- package/packages/dd-trace/src/standalone/product.js +2 -2
- package/packages/dd-trace/src/standalone/tracesource.js +0 -1
- package/packages/dd-trace/src/startup-log.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +0 -8
- package/packages/dd-trace/src/telemetry/logs/index.js +16 -5
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +16 -6
- package/packages/dd-trace/src/telemetry/metrics.js +0 -2
- package/packages/dd-trace/src/telemetry/send-data.js +2 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +4 -1
- package/packages/dd-trace/src/tracer.js +5 -4
- package/packages/dd-trace/src/util.js +13 -1
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- package/packages/datadog-instrumentations/src/bullmq.js +0 -11
- package/packages/datadog-instrumentations/src/langchain.js +0 -7
- package/packages/datadog-instrumentations/src/langgraph.js +0 -7
- package/packages/datadog-instrumentations/src/mercurius.js +0 -11
|
@@ -36,7 +36,6 @@ function isFastSlash (layer, matchers) {
|
|
|
36
36
|
* @param {{ handle: Function, name?: string, path?: string,
|
|
37
37
|
* regexp?: { fast_star?: boolean, fast_slash?: boolean } }} layer
|
|
38
38
|
* @param {Array<{ path?: string, regex?: RegExp }> & { hasStarPath?: boolean, hasSlashPath?: boolean }} matchers
|
|
39
|
-
* @returns {void}
|
|
40
39
|
*/
|
|
41
40
|
function annotateLayer (layer, matchers) {
|
|
42
41
|
const handle = layer.handle
|
|
@@ -382,7 +381,6 @@ function createLayerDispatchWrappers (name) {
|
|
|
382
381
|
|
|
383
382
|
/**
|
|
384
383
|
* @param {{ handle_request?: unknown, handleRequest?: unknown }} layer
|
|
385
|
-
* @returns {boolean}
|
|
386
384
|
*/
|
|
387
385
|
function hasLayerDispatch (layer) {
|
|
388
386
|
return typeof layer.handle_request === 'function' || typeof layer.handleRequest === 'function'
|
|
@@ -16,7 +16,6 @@ function detectRum () {
|
|
|
16
16
|
return { isRumInstrumented, isRumActive, rumSamplingRate }
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
/** @returns {boolean} */
|
|
20
19
|
function stopRumSession () {
|
|
21
20
|
if (window.DD_RUM && window.DD_RUM.stopSession) {
|
|
22
21
|
window.DD_RUM.stopSession()
|
|
@@ -25,7 +24,6 @@ function stopRumSession () {
|
|
|
25
24
|
return false
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
/** @returns {boolean} */
|
|
29
27
|
function stopRumSessionAndReportActivity () {
|
|
30
28
|
if (window.DD_RUM && window.DD_RUM.stopSession) {
|
|
31
29
|
const isRumActive = window.DD_RUM.getInternalContext
|
|
@@ -95,7 +95,6 @@ addHook({ name: 'sequelize', versions: ['>=4'], file: 'lib/transaction.js' }, Tr
|
|
|
95
95
|
/**
|
|
96
96
|
* @param {{ pool: SequelizePool & { read?: SequelizePool, write?: SequelizePool } }} manager
|
|
97
97
|
* @param {[{ type?: string, useMaster?: boolean }?]} args
|
|
98
|
-
* @returns {boolean}
|
|
99
98
|
*/
|
|
100
99
|
function sequelizeHasIdleConnection (manager, args) {
|
|
101
100
|
const pool = manager.pool
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { addHook, getHooks } = require('./helpers/instrument')
|
|
4
|
+
|
|
5
|
+
addHook({ name: '@supabase/supabase-js', versions: ['>=2.112.2'] }, exports => exports)
|
|
6
|
+
|
|
7
|
+
for (const hook of getHooks([
|
|
8
|
+
'@supabase/auth-js',
|
|
9
|
+
'@supabase/storage-js',
|
|
10
|
+
'@supabase/realtime-js',
|
|
11
|
+
'@supabase/functions-js',
|
|
12
|
+
'@supabase/postgrest-js',
|
|
13
|
+
]).values()) {
|
|
14
|
+
addHook(hook, exports => exports)
|
|
15
|
+
}
|
|
@@ -45,9 +45,13 @@ function wrapRequestUpgrade (Request) {
|
|
|
45
45
|
const method = Request.prototype[methodName]
|
|
46
46
|
|
|
47
47
|
// Orchestrion cannot leave fixed source byte-for-byte untouched after a conditional AST match.
|
|
48
|
-
if (typeof method !== 'function' ||
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
if (typeof method !== 'function' || !requestSource.includes('channels.trailers.publish')) {
|
|
49
|
+
return Request
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const methodSource = Function.prototype.toString.call(method)
|
|
53
|
+
// Undici 6.29 delegates native upgrade completion to a private helper.
|
|
54
|
+
if (methodSource.includes('channels.trailers.publish') || methodSource.includes('#publishUpgradeTrailers')) {
|
|
51
55
|
return Request
|
|
52
56
|
}
|
|
53
57
|
|
|
@@ -4,7 +4,8 @@ const path = require('node:path')
|
|
|
4
4
|
|
|
5
5
|
const satisfies = require('../../../vendor/dist/semifies')
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const { getDynamicAtrRetryCount } = require('../../dd-trace/src/ci-visibility/dynamic-atr-retries')
|
|
8
|
+
const { EMPTY_EFD_RETRY_POLICY, hasEfdRetries } = require('../../dd-trace/src/ci-visibility/efd-retry-policy')
|
|
8
9
|
const { RUM_TEST_EXECUTION_ID_COOKIE_NAME } = require('../../dd-trace/src/ci-visibility/rum')
|
|
9
10
|
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
10
11
|
const log = require('../../dd-trace/src/log')
|
|
@@ -94,7 +95,6 @@ function noop () {}
|
|
|
94
95
|
* Removes Vite and Vitest runtime query parameters from browser error URLs.
|
|
95
96
|
*
|
|
96
97
|
* @param {string} url
|
|
97
|
-
* @returns {string}
|
|
98
98
|
*/
|
|
99
99
|
function removeVitestBrowserUrlMetadata (url) {
|
|
100
100
|
const locationMatch = url.match(VITEST_BROWSER_STACK_LOCATION_RE)
|
|
@@ -129,7 +129,6 @@ function removeVitestBrowserUrlMetadata (url) {
|
|
|
129
129
|
* Removes Vite and Vitest runtime URL metadata from browser error text.
|
|
130
130
|
*
|
|
131
131
|
* @param {string} value
|
|
132
|
-
* @returns {string}
|
|
133
132
|
*/
|
|
134
133
|
function normalizeVitestBrowserErrorText (value) {
|
|
135
134
|
return value.replaceAll(VITEST_BROWSER_URL_RE, removeVitestBrowserUrlMetadata)
|
|
@@ -139,7 +138,6 @@ function normalizeVitestBrowserErrorText (value) {
|
|
|
139
138
|
* Removes the ephemeral Vite server origin in addition to its runtime query parameters.
|
|
140
139
|
*
|
|
141
140
|
* @param {string} url
|
|
142
|
-
* @returns {string}
|
|
143
141
|
*/
|
|
144
142
|
function normalizeVitestBrowserStackUrl (url) {
|
|
145
143
|
const normalizedUrl = removeVitestBrowserUrlMetadata(url)
|
|
@@ -152,7 +150,6 @@ function normalizeVitestBrowserStackUrl (url) {
|
|
|
152
150
|
* Normalizes browser URLs in a stack when Vitest does not provide parsed frames.
|
|
153
151
|
*
|
|
154
152
|
* @param {string} value
|
|
155
|
-
* @returns {string}
|
|
156
153
|
*/
|
|
157
154
|
function normalizeVitestBrowserStackText (value) {
|
|
158
155
|
return value.replaceAll(VITEST_BROWSER_URL_RE, normalizeVitestBrowserStackUrl)
|
|
@@ -330,7 +327,6 @@ function isNoWorkerInitPool (pool, isVitestWorkerPool) {
|
|
|
330
327
|
|
|
331
328
|
/**
|
|
332
329
|
* @param {object} state
|
|
333
|
-
* @returns {boolean}
|
|
334
330
|
*/
|
|
335
331
|
function isEarlyFlakeDetectionActive (state) {
|
|
336
332
|
return state.isEarlyFlakeDetectionEnabled &&
|
|
@@ -354,7 +350,20 @@ function configure (ctx, frameworkVersion, testSpecifications, setupData, option
|
|
|
354
350
|
testManagementTestsBySuite,
|
|
355
351
|
testPropertiesByFilepath,
|
|
356
352
|
testSessionConfiguration,
|
|
353
|
+
flakyTestRetriesConfiguration,
|
|
357
354
|
} = setupData
|
|
355
|
+
const { earlyFlakeDetectionRetryPolicy, dynamicAtrBuckets } = state
|
|
356
|
+
|
|
357
|
+
// Resolve the shared policy in Node; Browser Mode receives only serializable duration/count pairs.
|
|
358
|
+
const dynamicAtrRetryPolicy = state.isDynamicAtrEnabled
|
|
359
|
+
? [
|
|
360
|
+
...EMPTY_EFD_RETRY_POLICY.durationRetryCounts.map(({ durationLimitMs }) => ({
|
|
361
|
+
durationLimitMs,
|
|
362
|
+
retryCount: getDynamicAtrRetryCount(durationLimitMs, earlyFlakeDetectionRetryPolicy, dynamicAtrBuckets),
|
|
363
|
+
})),
|
|
364
|
+
{ retryCount: getDynamicAtrRetryCount(Infinity, earlyFlakeDetectionRetryPolicy, dynamicAtrBuckets) },
|
|
365
|
+
]
|
|
366
|
+
: undefined
|
|
358
367
|
|
|
359
368
|
setProvidedContext(ctx, {
|
|
360
369
|
_ddVitestWorkerSetup: {
|
|
@@ -366,6 +375,8 @@ function configure (ctx, frameworkVersion, testSpecifications, setupData, option
|
|
|
366
375
|
efdSuiteAdmissionBrowserCommand: VITEST_BROWSER_EFD_SUITE_ADMISSION_COMMAND,
|
|
367
376
|
isEfdSuiteAdmissionEnabled: state.isEfdSuiteAdmissionEnabled,
|
|
368
377
|
isEarlyFlakeDetectionEnabled: isEarlyFlakeDetectionActive(state),
|
|
378
|
+
dynamicAtrRetryPolicy,
|
|
379
|
+
flakyTestRetriesConfiguration,
|
|
369
380
|
isRumCorrelationEnabled: !canRaceRumCorrelation(ctx, testSpecifications),
|
|
370
381
|
knownTests: knownTestsBySuite || {},
|
|
371
382
|
modifiedFiles: modifiedFiles || {},
|
|
@@ -456,7 +467,6 @@ function addSetupFileToVitestConfigs (ctx, setupFile, testSpecifications) {
|
|
|
456
467
|
* @param {{
|
|
457
468
|
* resolve?: { dedupe?: string[] }
|
|
458
469
|
* }} viteConfig
|
|
459
|
-
* @returns {void}
|
|
460
470
|
*/
|
|
461
471
|
function configureVitestBrowserSetupFile (viteConfig) {
|
|
462
472
|
viteConfig.resolve ||= {}
|
|
@@ -473,7 +483,6 @@ function configureVitestBrowserSetupFile (viteConfig) {
|
|
|
473
483
|
* @param {unknown} _context
|
|
474
484
|
* @param {string} testSuite
|
|
475
485
|
* @param {unknown} hasNewTest
|
|
476
|
-
* @returns {boolean}
|
|
477
486
|
*/
|
|
478
487
|
function handleBrowserEfdSuiteAdmission (_context, testSuite, hasNewTest) {
|
|
479
488
|
return reserveEarlyFlakeDetectionSuite?.(testSuite, hasNewTest === true) === true
|
|
@@ -483,7 +492,6 @@ function handleBrowserEfdSuiteAdmission (_context, testSuite, hasNewTest) {
|
|
|
483
492
|
* Allows Vite to serve the Datadog setup file after its default workspace detection has run.
|
|
484
493
|
*
|
|
485
494
|
* @param {{ server?: { fs?: { allow?: string[] } } }} viteConfig
|
|
486
|
-
* @returns {void}
|
|
487
495
|
*/
|
|
488
496
|
function allowVitestBrowserSetupFile (viteConfig) {
|
|
489
497
|
const allow = viteConfig.server?.fs?.allow
|
|
@@ -505,7 +513,6 @@ function allowVitestBrowserSetupFile (viteConfig) {
|
|
|
505
513
|
* Installs the Vite access plugin on each parent project that owns a Browser Mode server.
|
|
506
514
|
*
|
|
507
515
|
* @param {object[]|undefined} testSpecifications
|
|
508
|
-
* @returns {void}
|
|
509
516
|
*/
|
|
510
517
|
function addVitestBrowserSetupFileAccess (testSpecifications) {
|
|
511
518
|
if (!Array.isArray(testSpecifications)) return
|
|
@@ -545,7 +552,6 @@ function addVitestBrowserRuntimeCommand (project) {
|
|
|
545
552
|
* Adds the private EFD admission command to a Vitest Browser Mode configuration.
|
|
546
553
|
*
|
|
547
554
|
* @param {object|undefined} config
|
|
548
|
-
* @returns {void}
|
|
549
555
|
*/
|
|
550
556
|
function addVitestBrowserCommand (config) {
|
|
551
557
|
const browserConfig = config?.browser
|
|
@@ -927,6 +933,7 @@ function createMainProcessReporter (reporterState) {
|
|
|
927
933
|
const { flakyTestRetriesConfiguration } = testOptimizationData
|
|
928
934
|
const isFlakyTestRetries = !!flakyTestRetriesConfiguration && isFlakyTestRetriesEnabledForTask({
|
|
929
935
|
isFlakyTestRetriesEnabled: state.isFlakyTestRetriesEnabled,
|
|
936
|
+
isDynamicAtrEnabled: state.isDynamicAtrEnabled,
|
|
930
937
|
flakyTestRetriesIncludesUnnamedProject: flakyTestRetriesConfiguration.includesUnnamedProject,
|
|
931
938
|
flakyTestRetriesProjectNames: flakyTestRetriesConfiguration.projectNames,
|
|
932
939
|
}, task)
|
|
@@ -1169,7 +1176,6 @@ function getRepeatedTestReport (task, testName, testSuiteAbsolutePath, testPrope
|
|
|
1169
1176
|
* @param {'attempt_to_fix'|'early_flake_detection'|'external'} type
|
|
1170
1177
|
* @param {string[]} statuses
|
|
1171
1178
|
* @param {boolean} isFinalAttempt
|
|
1172
|
-
* @returns {boolean}
|
|
1173
1179
|
*/
|
|
1174
1180
|
function hasFailedAllManagedRetries (task, testProperties, type, statuses, isFinalAttempt) {
|
|
1175
1181
|
if (!isFinalAttempt || statuses.length === 0 || !statuses.every(status => status === 'fail')) {
|
|
@@ -1207,7 +1213,6 @@ function getEarlyFlakeDetectionFinalStatus (statuses, testProperties) {
|
|
|
1207
1213
|
*
|
|
1208
1214
|
* @param {string} status
|
|
1209
1215
|
* @param {{ isDisabled?: boolean, isQuarantined?: boolean }} testProperties
|
|
1210
|
-
* @returns {string}
|
|
1211
1216
|
*/
|
|
1212
1217
|
function getExternalFinalStatus (status, testProperties) {
|
|
1213
1218
|
return testProperties.isDisabled || testProperties.isQuarantined ? 'skip' : status
|
|
@@ -1692,7 +1697,6 @@ function getEffectiveTestSpecificationPool (testSpecification, defaultPool) {
|
|
|
1692
1697
|
* Resolves Vitest's default worker pool when the user did not configure one.
|
|
1693
1698
|
*
|
|
1694
1699
|
* @param {{ pool?: string }|undefined} config
|
|
1695
|
-
* @returns {string}
|
|
1696
1700
|
*/
|
|
1697
1701
|
function getEffectiveConfigPool (config) {
|
|
1698
1702
|
return config?.pool || VITEST_DEFAULT_POOL
|
|
@@ -1747,7 +1751,6 @@ function normalizeProjectName (name) {
|
|
|
1747
1751
|
* Returns whether a Vitest specification runs in Browser Mode.
|
|
1748
1752
|
*
|
|
1749
1753
|
* @param {object} testSpecification
|
|
1750
|
-
* @returns {boolean}
|
|
1751
1754
|
*/
|
|
1752
1755
|
function isBrowserTestSpecification (testSpecification) {
|
|
1753
1756
|
return getTestSpecificationPool(testSpecification) === 'browser' ||
|
|
@@ -1758,7 +1761,6 @@ function isBrowserTestSpecification (testSpecification) {
|
|
|
1758
1761
|
* Returns whether a Vitest project has Browser Mode enabled.
|
|
1759
1762
|
*
|
|
1760
1763
|
* @param {object|undefined} project
|
|
1761
|
-
* @returns {boolean}
|
|
1762
1764
|
*/
|
|
1763
1765
|
function isBrowserProject (project) {
|
|
1764
1766
|
try {
|
|
@@ -1771,7 +1773,6 @@ function isBrowserProject (project) {
|
|
|
1771
1773
|
* Returns whether Vitest can overlap tests or their setup and teardown.
|
|
1772
1774
|
*
|
|
1773
1775
|
* @param {object|undefined} config
|
|
1774
|
-
* @returns {boolean}
|
|
1775
1776
|
*/
|
|
1776
1777
|
function hasConcurrentTestExecution (config) {
|
|
1777
1778
|
const sequence = config?.sequence
|
|
@@ -1785,7 +1786,6 @@ function hasConcurrentTestExecution (config) {
|
|
|
1785
1786
|
*
|
|
1786
1787
|
* @param {object} ctx
|
|
1787
1788
|
* @param {object[]|undefined} testSpecifications
|
|
1788
|
-
* @returns {boolean}
|
|
1789
1789
|
*/
|
|
1790
1790
|
function canRaceRumCorrelation (ctx, testSpecifications) {
|
|
1791
1791
|
if (!Array.isArray(testSpecifications)) {
|
|
@@ -65,12 +65,17 @@ const workerProcesses = new WeakSet()
|
|
|
65
65
|
const mainProcessSetupStates = new WeakMap()
|
|
66
66
|
const coverageWrappedProviders = new WeakSet()
|
|
67
67
|
const finishWrappedContexts = new WeakSet()
|
|
68
|
+
const finishedSessionContexts = new WeakSet()
|
|
69
|
+
const sessionWrappedPrototypes = new WeakSet()
|
|
70
|
+
const emptyShardContexts = new WeakSet()
|
|
68
71
|
const runFilesWrappedPrototypes = new WeakSet()
|
|
69
72
|
const activeRunFilesContexts = new WeakSet()
|
|
70
73
|
const runErrorsByContext = new WeakMap()
|
|
71
74
|
const typecheckPoolWorkerRequests = new WeakMap()
|
|
72
75
|
let isFlakyTestRetriesEnabled = false
|
|
73
76
|
let flakyTestRetriesCount = 0
|
|
77
|
+
let isDynamicAtrEnabled = false
|
|
78
|
+
let dynamicAtrBuckets
|
|
74
79
|
let isEarlyFlakeDetectionEnabled = false
|
|
75
80
|
let earlyFlakeDetectionRetryPolicy = EMPTY_EFD_RETRY_POLICY
|
|
76
81
|
let earlyFlakeDetectionFaultyThreshold = 0
|
|
@@ -161,16 +166,6 @@ function getThreadsPoolWorkerExport (vitestPackage) {
|
|
|
161
166
|
return findExportByName(vitestPackage, 'ThreadsPoolWorker')
|
|
162
167
|
}
|
|
163
168
|
|
|
164
|
-
function getSessionStatus (state) {
|
|
165
|
-
if (state.getCountOfFailedTests() > 0) {
|
|
166
|
-
return 'fail'
|
|
167
|
-
}
|
|
168
|
-
if (state.pathsSet.size === 0) {
|
|
169
|
-
return 'skip'
|
|
170
|
-
}
|
|
171
|
-
return 'pass'
|
|
172
|
-
}
|
|
173
|
-
|
|
174
169
|
function getTestFilepathsFromSpecifications (testSpecifications) {
|
|
175
170
|
if (!Array.isArray(testSpecifications) || !testSpecifications.length) {
|
|
176
171
|
return
|
|
@@ -232,7 +227,6 @@ function getTestFilepaths (ctx, testSpecifications) {
|
|
|
232
227
|
*
|
|
233
228
|
* @param {string} testFilepath
|
|
234
229
|
* @param {string} repositoryRoot
|
|
235
|
-
* @returns {string}
|
|
236
230
|
*/
|
|
237
231
|
function getNormalizedTestSuitePath (testFilepath, repositoryRoot) {
|
|
238
232
|
const testSuiteAbsolutePath = path.isAbsolute(testFilepath) ? testFilepath : path.join(repositoryRoot, testFilepath)
|
|
@@ -242,7 +236,6 @@ function getNormalizedTestSuitePath (testFilepath, repositoryRoot) {
|
|
|
242
236
|
/**
|
|
243
237
|
* Resets suite-level EFD admission state between Vitest runs.
|
|
244
238
|
*
|
|
245
|
-
* @returns {void}
|
|
246
239
|
*/
|
|
247
240
|
function resetEfdSuiteTracker () {
|
|
248
241
|
activeNoWorkerInitState = undefined
|
|
@@ -255,7 +248,6 @@ function resetEfdSuiteTracker () {
|
|
|
255
248
|
* Returns whether a Vitest pool has a transport for runtime EFD suite admission.
|
|
256
249
|
*
|
|
257
250
|
* @param {string|undefined} pool
|
|
258
|
-
* @returns {boolean}
|
|
259
251
|
*/
|
|
260
252
|
function isEfdSuiteAdmissionPool (pool) {
|
|
261
253
|
return pool === undefined || pool === 'forks' || pool === 'threads' || pool === 'browser'
|
|
@@ -267,7 +259,6 @@ function isEfdSuiteAdmissionPool (pool) {
|
|
|
267
259
|
* @param {string} frameworkVersion
|
|
268
260
|
* @param {object[]|undefined} testSpecifications
|
|
269
261
|
* @param {object} ctx
|
|
270
|
-
* @returns {boolean}
|
|
271
262
|
*/
|
|
272
263
|
function supportsEfdSuiteAdmission (frameworkVersion, testSpecifications, ctx) {
|
|
273
264
|
if (!satisfies(frameworkVersion, '>=4.0.0')) return false
|
|
@@ -288,7 +279,6 @@ function supportsEfdSuiteAdmission (frameworkVersion, testSpecifications, ctx) {
|
|
|
288
279
|
*
|
|
289
280
|
* @param {string[]} testFilepaths
|
|
290
281
|
* @param {string} repositoryRoot
|
|
291
|
-
* @returns {void}
|
|
292
282
|
*/
|
|
293
283
|
function configureEfdSuiteTracker (testFilepaths, repositoryRoot) {
|
|
294
284
|
const testSuites = new Set()
|
|
@@ -308,7 +298,6 @@ function configureEfdSuiteTracker (testFilepaths, repositoryRoot) {
|
|
|
308
298
|
*
|
|
309
299
|
* @param {string} testSuite
|
|
310
300
|
* @param {boolean} hasNewTest
|
|
311
|
-
* @returns {boolean}
|
|
312
301
|
*/
|
|
313
302
|
function reserveEarlyFlakeDetectionSuite (testSuite, hasNewTest) {
|
|
314
303
|
if (!isEfdSuiteAdmissionEnabled || typeof testSuite !== 'string') return false
|
|
@@ -651,6 +640,8 @@ function wrapSessionFinish (ctx) {
|
|
|
651
640
|
function resetLibraryConfig () {
|
|
652
641
|
isFlakyTestRetriesEnabled = false
|
|
653
642
|
flakyTestRetriesCount = 0
|
|
643
|
+
isDynamicAtrEnabled = false
|
|
644
|
+
dynamicAtrBuckets = undefined
|
|
654
645
|
isEarlyFlakeDetectionEnabled = false
|
|
655
646
|
earlyFlakeDetectionRetryPolicy = EMPTY_EFD_RETRY_POLICY
|
|
656
647
|
earlyFlakeDetectionFaultyThreshold = 0
|
|
@@ -667,6 +658,8 @@ function resetLibraryConfig () {
|
|
|
667
658
|
function applyLibraryConfig (libraryConfig) {
|
|
668
659
|
isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
|
|
669
660
|
flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
|
|
661
|
+
isDynamicAtrEnabled = libraryConfig.isDynamicAtrEnabled
|
|
662
|
+
dynamicAtrBuckets = libraryConfig.dynamicAtrBuckets
|
|
670
663
|
isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
|
|
671
664
|
earlyFlakeDetectionRetryPolicy = libraryConfig.earlyFlakeDetectionRetryPolicy ?? EMPTY_EFD_RETRY_POLICY
|
|
672
665
|
earlyFlakeDetectionFaultyThreshold = libraryConfig.earlyFlakeDetectionFaultyThreshold ?? 0
|
|
@@ -688,6 +681,8 @@ function resetMainProcessProvidedContext (ctx) {
|
|
|
688
681
|
_ddIsEfdSuiteAdmissionEnabled: false,
|
|
689
682
|
_ddIsFlakyTestRetriesEnabled: false,
|
|
690
683
|
_ddFlakyTestRetriesCount: 0,
|
|
684
|
+
_ddIsDynamicAtrEnabled: false,
|
|
685
|
+
_ddDynamicAtrBuckets: undefined,
|
|
691
686
|
_ddFlakyTestRetriesIncludesUnnamedProject: false,
|
|
692
687
|
_ddFlakyTestRetriesProjectNames: undefined,
|
|
693
688
|
_ddIsImpactedTestsEnabled: false,
|
|
@@ -766,6 +761,8 @@ async function runMainProcessSetup (
|
|
|
766
761
|
resetLibraryConfig()
|
|
767
762
|
} else {
|
|
768
763
|
applyLibraryConfig(libraryConfig)
|
|
764
|
+
// Older runners cache a numeric ceiling and cannot stop retries before the next lifecycle starts.
|
|
765
|
+
isDynamicAtrEnabled &&= satisfies(frameworkVersion, '>=4.1.0')
|
|
769
766
|
}
|
|
770
767
|
} catch {
|
|
771
768
|
requestErrorTags = {}
|
|
@@ -832,6 +829,8 @@ async function runMainProcessSetup (
|
|
|
832
829
|
setProvidedContext(ctx, {
|
|
833
830
|
_ddIsFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled,
|
|
834
831
|
_ddFlakyTestRetriesCount: flakyTestRetriesCount,
|
|
832
|
+
_ddIsDynamicAtrEnabled: isDynamicAtrEnabled,
|
|
833
|
+
_ddDynamicAtrBuckets: dynamicAtrBuckets,
|
|
835
834
|
_ddFlakyTestRetriesIncludesUnnamedProject: flakyTestRetriesConfiguration.includesUnnamedProject,
|
|
836
835
|
_ddFlakyTestRetriesProjectNames: flakyTestRetriesConfiguration.projectNames,
|
|
837
836
|
}, 'Could not send library configuration to workers.')
|
|
@@ -972,6 +971,8 @@ function getNoWorkerInitState () {
|
|
|
972
971
|
isEarlyFlakeDetectionEnabled,
|
|
973
972
|
isEarlyFlakeDetectionFaulty,
|
|
974
973
|
isFlakyTestRetriesEnabled,
|
|
974
|
+
isDynamicAtrEnabled,
|
|
975
|
+
dynamicAtrBuckets,
|
|
975
976
|
isKnownTestsEnabled,
|
|
976
977
|
newTestsWithDynamicNames,
|
|
977
978
|
requestErrorTags,
|
|
@@ -1039,14 +1040,21 @@ function shouldUseBrowserReporter (frameworkVersion, testSpecifications) {
|
|
|
1039
1040
|
}
|
|
1040
1041
|
|
|
1041
1042
|
function configureFlakyTestRetries (ctx, testSpecifications) {
|
|
1042
|
-
if (!isFlakyTestRetriesEnabled || flakyTestRetriesCount <= 0) return
|
|
1043
|
-
|
|
1043
|
+
if (!isFlakyTestRetriesEnabled || (!isDynamicAtrEnabled && flakyTestRetriesCount <= 0)) return
|
|
1044
|
+
|
|
1045
|
+
const maximumDynamicAtrRetries = dynamicAtrBuckets
|
|
1046
|
+
? Math.max(...dynamicAtrBuckets)
|
|
1047
|
+
: earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
1048
|
+
const retryCount = isDynamicAtrEnabled
|
|
1049
|
+
? Math.max(1, maximumDynamicAtrRetries)
|
|
1050
|
+
: flakyTestRetriesCount
|
|
1044
1051
|
let configured = false
|
|
1045
1052
|
let includesUnnamedProject = false
|
|
1046
1053
|
const projectNames = []
|
|
1047
1054
|
for (const { config, projectName } of getVitestProjectConfigs(ctx, testSpecifications)) {
|
|
1048
|
-
if (!config.retry) {
|
|
1049
|
-
|
|
1055
|
+
if (!config.retry || config.retry.__ddTestOptAtr) {
|
|
1056
|
+
// The serializable marker survives task inheritance and setup refreshes, unlike numeric retry counts.
|
|
1057
|
+
config.retry = isDynamicAtrEnabled ? { count: retryCount, __ddTestOptAtr: true } : retryCount
|
|
1050
1058
|
configured = true
|
|
1051
1059
|
if (projectName) {
|
|
1052
1060
|
projectNames.push(projectName)
|
|
@@ -1179,6 +1187,9 @@ function safeWorkspaceProject (ctx) {
|
|
|
1179
1187
|
|
|
1180
1188
|
function getSortWrapper (sort, frameworkVersion) {
|
|
1181
1189
|
return async function () {
|
|
1190
|
+
if (this.ctx.config.shard && this.ctx.state.pathsSet.size > 0 && arguments[0].length === 0) {
|
|
1191
|
+
emptyShardContexts.add(this.ctx)
|
|
1192
|
+
}
|
|
1182
1193
|
if (!activeRunFilesContexts.has(this.ctx)) {
|
|
1183
1194
|
const testSpecifications = arguments[0]
|
|
1184
1195
|
await ensureMainProcessSetup(this.ctx, frameworkVersion, testSpecifications)
|
|
@@ -1189,18 +1200,18 @@ function getSortWrapper (sort, frameworkVersion) {
|
|
|
1189
1200
|
}
|
|
1190
1201
|
|
|
1191
1202
|
function getFinishWrapper (exitOrClose) {
|
|
1192
|
-
let isClosed = false
|
|
1193
1203
|
return async function () {
|
|
1194
|
-
if (
|
|
1204
|
+
if (finishedSessionContexts.has(this)) {
|
|
1195
1205
|
return exitOrClose.apply(this, arguments)
|
|
1196
1206
|
}
|
|
1197
|
-
isClosed = true
|
|
1198
1207
|
|
|
1199
1208
|
if (!testSessionFinishCh.hasSubscribers) {
|
|
1200
1209
|
return exitOrClose.apply(this, arguments)
|
|
1201
1210
|
}
|
|
1211
|
+
finishedSessionContexts.add(this)
|
|
1202
1212
|
|
|
1203
1213
|
const failedSuites = this.state.getFailedFilepaths()
|
|
1214
|
+
const hasRunError = runErrorsByContext.has(this)
|
|
1204
1215
|
const runError = runErrorsByContext.get(this)
|
|
1205
1216
|
runErrorsByContext.delete(this)
|
|
1206
1217
|
let error = runError
|
|
@@ -1208,8 +1219,30 @@ function getFinishWrapper (exitOrClose) {
|
|
|
1208
1219
|
error = new Error(`Test suites failed: ${failedSuites.length}.`)
|
|
1209
1220
|
}
|
|
1210
1221
|
|
|
1222
|
+
// pathsSet contains candidates before sharding, including files that never run.
|
|
1223
|
+
const hasNoTestFiles = this.state.pathsSet.size === 0
|
|
1224
|
+
const isEmptyShard = emptyShardContexts.has(this)
|
|
1225
|
+
const hasUnexpectedEmptySession = hasNoTestFiles && !isEmptyShard &&
|
|
1226
|
+
!areAllSuitesSkipped && !this.config.passWithNoTests
|
|
1227
|
+
if (!error && hasUnexpectedEmptySession) {
|
|
1228
|
+
error = new Error('No test files were found.')
|
|
1229
|
+
}
|
|
1230
|
+
const tests = getTypeTasks(this.state.getFiles())
|
|
1231
|
+
const hasExecutedTests = tests.some(test =>
|
|
1232
|
+
test.mode !== 'skip' && test.mode !== 'todo' &&
|
|
1233
|
+
test.result?.state !== 'skip' && test.result?.state !== 'todo'
|
|
1234
|
+
)
|
|
1235
|
+
const hasErrors = hasRunError || error ||
|
|
1236
|
+
this.state.getCountOfFailedTests() > 0 || this.state.getUnhandledErrors().length > 0
|
|
1237
|
+
const testSessionEmptyReason = !hasErrors && !hasExecutedTests
|
|
1238
|
+
? (isEmptyShard
|
|
1239
|
+
? 'zero_test_shard'
|
|
1240
|
+
: tests.length > 0 || skippedSuites.length > 0 ? 'all_tests_skipped' : 'zero_tests')
|
|
1241
|
+
: undefined
|
|
1242
|
+
const status = hasErrors ? 'fail' : (testSessionEmptyReason ? 'skip' : 'pass')
|
|
1211
1243
|
const flushPromise = getChannelPromise(testSessionFinishCh, {
|
|
1212
|
-
status
|
|
1244
|
+
status,
|
|
1245
|
+
testSessionEmptyReason,
|
|
1213
1246
|
testCodeCoverageLinesTotal,
|
|
1214
1247
|
error,
|
|
1215
1248
|
isEarlyFlakeDetectionEnabled,
|
|
@@ -1306,7 +1339,6 @@ function getTestSpecificationPool (testSpecification) {
|
|
|
1306
1339
|
* Detect whether Vitest selected only TypeScript typecheck specifications.
|
|
1307
1340
|
*
|
|
1308
1341
|
* @param {unknown} testSpecifications
|
|
1309
|
-
* @returns {boolean}
|
|
1310
1342
|
*/
|
|
1311
1343
|
function hasOnlyTypecheckTestSpecifications (testSpecifications) {
|
|
1312
1344
|
if (!Array.isArray(testSpecifications) || testSpecifications.length === 0) return false
|
|
@@ -1366,12 +1398,46 @@ function markVitestWorkerEnv (ctx, testSpecifications, shouldSkipWorkerInit = fa
|
|
|
1366
1398
|
config.env = getVitestWorkerEnv(config.env, shouldSkipWorkerInit)
|
|
1367
1399
|
}
|
|
1368
1400
|
|
|
1401
|
+
/**
|
|
1402
|
+
* Installs completion hooks before discovery, which can bypass runFiles entirely.
|
|
1403
|
+
* @param {Function} Vitest
|
|
1404
|
+
*/
|
|
1405
|
+
function wrapVitestSession (Vitest) {
|
|
1406
|
+
if (!Vitest?.prototype?.start || sessionWrappedPrototypes.has(Vitest.prototype)) return
|
|
1407
|
+
sessionWrappedPrototypes.add(Vitest.prototype)
|
|
1408
|
+
|
|
1409
|
+
// Empty discovery bypasses runFiles. Vitest 1 exits directly after reporting coverage,
|
|
1410
|
+
// so its finalization must be awaited before that process.exit rather than only in close.
|
|
1411
|
+
// Hashed bundle names prevent Orchestrion's exact-file matching.
|
|
1412
|
+
shimmer.wrap(Vitest.prototype, 'start', start => function () {
|
|
1413
|
+
if (!testSessionFinishCh.hasSubscribers) return start.apply(this, arguments)
|
|
1414
|
+
wrapSessionFinish(this)
|
|
1415
|
+
return start.apply(this, arguments).then(undefined, error => {
|
|
1416
|
+
if (error?.code !== 'VITEST_FILES_NOT_FOUND') runErrorsByContext.set(this, error)
|
|
1417
|
+
throw error
|
|
1418
|
+
})
|
|
1419
|
+
})
|
|
1420
|
+
shimmer.wrap(Vitest.prototype, 'reportCoverage', reportCoverage => function () {
|
|
1421
|
+
const result = reportCoverage.apply(this, arguments)
|
|
1422
|
+
if (!testSessionFinishCh.hasSubscribers || !isSessionStarted || this.config.watch ||
|
|
1423
|
+
mainProcessSetupStates.has(this) || this.state.pathsSet.size > 0) {
|
|
1424
|
+
return result
|
|
1425
|
+
}
|
|
1426
|
+
return result.then(value => {
|
|
1427
|
+
const finish = getFinishWrapper(() => value)
|
|
1428
|
+
return finish.call(this)
|
|
1429
|
+
})
|
|
1430
|
+
})
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1369
1433
|
function wrapVitestRunFiles (Vitest, frameworkVersion) {
|
|
1370
1434
|
if (!Vitest?.prototype?.runFiles || runFilesWrappedPrototypes.has(Vitest.prototype)) {
|
|
1371
1435
|
return
|
|
1372
1436
|
}
|
|
1373
1437
|
runFilesWrappedPrototypes.add(Vitest.prototype)
|
|
1374
1438
|
|
|
1439
|
+
wrapVitestSession(Vitest)
|
|
1440
|
+
|
|
1375
1441
|
shimmer.wrap(Vitest.prototype, 'runFiles', runFiles => async function (testSpecifications) {
|
|
1376
1442
|
if (activeRunFilesContexts.has(this)) {
|
|
1377
1443
|
return runFiles.apply(this, arguments)
|
|
@@ -1413,7 +1479,6 @@ function getTypecheckTaskStatus (task) {
|
|
|
1413
1479
|
*
|
|
1414
1480
|
* @param {string|undefined} suiteName
|
|
1415
1481
|
* @param {string} testSuiteAbsolutePath
|
|
1416
|
-
* @returns {boolean}
|
|
1417
1482
|
*/
|
|
1418
1483
|
function isTypecheckFileSuiteName (suiteName, testSuiteAbsolutePath) {
|
|
1419
1484
|
if (!suiteName || !testSuiteAbsolutePath) return false
|
|
@@ -1429,7 +1494,6 @@ function isTypecheckFileSuiteName (suiteName, testSuiteAbsolutePath) {
|
|
|
1429
1494
|
*
|
|
1430
1495
|
* @param {object} task
|
|
1431
1496
|
* @param {string} testSuiteAbsolutePath
|
|
1432
|
-
* @returns {string}
|
|
1433
1497
|
*/
|
|
1434
1498
|
function getTypecheckTestName (task, testSuiteAbsolutePath) {
|
|
1435
1499
|
let testName = task.name || task.fullTestName
|
|
@@ -1508,7 +1572,6 @@ function updateTypecheckTaskResultForTestManagement (task, status, testManagemen
|
|
|
1508
1572
|
* Recompute suite/file typecheck results after Test Management rewrites child test results.
|
|
1509
1573
|
*
|
|
1510
1574
|
* @param {object} task
|
|
1511
|
-
* @returns {string}
|
|
1512
1575
|
*/
|
|
1513
1576
|
function updateTypecheckTaskTreeResult (task) {
|
|
1514
1577
|
if (!Array.isArray(task.tasks)) return getTypecheckTaskStatus(task)
|
|
@@ -1552,7 +1615,6 @@ function updateTypecheckTaskTreeResult (task) {
|
|
|
1552
1615
|
* sourceErrors?: object[],
|
|
1553
1616
|
* state?: string
|
|
1554
1617
|
* }} result
|
|
1555
|
-
* @returns {boolean}
|
|
1556
1618
|
*/
|
|
1557
1619
|
function updateTypecheckResult (result) {
|
|
1558
1620
|
if (result.sourceErrors?.length) return false
|
|
@@ -1945,7 +2007,6 @@ function getWrappedOn (on) {
|
|
|
1945
2007
|
* @param {object} workerProcess
|
|
1946
2008
|
* @param {number} interprocessCode
|
|
1947
2009
|
* @param {object} data
|
|
1948
|
-
* @returns {boolean}
|
|
1949
2010
|
*/
|
|
1950
2011
|
function handleEfdAdmissionMessage (workerProcess, interprocessCode, data) {
|
|
1951
2012
|
if (interprocessCode !== VITEST_WORKER_EFD_SUITE_ADMISSION_REQUEST_CODE) return false
|
|
@@ -2060,6 +2121,36 @@ addHook({
|
|
|
2060
2121
|
return wrapTinyPool(TinyPool)
|
|
2061
2122
|
})
|
|
2062
2123
|
|
|
2124
|
+
/**
|
|
2125
|
+
* Older Vitest versions expose their core instance through the logger constructor.
|
|
2126
|
+
* @param {Record<string, Function>} vitestPackage
|
|
2127
|
+
*/
|
|
2128
|
+
function wrapVitestLogger (vitestPackage) {
|
|
2129
|
+
const logger = findExportByName(vitestPackage, 'Logger')
|
|
2130
|
+
if (logger) {
|
|
2131
|
+
// Hashed bundle names prevent Orchestrion's exact-file matching.
|
|
2132
|
+
shimmer.wrap(vitestPackage, logger.key, Logger => class extends Logger {
|
|
2133
|
+
constructor (...args) {
|
|
2134
|
+
super(...args)
|
|
2135
|
+
if (testSessionFinishCh.hasSubscribers) wrapVitestSession(args[0]?.constructor)
|
|
2136
|
+
}
|
|
2137
|
+
})
|
|
2138
|
+
}
|
|
2139
|
+
return vitestPackage
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
addHook({
|
|
2143
|
+
name: 'vitest',
|
|
2144
|
+
versions: ['>=1.6.0 <2.0.5'],
|
|
2145
|
+
filePattern: 'dist/vendor/index.*',
|
|
2146
|
+
}, wrapVitestLogger)
|
|
2147
|
+
|
|
2148
|
+
addHook({
|
|
2149
|
+
name: 'vitest',
|
|
2150
|
+
versions: ['>=2.0.5 <3.0.0'],
|
|
2151
|
+
filePattern: 'dist/chunks/index.*',
|
|
2152
|
+
}, wrapVitestLogger)
|
|
2153
|
+
|
|
2063
2154
|
// There are multiple index* files across different versions of vitest,
|
|
2064
2155
|
// so we check for the existence of BaseSequencer to determine if we are in the right file
|
|
2065
2156
|
addHook({
|
|
@@ -45,7 +45,6 @@ const codeCoverageReportCh = channel('ci:vitest:coverage-report')
|
|
|
45
45
|
* Resolves a path without failing Test Optimization when the path is unavailable.
|
|
46
46
|
*
|
|
47
47
|
* @param {string} filepath
|
|
48
|
-
* @returns {string}
|
|
49
48
|
*/
|
|
50
49
|
function realpath (filepath) {
|
|
51
50
|
try {
|
|
@@ -179,6 +178,8 @@ function getProvidedContext () {
|
|
|
179
178
|
_ddTestManagementAttemptToFixRetries: testManagementAttemptToFixRetries,
|
|
180
179
|
_ddIsFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled,
|
|
181
180
|
_ddFlakyTestRetriesCount: flakyTestRetriesCount,
|
|
181
|
+
_ddIsDynamicAtrEnabled: isDynamicAtrEnabled,
|
|
182
|
+
_ddDynamicAtrBuckets: dynamicAtrBuckets,
|
|
182
183
|
_ddFlakyTestRetriesIncludesUnnamedProject: flakyTestRetriesIncludesUnnamedProject,
|
|
183
184
|
_ddFlakyTestRetriesProjectNames: flakyTestRetriesProjectNames,
|
|
184
185
|
_ddIsImpactedTestsEnabled: isImpactedTestsEnabled,
|
|
@@ -206,6 +207,8 @@ function getProvidedContext () {
|
|
|
206
207
|
testManagementAttemptToFixRetries,
|
|
207
208
|
isFlakyTestRetriesEnabled,
|
|
208
209
|
flakyTestRetriesCount: flakyTestRetriesCount ?? 0,
|
|
210
|
+
isDynamicAtrEnabled,
|
|
211
|
+
dynamicAtrBuckets,
|
|
209
212
|
flakyTestRetriesIncludesUnnamedProject,
|
|
210
213
|
flakyTestRetriesProjectNames,
|
|
211
214
|
isImpactedTestsEnabled,
|
|
@@ -232,6 +235,8 @@ function getProvidedContext () {
|
|
|
232
235
|
testManagementAttemptToFixRetries: 0,
|
|
233
236
|
isFlakyTestRetriesEnabled: false,
|
|
234
237
|
flakyTestRetriesCount: 0,
|
|
238
|
+
isDynamicAtrEnabled: false,
|
|
239
|
+
dynamicAtrBuckets: undefined,
|
|
235
240
|
flakyTestRetriesIncludesUnnamedProject: false,
|
|
236
241
|
flakyTestRetriesProjectNames: undefined,
|
|
237
242
|
isImpactedTestsEnabled: false,
|
|
@@ -250,6 +255,7 @@ function getProvidedContext () {
|
|
|
250
255
|
|
|
251
256
|
function isFlakyTestRetriesEnabledForTask (providedContext, task) {
|
|
252
257
|
if (!providedContext.isFlakyTestRetriesEnabled) return false
|
|
258
|
+
if (providedContext.isDynamicAtrEnabled && !task.retry?.__ddTestOptAtr) return false
|
|
253
259
|
|
|
254
260
|
const { flakyTestRetriesProjectNames } = providedContext
|
|
255
261
|
if (!Array.isArray(flakyTestRetriesProjectNames)) return true
|