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,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { BLOCKER_CATEGORIES, getBlockerDomain } = require('./blocker-category')
|
|
3
4
|
const { getCommandBlocker } = require('./command-blocker')
|
|
4
5
|
const { runCommand, serializeDisplayCommand } = require('./command-runner')
|
|
5
6
|
const { getBasicCommand } = require('./runner-command')
|
|
@@ -17,12 +18,81 @@ const { getObservedTestCount } = require('./test-output')
|
|
|
17
18
|
* @returns {Promise<{ok: boolean, failure?: object, preflight: object}>} preflight outcome
|
|
18
19
|
*/
|
|
19
20
|
async function runFrameworkPreflight ({ framework, out, options }) {
|
|
20
|
-
const
|
|
21
|
-
|
|
21
|
+
const candidates = [
|
|
22
|
+
{
|
|
23
|
+
localSocketRequired: framework.localSocketRequired,
|
|
24
|
+
testFile: framework.validation.testFile,
|
|
25
|
+
},
|
|
26
|
+
...(framework.validation.fallbackTests || []),
|
|
27
|
+
]
|
|
28
|
+
const attempts = []
|
|
29
|
+
let last
|
|
30
|
+
|
|
31
|
+
for (const [index, candidate] of candidates.entries()) {
|
|
32
|
+
// Fallbacks are ordered and later candidates must not run after one succeeds.
|
|
33
|
+
// eslint-disable-next-line no-await-in-loop
|
|
34
|
+
const attempt = await runCandidate({ framework, index, options, out, testFile: candidate.testFile })
|
|
35
|
+
attempts.push(attempt.preflight)
|
|
36
|
+
last = attempt
|
|
37
|
+
if (!attempt.ok) {
|
|
38
|
+
if (isSharedCandidateBlocker(attempt.commandFailure, framework)) break
|
|
39
|
+
continue
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
framework.validation.testFile = candidate.testFile
|
|
43
|
+
const preflight = { ...attempt.preflight, attempts, selectedTestFile: candidate.testFile }
|
|
44
|
+
framework.preflight = preflight
|
|
45
|
+
return { ok: true, preflight }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { commandFailure, observedTestCount, preflight, result } = last
|
|
49
|
+
const completePreflight = {
|
|
50
|
+
...preflight,
|
|
51
|
+
attempts,
|
|
52
|
+
selectedTestFile: undefined,
|
|
53
|
+
}
|
|
54
|
+
framework.preflight = completePreflight
|
|
55
|
+
const blockerCategory = commandFailure?.blockerCategory ||
|
|
56
|
+
(observedTestCount === 0
|
|
57
|
+
? BLOCKER_CATEGORIES.VALIDATOR_LIMITATION
|
|
58
|
+
: BLOCKER_CATEGORIES.CLEAN_TEST_FAILED)
|
|
59
|
+
const domain = getBlockerDomain(blockerCategory)
|
|
60
|
+
const diagnosis = getFailureDiagnosis(
|
|
61
|
+
result,
|
|
62
|
+
observedTestCount,
|
|
63
|
+
commandFailure,
|
|
64
|
+
preflight.diagnosticSummary,
|
|
65
|
+
framework
|
|
66
|
+
)
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
preflight: completePreflight,
|
|
70
|
+
failure: {
|
|
71
|
+
frameworkId: framework.id,
|
|
72
|
+
scenario: 'basic-reporting',
|
|
73
|
+
status: 'blocked',
|
|
74
|
+
diagnosis,
|
|
75
|
+
evidence: {
|
|
76
|
+
blockerCategory,
|
|
77
|
+
commandFailure,
|
|
78
|
+
domain,
|
|
79
|
+
recommendation: commandFailure?.recommendation ||
|
|
80
|
+
`Resolve the selected project test failure before retrying validation: ${diagnosis}`,
|
|
81
|
+
validationIncomplete: true,
|
|
82
|
+
},
|
|
83
|
+
artifacts: Object.values(result.artifacts),
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function runCandidate ({ framework, index, options, out, testFile }) {
|
|
89
|
+
const suffix = index === 0 ? '' : `-fallback-${index}`
|
|
90
|
+
const command = getBasicCommand(framework, testFile)
|
|
91
|
+
const outDir = frameworkOutDir(out, framework, `preflight${suffix}`)
|
|
22
92
|
const result = await runCommand(command, {
|
|
23
93
|
artifactRoot: out,
|
|
24
94
|
envMode: 'clean',
|
|
25
|
-
label: `${framework.id}:preflight`,
|
|
95
|
+
label: `${framework.id}:preflight${suffix}`,
|
|
26
96
|
outDir,
|
|
27
97
|
repositoryRoot: options.repositoryRoot,
|
|
28
98
|
requireExecutableApproval: options.requireExecutableApproval,
|
|
@@ -32,12 +102,13 @@ async function runFrameworkPreflight ({ framework, out, options }) {
|
|
|
32
102
|
const commandFailure = getCommandBlocker(result, {
|
|
33
103
|
browserRequired: framework.browserRequired,
|
|
34
104
|
framework: framework.framework,
|
|
105
|
+
packageJson: framework.project.packageJson,
|
|
35
106
|
testsRan: Number.isInteger(observedTestCount) && observedTestCount > 0,
|
|
36
107
|
})
|
|
37
108
|
const preflight = {
|
|
38
109
|
command: serializeDisplayCommand(command),
|
|
39
110
|
diagnosticSummary: findInterestingLines(`${result.stdout}\n${result.stderr}`, [
|
|
40
|
-
/\b(?:Abort trap|Cannot find|Error|ERR_[A-Z_]+|Failed to|Received signal|SIGABRT)\b/i,
|
|
111
|
+
/\b(?:Abort trap|Cannot find|Error|TypeError|ReferenceError|RangeError|SyntaxError|ERR_[A-Z_]+|FAIL|Failed to|No tests found|Received signal|SIGABRT)\b/i,
|
|
41
112
|
], 4),
|
|
42
113
|
durationMs: result.durationMs,
|
|
43
114
|
exitCode: result.exitCode,
|
|
@@ -49,35 +120,16 @@ async function runFrameworkPreflight ({ framework, out, options }) {
|
|
|
49
120
|
source: 'validator',
|
|
50
121
|
stderrSummary: summarizeTestOutput('', result.stderr).join('\n'),
|
|
51
122
|
stdoutSummary: summarizeTestOutput(result.stdout).join('\n'),
|
|
123
|
+
testFile,
|
|
52
124
|
timedOut: result.timedOut,
|
|
53
125
|
...(commandFailure ? { commandFailure } : {}),
|
|
54
126
|
}
|
|
55
|
-
framework.preflight = preflight
|
|
56
|
-
|
|
57
|
-
if (!result.timedOut && result.exitCode === 0 && observedTestCount !== 0) {
|
|
58
|
-
return { ok: true, preflight }
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const domain = commandFailure?.blockedByExecutionEnvironment
|
|
62
|
-
? 'execution_environment'
|
|
63
|
-
: commandFailure?.localRuntimeBlocked
|
|
64
|
-
? 'local_runtime'
|
|
65
|
-
: 'project_setup'
|
|
66
127
|
return {
|
|
67
|
-
|
|
128
|
+
commandFailure,
|
|
129
|
+
observedTestCount,
|
|
130
|
+
ok: !result.timedOut && result.exitCode === 0 && observedTestCount !== 0,
|
|
68
131
|
preflight,
|
|
69
|
-
|
|
70
|
-
frameworkId: framework.id,
|
|
71
|
-
scenario: 'basic-reporting',
|
|
72
|
-
status: 'blocked',
|
|
73
|
-
diagnosis: getFailureDiagnosis(result, observedTestCount, commandFailure),
|
|
74
|
-
evidence: {
|
|
75
|
-
commandFailure,
|
|
76
|
-
domain,
|
|
77
|
-
validationIncomplete: true,
|
|
78
|
-
},
|
|
79
|
-
artifacts: Object.values(result.artifacts),
|
|
80
|
-
},
|
|
132
|
+
result,
|
|
81
133
|
}
|
|
82
134
|
}
|
|
83
135
|
|
|
@@ -87,11 +139,17 @@ async function runFrameworkPreflight ({ framework, out, options }) {
|
|
|
87
139
|
* @param {object} result command result
|
|
88
140
|
* @param {number|null} observedTestCount parsed test count
|
|
89
141
|
* @param {object|undefined} commandFailure classified blocker
|
|
142
|
+
* @param {string[]} diagnosticSummary bounded diagnostic lines
|
|
143
|
+
* @param {object} framework framework manifest entry
|
|
90
144
|
* @returns {string} customer-facing diagnosis
|
|
91
145
|
*/
|
|
92
|
-
function getFailureDiagnosis (result, observedTestCount, commandFailure) {
|
|
146
|
+
function getFailureDiagnosis (result, observedTestCount, commandFailure, diagnosticSummary, framework) {
|
|
147
|
+
const sharedPrerequisite = !commandFailure && framework.allCandidatesRequireLocalSocket
|
|
148
|
+
? ' Every approved candidate appears to require localhost, so retry in the project environment where its ' +
|
|
149
|
+
'listener-based tests normally pass.'
|
|
150
|
+
: ''
|
|
93
151
|
if (commandFailure?.summary) {
|
|
94
|
-
return `${commandFailure.summary} Basic Reporting could not be tested reliably
|
|
152
|
+
return `${commandFailure.summary} Basic Reporting could not be tested reliably.${sharedPrerequisite}`
|
|
95
153
|
}
|
|
96
154
|
if (result.timedOut) {
|
|
97
155
|
return 'The direct representative test exceeded its approved timeout. Basic Reporting could not be tested ' +
|
|
@@ -101,8 +159,29 @@ function getFailureDiagnosis (result, observedTestCount, commandFailure) {
|
|
|
101
159
|
return 'The direct runner completed without reporting a test. The selected file may require project wrapper or ' +
|
|
102
160
|
'configuration semantics, so Basic Reporting remains incomplete.'
|
|
103
161
|
}
|
|
162
|
+
if (diagnosticSummary.length > 0) {
|
|
163
|
+
return `The direct representative test exited ${result.exitCode} without Datadog initialization. ` +
|
|
164
|
+
`The first reported issue was: ${diagnosticSummary[0]}${sharedPrerequisite}`
|
|
165
|
+
}
|
|
104
166
|
return `The direct representative test exited ${result.exitCode} without Datadog initialization. Fix or prepare ` +
|
|
105
|
-
|
|
167
|
+
`that test normally, then create a fresh validation plan.${sharedPrerequisite}`
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Do not try fallbacks when every disclosed candidate shares the same prerequisite.
|
|
171
|
+
function isSharedCandidateBlocker (commandFailure, framework) {
|
|
172
|
+
if (!commandFailure) return false
|
|
173
|
+
if (commandFailure.kind === 'local-test-socket-blocked') {
|
|
174
|
+
return framework.allCandidatesRequireLocalSocket === true
|
|
175
|
+
}
|
|
176
|
+
return commandFailure.kind.endsWith('-browser-launch-blocked') ||
|
|
177
|
+
[
|
|
178
|
+
'cucumber-browser-missing',
|
|
179
|
+
'cypress-runtime-missing',
|
|
180
|
+
'playwright-browser-missing',
|
|
181
|
+
'project-command-environment-missing',
|
|
182
|
+
'test-runner-command-missing',
|
|
183
|
+
'vitest-browser-provider-missing',
|
|
184
|
+
].includes(commandFailure.kind)
|
|
106
185
|
}
|
|
107
186
|
|
|
108
187
|
module.exports = { runFrameworkPreflight }
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const path = require('node:path')
|
|
4
|
+
|
|
5
|
+
const BUILD_DIRECTORY_PATTERN = /(?:^|\/)(?:build|dist|generated)(?:\/|$)/
|
|
6
|
+
const WINDOWS_ABSOLUTE_PATH_PATTERN = /^[A-Za-z]:\//
|
|
7
|
+
|
|
8
|
+
// Bare package subpaths and node_modules paths belong to dependencies, not to the customer project.
|
|
9
|
+
function isProjectBuildArtifactPath (filename, projectRoot, baseDirectory = projectRoot) {
|
|
10
|
+
const normalized = String(filename).replaceAll('\\', '/')
|
|
11
|
+
if (!BUILD_DIRECTORY_PATTERN.test(normalized) ||
|
|
12
|
+
/(?:^|\/)node_modules(?:\/|$)/.test(normalized)) return false
|
|
13
|
+
|
|
14
|
+
const relativePath = normalized.startsWith('./') || normalized.startsWith('../')
|
|
15
|
+
if ((!relativePath && !normalized.startsWith('/') && !WINDOWS_ABSOLUTE_PATH_PATTERN.test(normalized)) ||
|
|
16
|
+
typeof projectRoot !== 'string') return false
|
|
17
|
+
|
|
18
|
+
const normalizedRoot = projectRoot.replaceAll('\\', '/')
|
|
19
|
+
const windowsPath = WINDOWS_ABSOLUTE_PATH_PATTERN.test(normalized)
|
|
20
|
+
const windowsRoot = WINDOWS_ABSOLUTE_PATH_PATTERN.test(normalizedRoot)
|
|
21
|
+
if (windowsPath !== windowsRoot && windowsPath) return false
|
|
22
|
+
const pathApi = windowsRoot ? path.win32 : path.posix
|
|
23
|
+
const root = pathApi.resolve(normalizedRoot)
|
|
24
|
+
const candidate = relativePath
|
|
25
|
+
? pathApi.resolve(String(baseDirectory).replaceAll('\\', '/'), normalized)
|
|
26
|
+
: pathApi.resolve(normalized)
|
|
27
|
+
const relative = pathApi.relative(root, candidate)
|
|
28
|
+
return relative === '' || (!relative.startsWith('..') && !pathApi.isAbsolute(relative))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = { isProjectBuildArtifactPath }
|
|
@@ -13,7 +13,6 @@ const SECRET_NAME_SOURCE = [
|
|
|
13
13
|
'PASSPHRASE',
|
|
14
14
|
'CREDENTIAL',
|
|
15
15
|
'PRIVATE_?KEY',
|
|
16
|
-
'CLIENT_?SECRET',
|
|
17
16
|
'ACCESS_?KEY',
|
|
18
17
|
'COOKIE',
|
|
19
18
|
].join('|')
|
|
@@ -22,23 +21,18 @@ const EXACT_SECRET_ASSIGNMENT_NAME_SOURCE = [
|
|
|
22
21
|
'AUTH',
|
|
23
22
|
'AUTHORIZATION',
|
|
24
23
|
'PASS',
|
|
25
|
-
'SET-COOKIE',
|
|
26
24
|
'PAT',
|
|
27
25
|
'JWT',
|
|
28
26
|
'WEBHOOK(?:_URL)?',
|
|
29
27
|
].join('|')
|
|
30
|
-
|
|
28
|
+
// Every pattern built from these name sources carries the `i` flag; the classes list uppercase only.
|
|
29
|
+
const SECRET_NAME_CHARS = '[A-Z0-9_.-]'
|
|
31
30
|
const SECRET_ASSIGNMENT_NAME_SOURCE = [
|
|
32
|
-
|
|
33
|
-
`[A-
|
|
34
|
-
`[A-
|
|
35
|
-
`[A-
|
|
36
|
-
`[A-
|
|
37
|
-
'PASS',
|
|
38
|
-
'AUTH',
|
|
39
|
-
'AUTHORIZATION',
|
|
40
|
-
'COOKIE',
|
|
41
|
-
'SET-COOKIE',
|
|
31
|
+
EXACT_SECRET_ASSIGNMENT_NAME_SOURCE,
|
|
32
|
+
`[A-Z_]${SECRET_NAME_CHARS}*(?:${SECRET_NAME_SOURCE})${SECRET_NAME_CHARS}*`,
|
|
33
|
+
`[A-Z_]${SECRET_NAME_CHARS}*[-_]PASS`,
|
|
34
|
+
`[A-Z_]${SECRET_NAME_CHARS}*[-_]AUTH(?:ORIZATION)?`,
|
|
35
|
+
`[A-Z_]${SECRET_NAME_CHARS}*[-_](?:PAT|JWT|WEBHOOK(?:_URL)?)`,
|
|
42
36
|
].join('|')
|
|
43
37
|
const SECRET_FLAG_SOURCE = [
|
|
44
38
|
'api-key',
|
|
@@ -54,7 +48,7 @@ const SECRET_FLAG_SOURCE = [
|
|
|
54
48
|
'auth',
|
|
55
49
|
].join('|')
|
|
56
50
|
const SECRET_VALUE_SOURCE = String.raw`("[^"]*"|'[^']*'|[^\s,;]+)`
|
|
57
|
-
const SENSITIVE_NAME_PATTERN = new RegExp(
|
|
51
|
+
const SENSITIVE_NAME_PATTERN = new RegExp(SECRET_NAME_SOURCE, 'i')
|
|
58
52
|
const SENSITIVE_AUTH_NAME_PATTERN = /(?:^|_)AUTH(?:ORIZATION)?(?:_|$)/i
|
|
59
53
|
const SENSITIVE_COOKIE_NAME_PATTERN = /(?:^|_)SET_?COOKIE(?:_|$)|(?:^|_)COOKIE(?:_|$)/i
|
|
60
54
|
const SENSITIVE_PASS_NAME_PATTERN = /(?:^|_)PASS(?:_|$)/i
|
|
@@ -64,16 +58,16 @@ const SECRET_ASSIGNMENT_PATTERN = new RegExp(
|
|
|
64
58
|
'gi'
|
|
65
59
|
)
|
|
66
60
|
const SECRET_FLAG_PATTERN = new RegExp(
|
|
67
|
-
String.raw`(--(?:${SECRET_FLAG_SOURCE})(?:-[A-
|
|
61
|
+
String.raw`(--(?:${SECRET_FLAG_SOURCE})(?:-[A-Z0-9]+)*)(=|\s+)` + SECRET_VALUE_SOURCE,
|
|
68
62
|
'gi'
|
|
69
63
|
)
|
|
70
64
|
const SECRET_FLAG_NAME_PATTERN = new RegExp(
|
|
71
|
-
`^--(?:${SECRET_FLAG_SOURCE})(?:-[A-
|
|
65
|
+
`^--(?:${SECRET_FLAG_SOURCE})(?:-[A-Z0-9]+)*$`,
|
|
72
66
|
'i'
|
|
73
67
|
)
|
|
74
68
|
const AUTH_HEADER_PATTERN = /\b(Bearer)\s+([^\s'",}\]]+)/gi
|
|
75
69
|
const AUTH_SCHEME_ASSIGNMENT_QUOTED_PATTERN = new RegExp(
|
|
76
|
-
String.raw`\b(${SECRET_ASSIGNMENT_NAME_SOURCE})\s*=\s*(["'])(?:Bearer|Basic)\s
|
|
70
|
+
String.raw`\b(${SECRET_ASSIGNMENT_NAME_SOURCE})\s*=\s*(["'])(?:Bearer|Basic)\s.*?\2`,
|
|
77
71
|
'gi'
|
|
78
72
|
)
|
|
79
73
|
const AUTH_SCHEME_ASSIGNMENT_PATTERN = new RegExp(
|
|
@@ -83,7 +77,7 @@ const AUTH_SCHEME_ASSIGNMENT_PATTERN = new RegExp(
|
|
|
83
77
|
const DEFAULT_IGNORABLE_PATTERN = /\p{Default_Ignorable_Code_Point}/gu
|
|
84
78
|
const DEFAULT_IGNORABLE_TEST_PATTERN = /\p{Default_Ignorable_Code_Point}/u
|
|
85
79
|
const CONTROL_CHARACTER_TEST_PATTERN = /\p{Cc}/u
|
|
86
|
-
const UNSAFE_CONTROL_SOURCE = String.raw`[\u0000-\u0008\
|
|
80
|
+
const UNSAFE_CONTROL_SOURCE = String.raw`[\u0000-\u0008\v\f\u000E-\u001F\u007F-\u009F]`
|
|
87
81
|
const UNSAFE_CONTROL_PATTERN = new RegExp(UNSAFE_CONTROL_SOURCE, 'g')
|
|
88
82
|
const UNSAFE_CONTROL_TEST_PATTERN = new RegExp(UNSAFE_CONTROL_SOURCE)
|
|
89
83
|
const PRIVATE_KEY_BLOCK_PATTERN =
|
|
@@ -92,10 +86,10 @@ const JWT_VALUE_PATTERN = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9
|
|
|
92
86
|
const KNOWN_TOKEN_VALUE_PATTERN =
|
|
93
87
|
/\b(?:gh[pousr]_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,}|glpat-[A-Za-z0-9_-]{20,}|xox[baprs]-[A-Za-z0-9-]{20,})\b/g
|
|
94
88
|
const SECRET_HEADER_ENV_NAME_SOURCE = [
|
|
95
|
-
|
|
96
|
-
`[A-
|
|
97
|
-
`[A-
|
|
98
|
-
`[A-
|
|
89
|
+
`${SECRET_NAME_SOURCE}|PAT|JWT|WEBHOOK(?:_URL)?`,
|
|
90
|
+
`[A-Z_]${SECRET_NAME_CHARS}*(?:${SECRET_NAME_SOURCE})${SECRET_NAME_CHARS}*`,
|
|
91
|
+
`[A-Z_]${SECRET_NAME_CHARS}*[-_]AUTH(?:ORIZATION)?`,
|
|
92
|
+
`[A-Z_]${SECRET_NAME_CHARS}*[-_](?:PAT|JWT|WEBHOOK(?:_URL)?)`,
|
|
99
93
|
].join('|')
|
|
100
94
|
const SECRET_HEADER_NAME_SOURCE = [
|
|
101
95
|
'dd-api-key',
|
|
@@ -103,16 +97,13 @@ const SECRET_HEADER_NAME_SOURCE = [
|
|
|
103
97
|
'api-key',
|
|
104
98
|
'authorization',
|
|
105
99
|
'proxy-authorization',
|
|
106
|
-
'token',
|
|
107
|
-
'cookie',
|
|
108
|
-
'set-cookie',
|
|
109
100
|
SECRET_HEADER_ENV_NAME_SOURCE,
|
|
110
101
|
].join('|')
|
|
111
102
|
const SECRET_HEADER_PATTERN = new RegExp(
|
|
112
|
-
String.raw`\b(
|
|
103
|
+
String.raw`\b(${SECRET_HEADER_NAME_SOURCE})\s*:\s*("[^"]*"|'[^']*'|[^\r\n,}]+)`,
|
|
113
104
|
'gi'
|
|
114
105
|
)
|
|
115
|
-
const URL_CREDENTIAL_PATTERN = /([a-z][a-z0-9+.-]*:\/\/)([^@\s/]+)(@)/gi
|
|
106
|
+
const URL_CREDENTIAL_PATTERN = /(?<![a-z0-9+.-])([a-z][a-z0-9+.-]*:\/\/)([^@\s/]+)(@)/gi
|
|
116
107
|
const GITHUB_SECRET_REFERENCE_PATTERN =
|
|
117
108
|
/(?:\b[A-Za-z_][A-Za-z0-9_.-]*\s*[:=]\s*)?\$\{\{\s*secrets\.([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g
|
|
118
109
|
const SAFE_REFERENCE_MARKER_PATTERN = /DDCIVARREF([0-9]+)X/g
|