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
|
@@ -96,6 +96,20 @@ class GoogleCloudPubsubConsumerPlugin extends ConsumerPlugin {
|
|
|
96
96
|
})
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
start (ctx) {
|
|
100
|
+
if (!this.config.dsmEnabled) return
|
|
101
|
+
const { message } = ctx
|
|
102
|
+
if (!message?.attributes) return
|
|
103
|
+
|
|
104
|
+
const { span } = ctx.currentStore
|
|
105
|
+
const subscription = message._subscriber._subscription
|
|
106
|
+
const topic = subscription?.metadata?.topic || message.attributes?.['pubsub.topic']
|
|
107
|
+
const payloadSize = getMessageSize(message)
|
|
108
|
+
this.tracer.decodeDataStreamsContext(message.attributes)
|
|
109
|
+
this.tracer
|
|
110
|
+
.setCheckpoint(['direction:in', `topic:${topic}`, 'type:google-pubsub'], span, payloadSize)
|
|
111
|
+
}
|
|
112
|
+
|
|
99
113
|
bindStart (ctx) {
|
|
100
114
|
const { message } = ctx
|
|
101
115
|
const subscription = message._subscriber._subscription
|
|
@@ -181,13 +195,6 @@ class GoogleCloudPubsubConsumerPlugin extends ConsumerPlugin {
|
|
|
181
195
|
}
|
|
182
196
|
}
|
|
183
197
|
|
|
184
|
-
if (this.config.dsmEnabled && message?.attributes) {
|
|
185
|
-
const payloadSize = getMessageSize(message)
|
|
186
|
-
this.tracer.decodeDataStreamsContext(message.attributes)
|
|
187
|
-
this.tracer
|
|
188
|
-
.setCheckpoint(['direction:in', `topic:${topic}`, 'type:google-pubsub'], span, payloadSize)
|
|
189
|
-
}
|
|
190
|
-
|
|
191
198
|
return ctx.currentStore
|
|
192
199
|
}
|
|
193
200
|
|
|
@@ -36,6 +36,25 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
|
|
|
36
36
|
if (topicName) attributes['pubsub.topic'] = topicName
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
start (ctx) {
|
|
40
|
+
if (!this.config.dsmEnabled) return
|
|
41
|
+
if (ctx.api !== 'publish' || !ctx.currentStore) return
|
|
42
|
+
const { request } = ctx
|
|
43
|
+
const messages = request.messages || []
|
|
44
|
+
const topic = request.topic
|
|
45
|
+
const { span } = ctx.currentStore
|
|
46
|
+
|
|
47
|
+
for (const msg of messages) {
|
|
48
|
+
const attributes = msg.attributes ??= {}
|
|
49
|
+
const dataStreamsContext = this.tracer.setCheckpoint(
|
|
50
|
+
['direction:out', `topic:${topic}`, 'type:google-pubsub'],
|
|
51
|
+
span,
|
|
52
|
+
getHeadersSize(msg)
|
|
53
|
+
)
|
|
54
|
+
DsmPathwayCodec.encode(dataStreamsContext, attributes)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
39
58
|
bindStart (ctx) {
|
|
40
59
|
const { request, api, projectId } = ctx
|
|
41
60
|
if (api !== 'publish') return
|
|
@@ -113,7 +132,6 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
|
|
|
113
132
|
|
|
114
133
|
const messageCountStr = String(messageCount)
|
|
115
134
|
const startTimeStr = String(Math.floor(batchSpan._startTime))
|
|
116
|
-
const dsmEnabled = this.config.dsmEnabled
|
|
117
135
|
|
|
118
136
|
for (let i = 0; i < messageCount; i++) {
|
|
119
137
|
const msg = messages[i]
|
|
@@ -137,15 +155,6 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
|
|
|
137
155
|
if (batchTraceIdUpper) {
|
|
138
156
|
attributes['_dd.pubsub_request.p.tid'] = batchTraceIdUpper
|
|
139
157
|
}
|
|
140
|
-
|
|
141
|
-
if (dsmEnabled) {
|
|
142
|
-
const dataStreamsContext = this.tracer.setCheckpoint(
|
|
143
|
-
['direction:out', `topic:${topic}`, 'type:google-pubsub'],
|
|
144
|
-
batchSpan,
|
|
145
|
-
getHeadersSize(msg)
|
|
146
|
-
)
|
|
147
|
-
DsmPathwayCodec.encode(dataStreamsContext, attributes)
|
|
148
|
-
}
|
|
149
158
|
}
|
|
150
159
|
|
|
151
160
|
ctx.batchSpan = batchSpan
|
|
@@ -495,6 +495,7 @@ function wrapResolve (resolve) {
|
|
|
495
495
|
// run in the parent store, not field.currentStore: the first sibling's
|
|
496
496
|
// synchronous resolver already finished the shared graphql.resolve span, so
|
|
497
497
|
// re-entering its store would parent user spans to a closed span.
|
|
498
|
+
// eslint-disable-next-line unicorn/prefer-else-if -- Keep sibling early return outside first-field setup.
|
|
498
499
|
if (!isFirst) {
|
|
499
500
|
return callInAsyncScope(resolve, this, arguments, rootCtx.abortController, field.parentStore, (err) => {
|
|
500
501
|
if (updateFieldCh.hasSubscribers) {
|
|
@@ -11,7 +11,7 @@ const transforms = require('./transforms')
|
|
|
11
11
|
const cache = new WeakMap()
|
|
12
12
|
|
|
13
13
|
function defaultEngineReportingSignature (ast, operationName) {
|
|
14
|
-
const key = operationName
|
|
14
|
+
const key = operationName ?? ''
|
|
15
15
|
let inner = cache.get(ast)
|
|
16
16
|
if (inner !== undefined) {
|
|
17
17
|
const cached = inner.get(key)
|
|
@@ -10,6 +10,7 @@ const HTTP_HEADERS = formats.HTTP_HEADERS
|
|
|
10
10
|
const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
|
|
11
11
|
const { buildClientHttpUrl } = require('../../dd-trace/src/plugins/util/url')
|
|
12
12
|
const log = require('../../dd-trace/src/log')
|
|
13
|
+
const { stripQueryAndFragment } = require('../../dd-trace/src/util')
|
|
13
14
|
const { CLIENT_PORT_KEY, COMPONENT, ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../dd-trace/src/constants')
|
|
14
15
|
|
|
15
16
|
const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
|
|
@@ -32,7 +33,7 @@ class HttpClientPlugin extends ClientPlugin {
|
|
|
32
33
|
// A URL object (e.g. from the fetch integration) carries the query in
|
|
33
34
|
// `options.search`, not `options.path`; keep it so url.full retains the query.
|
|
34
35
|
const pathname = options.path || `${options.pathname || ''}${options.search || ''}`
|
|
35
|
-
const path = pathname ? pathname
|
|
36
|
+
const path = pathname ? stripQueryAndFragment(pathname) : '/'
|
|
36
37
|
const uri = `${base}${path}`
|
|
37
38
|
|
|
38
39
|
const allowed = this.config.filter(uri)
|
|
@@ -55,7 +56,7 @@ class HttpClientPlugin extends ClientPlugin {
|
|
|
55
56
|
'out.host': hostname,
|
|
56
57
|
},
|
|
57
58
|
metrics: {
|
|
58
|
-
[CLIENT_PORT_KEY]: Number.parseInt(options.port),
|
|
59
|
+
[CLIENT_PORT_KEY]: Number.parseInt(options.port, 10),
|
|
59
60
|
},
|
|
60
61
|
}, false)
|
|
61
62
|
|
|
@@ -197,7 +197,7 @@ class JestPlugin extends CiPlugin {
|
|
|
197
197
|
config._ddRequestErrorTags = this.getSessionRequestErrorTags()
|
|
198
198
|
config._ddItrCorrelationId = this.itrCorrelationId
|
|
199
199
|
config._ddIsEarlyFlakeDetectionEnabled = !!this.libraryConfig?.isEarlyFlakeDetectionEnabled
|
|
200
|
-
config.
|
|
200
|
+
config._ddEarlyFlakeDetectionRetryPolicy = this.libraryConfig?.earlyFlakeDetectionRetryPolicy
|
|
201
201
|
config._ddRepositoryRoot = this.repositoryRoot
|
|
202
202
|
config._ddIsFlakyTestRetriesEnabled = this.libraryConfig?.isFlakyTestRetriesEnabled ?? false
|
|
203
203
|
config._ddIsTestManagementTestsEnabled = this.libraryConfig?.isTestManagementEnabled ?? false
|
|
@@ -237,9 +237,8 @@ class JestPlugin extends CiPlugin {
|
|
|
237
237
|
|
|
238
238
|
const testSuiteMetadata = {
|
|
239
239
|
...getTestSuiteCommonTags(testCommand, frameworkVersion, testSuite, 'jest'),
|
|
240
|
-
|
|
241
|
-
...
|
|
242
|
-
...(itrSkippingEnabledTags !== undefined && itrSkippingEnabledTags !== null ? itrSkippingEnabledTags : {}),
|
|
240
|
+
...requestErrorTags,
|
|
241
|
+
...itrSkippingEnabledTags,
|
|
243
242
|
}
|
|
244
243
|
|
|
245
244
|
if (_ddUnskippable) {
|
|
@@ -300,23 +299,6 @@ class JestPlugin extends CiPlugin {
|
|
|
300
299
|
}
|
|
301
300
|
})
|
|
302
301
|
|
|
303
|
-
this.addSub('ci:jest:worker-report:telemetry', data => {
|
|
304
|
-
const telemetryEvents = JSON.parse(data)
|
|
305
|
-
for (const event of telemetryEvents) {
|
|
306
|
-
if (event.type === 'ciVisEvent') {
|
|
307
|
-
this.telemetry.ciVisEvent(event.name, event.testLevel, {
|
|
308
|
-
...event.tags,
|
|
309
|
-
testFramework: event.testFramework,
|
|
310
|
-
isUnsupportedCIProvider: event.isUnsupportedCIProvider,
|
|
311
|
-
})
|
|
312
|
-
} else if (event.type === 'count') {
|
|
313
|
-
this.telemetry.count(event.name, event.tags, event.value)
|
|
314
|
-
} else if (event.type === 'distribution') {
|
|
315
|
-
this.telemetry.distribution(event.name, event.tags, event.measure)
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
})
|
|
319
|
-
|
|
320
302
|
this.addSub('ci:jest:test-suite:finish', ({
|
|
321
303
|
status,
|
|
322
304
|
errorMessage,
|
|
@@ -15,6 +15,8 @@ const log = require('../../dd-trace/src/log')
|
|
|
15
15
|
* [[1, 2, 3], [2, 3, 5]]
|
|
16
16
|
* 2. An array of objects, e.g.
|
|
17
17
|
* [{ a: 1, b: 2, expected: 3 }, { a: 2, b: 3, expected: 5}]
|
|
18
|
+
*
|
|
19
|
+
* @param {unknown[]} testParameters `test.each` arguments
|
|
18
20
|
*/
|
|
19
21
|
function getFormattedJestTestParameters (testParameters) {
|
|
20
22
|
if (!testParameters || !testParameters.length) {
|
|
@@ -43,7 +45,8 @@ function getFormattedJestTestParameters (testParameters) {
|
|
|
43
45
|
|
|
44
46
|
// @fast-check/jest appends a random seed to the reported test name. A test name that keeps changing
|
|
45
47
|
// breaks some Test Optimization features, so normalize this narrow suffix regardless of import style.
|
|
46
|
-
|
|
48
|
+
// fast-check emits exactly one space before the suffix.
|
|
49
|
+
const SEED_SUFFIX_RE = / ?\(with seed=-?\d+\) ?$/i
|
|
47
50
|
|
|
48
51
|
function removeSeedSuffixFromTestName (testName) {
|
|
49
52
|
return testName.replace(SEED_SUFFIX_RE, '')
|
|
@@ -29,12 +29,13 @@ class KafkajsProducerPlugin extends ProducerPlugin {
|
|
|
29
29
|
/**
|
|
30
30
|
*
|
|
31
31
|
* @typedef {object} ProducerResponseItem
|
|
32
|
-
* @property {string}
|
|
32
|
+
* @property {string} topicName
|
|
33
33
|
* @property {number} partition
|
|
34
34
|
* @property {import('kafkajs/utils/long').Long} [offset]
|
|
35
35
|
* @property {import('kafkajs/utils/long').Long} [baseOffset]
|
|
36
36
|
*
|
|
37
37
|
* @param {ProducerResponseItem} response
|
|
38
|
+
* @param {string} [clusterId]
|
|
38
39
|
* @returns {ProducerBacklog}
|
|
39
40
|
*/
|
|
40
41
|
transformProduceResponse (response, clusterId) {
|
|
@@ -9,7 +9,7 @@ function getTokensFromLlmOutput (result) {
|
|
|
9
9
|
const { llmOutput } = result
|
|
10
10
|
if (!llmOutput) return tokens
|
|
11
11
|
|
|
12
|
-
const tokenUsage = llmOutput.tokenUsage || llmOutput.usage_metadata
|
|
12
|
+
const tokenUsage = llmOutput.tokenUsage || llmOutput.usage_metadata
|
|
13
13
|
if (!tokenUsage) return tokens
|
|
14
14
|
|
|
15
15
|
for (const tokenNames of [['input', 'prompt'], ['output', 'completion'], ['total']]) {
|
|
@@ -25,7 +25,7 @@ function getTokensFromLlmOutput (result) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// assign total_tokens again in case it was improperly set the first time, or was not on tokenUsage
|
|
28
|
-
tokens.total
|
|
28
|
+
tokens.total ||= tokens.input + tokens.output
|
|
29
29
|
|
|
30
30
|
return tokens
|
|
31
31
|
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { fileURLToPath } = require('node:url')
|
|
4
|
+
|
|
5
|
+
const { channel } = require('dc-polyfill')
|
|
6
|
+
|
|
3
7
|
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
4
8
|
const { storage } = require('../../datadog-core')
|
|
9
|
+
const log = require('../../dd-trace/src/log')
|
|
10
|
+
const {
|
|
11
|
+
sendWebdriverioWorkerMessage,
|
|
12
|
+
SUITE_FINISH,
|
|
13
|
+
} = require('../../datadog-instrumentations/src/mocha/webdriverio-protocol')
|
|
5
14
|
|
|
6
15
|
const {
|
|
7
16
|
TEST_STATUS,
|
|
@@ -34,6 +43,8 @@ const {
|
|
|
34
43
|
TEST_IS_MODIFIED,
|
|
35
44
|
TEST_FINAL_STATUS,
|
|
36
45
|
TEST_HAS_DYNAMIC_NAME,
|
|
46
|
+
TEST_FRAMEWORK_ADAPTER,
|
|
47
|
+
getTestSuiteExecutionKey,
|
|
37
48
|
isModifiedTest,
|
|
38
49
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
39
50
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
@@ -49,6 +60,94 @@ const {
|
|
|
49
60
|
TELEMETRY_TEST_SESSION,
|
|
50
61
|
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
51
62
|
|
|
63
|
+
const jasmineAdapterRunAsyncEndCh = 'tracing:orchestrion:@wdio/jasmine-framework:JasmineAdapter_run:asyncEnd'
|
|
64
|
+
const jasmineDoneCh = 'ci:webdriverio:jasmine:done'
|
|
65
|
+
const jasmineReporterSpecDoneEndCh = 'tracing:orchestrion:@wdio/jasmine-framework:JasmineReporter_specDone:end'
|
|
66
|
+
const jasmineReporterSpecStartedEndCh = 'tracing:orchestrion:@wdio/jasmine-framework:JasmineReporter_specStarted:end'
|
|
67
|
+
const jasmineReporterSuiteDoneEndCh = 'tracing:orchestrion:@wdio/jasmine-framework:JasmineReporter_suiteDone:end'
|
|
68
|
+
const jasmineReporterSuiteStartedEndCh = 'tracing:orchestrion:@wdio/jasmine-framework:JasmineReporter_suiteStarted:end'
|
|
69
|
+
const jasmineTestFunctionStartCh = 'tracing:orchestrion:@wdio/utils:testFrameworkFnWrapper:start'
|
|
70
|
+
const testFinishCh = channel('ci:mocha:test:finish')
|
|
71
|
+
const WEBDRIVERIO_JASMINE_ADAPTER = 'jasmine'
|
|
72
|
+
const workerFinishCh = channel('ci:mocha:worker:finish')
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @typedef {object} WebdriverioJasmineResult
|
|
76
|
+
* @property {string|undefined} id
|
|
77
|
+
* @property {string|undefined} description
|
|
78
|
+
* @property {Array<{message?: string, stack?: string}>|undefined} failedExpectations
|
|
79
|
+
* @property {string|undefined} file
|
|
80
|
+
* @property {string|undefined} filename
|
|
81
|
+
* @property {string|undefined} fullName
|
|
82
|
+
* @property {string|undefined} parentSuiteId
|
|
83
|
+
* @property {string|undefined} status
|
|
84
|
+
*/
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Normalizes a WebdriverIO Jasmine spec identifier to a filesystem path.
|
|
88
|
+
*
|
|
89
|
+
* @param {string|undefined} file
|
|
90
|
+
* @returns {string|undefined}
|
|
91
|
+
*/
|
|
92
|
+
function normalizeJasmineFile (file) {
|
|
93
|
+
return file?.startsWith('file://') ? fileURLToPath(file) : file
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Maps a Jasmine result status to the Test Optimization status vocabulary.
|
|
98
|
+
*
|
|
99
|
+
* @param {string|undefined} status
|
|
100
|
+
* @returns {'pass'|'fail'|'skip'}
|
|
101
|
+
*/
|
|
102
|
+
function getJasmineStatus (status) {
|
|
103
|
+
if (status === 'passed') return 'pass'
|
|
104
|
+
if (status === 'failed') return 'fail'
|
|
105
|
+
return 'skip'
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Converts Jasmine's failed-expectation shape to an Error.
|
|
110
|
+
*
|
|
111
|
+
* @param {WebdriverioJasmineResult} result
|
|
112
|
+
* @returns {Error|undefined}
|
|
113
|
+
*/
|
|
114
|
+
function getJasmineError (result) {
|
|
115
|
+
const failedExpectation = result.failedExpectations?.[0]
|
|
116
|
+
if (!failedExpectation) return
|
|
117
|
+
|
|
118
|
+
const error = new Error(failedExpectation.message)
|
|
119
|
+
if (failedExpectation.stack) {
|
|
120
|
+
error.stack = failedExpectation.stack
|
|
121
|
+
}
|
|
122
|
+
return error
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Resolves the spec file responsible for a run-level Jasmine failure.
|
|
127
|
+
*
|
|
128
|
+
* @param {WebdriverioJasmineResult|undefined} result
|
|
129
|
+
* @param {string[]} specs
|
|
130
|
+
* @returns {string|undefined}
|
|
131
|
+
*/
|
|
132
|
+
function getJasmineFailureFile (result, specs) {
|
|
133
|
+
const resultFile = normalizeJasmineFile(result?.file || result?.filename)
|
|
134
|
+
if (resultFile) {
|
|
135
|
+
return resultFile
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const stack = result?.failedExpectations?.[0]?.stack
|
|
139
|
+
if (stack) {
|
|
140
|
+
for (const spec of specs) {
|
|
141
|
+
const file = normalizeJasmineFile(spec)
|
|
142
|
+
if (file && stack.includes(file)) {
|
|
143
|
+
return file
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return specs.length === 1 ? normalizeJasmineFile(specs[0]) : undefined
|
|
149
|
+
}
|
|
150
|
+
|
|
52
151
|
class MochaPlugin extends CiPlugin {
|
|
53
152
|
static id = 'mocha'
|
|
54
153
|
|
|
@@ -58,6 +157,100 @@ class MochaPlugin extends CiPlugin {
|
|
|
58
157
|
this._testTitleToParams = {}
|
|
59
158
|
this.sourceRoot = process.cwd()
|
|
60
159
|
|
|
160
|
+
this.addSub('ci:mocha:worker:configuration', ({
|
|
161
|
+
libraryConfig,
|
|
162
|
+
repositoryRoot,
|
|
163
|
+
specs,
|
|
164
|
+
testFramework,
|
|
165
|
+
testFrameworkAdapter,
|
|
166
|
+
}) => {
|
|
167
|
+
this.libraryConfig = libraryConfig
|
|
168
|
+
this.testFramework = testFramework
|
|
169
|
+
this.testFrameworkAdapter = testFrameworkAdapter
|
|
170
|
+
this._setRepositoryRoot(repositoryRoot)
|
|
171
|
+
if (testFrameworkAdapter === WEBDRIVERIO_JASMINE_ADAPTER) {
|
|
172
|
+
this._webdriverioJasmineState = {
|
|
173
|
+
currentResult: undefined,
|
|
174
|
+
specs: specs || [],
|
|
175
|
+
suiteErrors: new Map(),
|
|
176
|
+
suiteFiles: new Map(),
|
|
177
|
+
suiteStatuses: new Map(),
|
|
178
|
+
tests: new Map(),
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
this.addBind(jasmineTestFunctionStartCh, (ctx) => {
|
|
184
|
+
if (this.testFrameworkAdapter !== WEBDRIVERIO_JASMINE_ADAPTER) {
|
|
185
|
+
return storage('legacy').getStore()
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const result = this._webdriverioJasmineState?.currentResult
|
|
189
|
+
const type = ctx.arguments?.[1]
|
|
190
|
+
if (type === 'Test' || (type === 'Hook' && result)) {
|
|
191
|
+
return this.#startWebdriverioJasmineTest(result)
|
|
192
|
+
}
|
|
193
|
+
return storage('legacy').getStore()
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
this.addSub(jasmineReporterSuiteStartedEndCh, (ctx) => {
|
|
197
|
+
if (this.testFrameworkAdapter === WEBDRIVERIO_JASMINE_ADAPTER) {
|
|
198
|
+
const suite = ctx.arguments?.[0]
|
|
199
|
+
const file = normalizeJasmineFile(suite?.filename)
|
|
200
|
+
if (suite?.id && file) {
|
|
201
|
+
this._webdriverioJasmineState.suiteFiles.set(suite.id, file)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
this.addSub(jasmineReporterSuiteDoneEndCh, (ctx) => {
|
|
207
|
+
if (this.testFrameworkAdapter === WEBDRIVERIO_JASMINE_ADAPTER) {
|
|
208
|
+
const state = this._webdriverioJasmineState
|
|
209
|
+
const suite = ctx.arguments?.[0]
|
|
210
|
+
const error = suite && getJasmineError(suite)
|
|
211
|
+
const file = normalizeJasmineFile(
|
|
212
|
+
suite?.filename ||
|
|
213
|
+
state.suiteFiles.get(suite?.id) ||
|
|
214
|
+
(state.specs.length === 1 ? state.specs[0] : undefined)
|
|
215
|
+
)
|
|
216
|
+
if (error && file) {
|
|
217
|
+
state.suiteErrors.set(file, error)
|
|
218
|
+
state.suiteStatuses.set(file, 'fail')
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
this.addSub(jasmineDoneCh, ({ result } = {}) => {
|
|
224
|
+
if (this.testFrameworkAdapter === WEBDRIVERIO_JASMINE_ADAPTER) {
|
|
225
|
+
const state = this._webdriverioJasmineState
|
|
226
|
+
const error = result && getJasmineError(result)
|
|
227
|
+
const file = getJasmineFailureFile(result, state.specs)
|
|
228
|
+
if (error && file) {
|
|
229
|
+
state.suiteErrors.set(file, error)
|
|
230
|
+
state.suiteStatuses.set(file, 'fail')
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
this.addSub(jasmineReporterSpecStartedEndCh, (ctx) => {
|
|
236
|
+
if (this.testFrameworkAdapter === WEBDRIVERIO_JASMINE_ADAPTER) {
|
|
237
|
+
this._webdriverioJasmineState.currentResult = ctx.arguments?.[0]
|
|
238
|
+
this.#startWebdriverioJasmineTest(ctx.arguments?.[0], ctx.self?._specs, ctx.self?.startedSuite)
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
this.addSub(jasmineReporterSpecDoneEndCh, (ctx) => {
|
|
243
|
+
if (this.testFrameworkAdapter === WEBDRIVERIO_JASMINE_ADAPTER) {
|
|
244
|
+
this.#finishWebdriverioJasmineTest(ctx.arguments?.[0], ctx.self?._specs)
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
this.addSub(jasmineAdapterRunAsyncEndCh, (ctx) => {
|
|
249
|
+
if (this.testFrameworkAdapter === WEBDRIVERIO_JASMINE_ADAPTER) {
|
|
250
|
+
this.#finishWebdriverioJasmineWorker(ctx)
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
|
|
61
254
|
this.addSub('ci:mocha:test-suite:code-coverage', ({ coverageFiles, suiteFile }) => {
|
|
62
255
|
if (!this.libraryConfig?.isCodeCoverageEnabled) {
|
|
63
256
|
return
|
|
@@ -88,23 +281,33 @@ class MochaPlugin extends CiPlugin {
|
|
|
88
281
|
})
|
|
89
282
|
|
|
90
283
|
this.addBind('ci:mocha:test-suite:start', (ctx) => {
|
|
91
|
-
const {
|
|
284
|
+
const {
|
|
285
|
+
testSuiteAbsolutePath,
|
|
286
|
+
testSuiteExecutionId,
|
|
287
|
+
isUnskippable,
|
|
288
|
+
isForcedToRun,
|
|
289
|
+
itrCorrelationId,
|
|
290
|
+
} = ctx
|
|
92
291
|
|
|
93
292
|
// If the test module span is undefined, the plugin has not been initialized correctly and we bail out
|
|
94
293
|
if (!this.testModuleSpan) {
|
|
95
294
|
return
|
|
96
295
|
}
|
|
97
296
|
const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.sourceRoot)
|
|
297
|
+
const testFramework = this.testFramework || this.constructor.id
|
|
98
298
|
const testSuiteMetadata = {
|
|
99
299
|
...getTestSuiteCommonTags(
|
|
100
300
|
this.command,
|
|
101
301
|
this.frameworkVersion,
|
|
102
302
|
testSuite,
|
|
103
|
-
|
|
303
|
+
testFramework
|
|
104
304
|
),
|
|
105
305
|
...this.getSessionRequestErrorTags(),
|
|
106
306
|
...this.getSessionItrSkippingEnabledTags(),
|
|
107
307
|
}
|
|
308
|
+
if (this.testFrameworkAdapter) {
|
|
309
|
+
testSuiteMetadata[TEST_FRAMEWORK_ADAPTER] = this.testFrameworkAdapter
|
|
310
|
+
}
|
|
108
311
|
if (isUnskippable) {
|
|
109
312
|
testSuiteMetadata[TEST_ITR_UNSKIPPABLE] = 'true'
|
|
110
313
|
this.telemetry.count(TELEMETRY_ITR_UNSKIPPABLE, { testLevel: 'suite' })
|
|
@@ -144,8 +347,9 @@ class MochaPlugin extends CiPlugin {
|
|
|
144
347
|
const store = storage('legacy').getStore()
|
|
145
348
|
ctx.parentStore = store
|
|
146
349
|
ctx.currentStore = { ...store, testSuiteSpan }
|
|
147
|
-
|
|
148
|
-
this.
|
|
350
|
+
const testSuiteKey = getTestSuiteExecutionKey(testSuite, testSuiteExecutionId)
|
|
351
|
+
this._testSuiteSpansByTestSuite.set(testSuiteKey, testSuiteSpan)
|
|
352
|
+
this._exportPendingWorkerTracesForTestSuite(testSuiteKey)
|
|
149
353
|
})
|
|
150
354
|
|
|
151
355
|
this.addSub('ci:mocha:test-suite:finish', ({ testSuiteSpan, status }) => {
|
|
@@ -203,8 +407,8 @@ class MochaPlugin extends CiPlugin {
|
|
|
203
407
|
return ctx.currentStore
|
|
204
408
|
})
|
|
205
409
|
|
|
206
|
-
this.addSub('ci:mocha:worker:finish', () => {
|
|
207
|
-
this.tracer._exporter.flush()
|
|
410
|
+
this.addSub('ci:mocha:worker:finish', ({ onDone } = {}) => {
|
|
411
|
+
this.tracer._exporter.flush(onDone)
|
|
208
412
|
})
|
|
209
413
|
|
|
210
414
|
this.addSub('ci:mocha:test:finish', ({
|
|
@@ -465,6 +669,138 @@ class MochaPlugin extends CiPlugin {
|
|
|
465
669
|
})
|
|
466
670
|
}
|
|
467
671
|
|
|
672
|
+
/**
|
|
673
|
+
* Starts a Jasmine test span around WebdriverIO's test-function wrapper.
|
|
674
|
+
*
|
|
675
|
+
* @param {WebdriverioJasmineResult|undefined} result
|
|
676
|
+
* @param {string[]} [specs]
|
|
677
|
+
* @param {{filename?: string}|undefined} currentSuite
|
|
678
|
+
* @returns {object|undefined}
|
|
679
|
+
*/
|
|
680
|
+
#startWebdriverioJasmineTest (result, specs, currentSuite) {
|
|
681
|
+
const state = this._webdriverioJasmineState
|
|
682
|
+
const currentStore = storage('legacy').getStore()
|
|
683
|
+
if (!state || !result?.id) {
|
|
684
|
+
return currentStore
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const existingTest = state.tests.get(result.id)
|
|
688
|
+
if (existingTest) {
|
|
689
|
+
return existingTest.currentStore
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const candidateSpecs = specs || state.specs
|
|
693
|
+
const testSuiteAbsolutePath = normalizeJasmineFile(
|
|
694
|
+
state.suiteFiles.get(result.parentSuiteId) ||
|
|
695
|
+
currentSuite?.filename ||
|
|
696
|
+
(candidateSpecs.length === 1 ? candidateSpecs[0] : undefined) ||
|
|
697
|
+
result.file ||
|
|
698
|
+
result.filename ||
|
|
699
|
+
candidateSpecs[0]
|
|
700
|
+
)
|
|
701
|
+
if (!testSuiteAbsolutePath) {
|
|
702
|
+
return currentStore
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
const span = this.startTestSpan({
|
|
706
|
+
testName: result.fullName || result.description,
|
|
707
|
+
testSuiteAbsolutePath,
|
|
708
|
+
title: result.description,
|
|
709
|
+
})
|
|
710
|
+
const testStore = { ...currentStore, span }
|
|
711
|
+
state.tests.set(result.id, {
|
|
712
|
+
currentStore: testStore,
|
|
713
|
+
span,
|
|
714
|
+
testSuiteAbsolutePath,
|
|
715
|
+
})
|
|
716
|
+
this.activeTestSpan = span
|
|
717
|
+
|
|
718
|
+
return testStore
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Finishes a Jasmine test after its reporter receives the final result.
|
|
723
|
+
*
|
|
724
|
+
* @param {WebdriverioJasmineResult|undefined} result
|
|
725
|
+
* @param {string[]} [specs]
|
|
726
|
+
* @returns {void}
|
|
727
|
+
*/
|
|
728
|
+
#finishWebdriverioJasmineTest (result, specs) {
|
|
729
|
+
const state = this._webdriverioJasmineState
|
|
730
|
+
if (!state || !result?.id) {
|
|
731
|
+
return
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
this.#startWebdriverioJasmineTest(result, specs)
|
|
735
|
+
const test = state.tests.get(result.id)
|
|
736
|
+
if (!test) {
|
|
737
|
+
return
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
const status = getJasmineStatus(result.status)
|
|
741
|
+
const error = getJasmineError(result)
|
|
742
|
+
if (error) {
|
|
743
|
+
test.span.setTag('error', error)
|
|
744
|
+
}
|
|
745
|
+
testFinishCh.publish({ span: test.span, status })
|
|
746
|
+
state.tests.delete(result.id)
|
|
747
|
+
if (state.currentResult?.id === result.id) {
|
|
748
|
+
state.currentResult = undefined
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
const previousStatus = state.suiteStatuses.get(test.testSuiteAbsolutePath)
|
|
752
|
+
if (status === 'fail' || !previousStatus || previousStatus === 'skip') {
|
|
753
|
+
state.suiteStatuses.set(test.testSuiteAbsolutePath, status)
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Reports Jasmine suite statuses and flushes worker traces before its run settles.
|
|
759
|
+
*
|
|
760
|
+
* @param {{
|
|
761
|
+
* resolveCallback?: (onDone: () => void) => void,
|
|
762
|
+
* rejectCallback?: (onDone: () => void) => void
|
|
763
|
+
* }} context
|
|
764
|
+
* @returns {void}
|
|
765
|
+
*/
|
|
766
|
+
#finishWebdriverioJasmineWorker (context) {
|
|
767
|
+
const state = this._webdriverioJasmineState
|
|
768
|
+
const results = []
|
|
769
|
+
const reportedFiles = new Set()
|
|
770
|
+
for (const [file, status] of state.suiteStatuses) {
|
|
771
|
+
const error = state.suiteErrors.get(file)
|
|
772
|
+
const result = { file, status }
|
|
773
|
+
if (error) {
|
|
774
|
+
result.error = {
|
|
775
|
+
message: error.message,
|
|
776
|
+
stack: error.stack,
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
results.push(result)
|
|
780
|
+
reportedFiles.add(file)
|
|
781
|
+
}
|
|
782
|
+
for (const spec of state.specs) {
|
|
783
|
+
const file = normalizeJasmineFile(spec)
|
|
784
|
+
if (!reportedFiles.has(file)) {
|
|
785
|
+
results.push({ file, status: 'skip' })
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
const waitForWorker = onDone => {
|
|
790
|
+
sendWebdriverioWorkerMessage({
|
|
791
|
+
origin: 'datadog',
|
|
792
|
+
name: SUITE_FINISH,
|
|
793
|
+
content: { results },
|
|
794
|
+
}, error => {
|
|
795
|
+
if (error) {
|
|
796
|
+
log.error('WebdriverIO Test Optimization IPC error', error)
|
|
797
|
+
}
|
|
798
|
+
}, () => workerFinishCh.publish({ onDone }))
|
|
799
|
+
}
|
|
800
|
+
context.resolveCallback = waitForWorker
|
|
801
|
+
context.rejectCallback = waitForWorker
|
|
802
|
+
}
|
|
803
|
+
|
|
468
804
|
startTestSpan (testInfo) {
|
|
469
805
|
const {
|
|
470
806
|
testName,
|