dd-trace 5.96.0 → 5.98.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/index.d.ts +60 -2
- package/package.json +9 -7
- package/packages/datadog-esbuild/index.js +20 -9
- package/packages/datadog-instrumentations/src/child_process.js +7 -17
- package/packages/datadog-instrumentations/src/crypto.js +1 -2
- package/packages/datadog-instrumentations/src/cucumber.js +69 -4
- package/packages/datadog-instrumentations/src/cypress-config.js +318 -0
- package/packages/datadog-instrumentations/src/cypress.js +86 -4
- package/packages/datadog-instrumentations/src/dns.js +1 -2
- package/packages/datadog-instrumentations/src/express.js +4 -4
- package/packages/datadog-instrumentations/src/fs.js +27 -29
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +41 -13
- package/packages/datadog-instrumentations/src/helpers/hook.js +31 -6
- package/packages/datadog-instrumentations/src/helpers/hooks.js +12 -19
- package/packages/datadog-instrumentations/src/helpers/instrument.js +27 -13
- package/packages/datadog-instrumentations/src/helpers/register.js +103 -142
- package/packages/datadog-instrumentations/src/http/client.js +2 -3
- package/packages/datadog-instrumentations/src/http/server.js +2 -5
- package/packages/datadog-instrumentations/src/http2/client.js +1 -3
- package/packages/datadog-instrumentations/src/http2/server.js +1 -3
- package/packages/datadog-instrumentations/src/jest.js +117 -16
- package/packages/datadog-instrumentations/src/limitd-client.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/utils.js +12 -1
- package/packages/datadog-instrumentations/src/net.js +2 -8
- package/packages/datadog-instrumentations/src/pino.js +1 -1
- package/packages/datadog-instrumentations/src/playwright.js +4 -1
- package/packages/datadog-instrumentations/src/prisma.js +1 -2
- package/packages/datadog-instrumentations/src/redis.js +12 -6
- package/packages/datadog-instrumentations/src/selenium.js +4 -1
- package/packages/datadog-instrumentations/src/sequelize.js +1 -1
- package/packages/datadog-instrumentations/src/url.js +1 -3
- package/packages/datadog-instrumentations/src/vitest.js +5 -1
- package/packages/datadog-instrumentations/src/vm.js +1 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +5 -4
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
- package/packages/datadog-plugin-cucumber/src/index.js +13 -3
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +166 -6
- package/packages/datadog-plugin-cypress/src/index.js +59 -2
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +2 -7
- package/packages/datadog-plugin-graphql/src/resolve.js +1 -1
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-http/src/server.js +10 -2
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +10 -2
- package/packages/datadog-plugin-jest/src/index.js +4 -2
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +31 -4
- package/packages/datadog-plugin-mocha/src/index.js +5 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +3 -3
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +10 -16
- package/packages/datadog-plugin-openai/src/services.js +1 -0
- package/packages/datadog-plugin-pg/src/index.js +1 -1
- package/packages/datadog-plugin-tedious/src/index.js +1 -1
- package/packages/datadog-plugin-ws/src/close.js +1 -1
- package/packages/datadog-plugin-ws/src/receiver.js +1 -1
- package/packages/datadog-webpack/index.js +3 -3
- package/packages/dd-trace/index.js +12 -10
- package/packages/dd-trace/src/agent/url.js +2 -2
- package/packages/dd-trace/src/aiguard/sdk.js +26 -22
- package/packages/dd-trace/src/appsec/blocked_templates.js +4 -3
- package/packages/dd-trace/src/appsec/blocking.js +64 -33
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/remote_config.js +1 -0
- package/packages/dd-trace/src/appsec/sdk/index.js +4 -0
- package/packages/dd-trace/src/appsec/sdk/set_user.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/track_event.js +5 -5
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/utils.js +4 -2
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +6 -1
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +4 -0
- package/packages/dd-trace/src/config/defaults.js +315 -146
- package/packages/dd-trace/src/config/generated-config-types.d.ts +9 -1
- package/packages/dd-trace/src/config/helper.js +59 -10
- package/packages/dd-trace/src/config/index.js +587 -1496
- package/packages/dd-trace/src/config/parsers.js +256 -0
- package/packages/dd-trace/src/config/remote_config.js +59 -2
- package/packages/dd-trace/src/config/supported-configurations.json +406 -432
- package/packages/dd-trace/src/constants.js +1 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +7 -1
- package/packages/dd-trace/src/crashtracking/index.js +1 -7
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +5 -2
- package/packages/dd-trace/src/debugger/index.js +1 -1
- package/packages/dd-trace/src/dogstatsd.js +12 -9
- package/packages/dd-trace/src/encode/0.4.js +8 -7
- package/packages/dd-trace/src/encode/span-stats.js +4 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +7 -1
- package/packages/dd-trace/src/exporters/common/request.js +9 -0
- package/packages/dd-trace/src/exporters/common/writer.js +12 -2
- package/packages/dd-trace/src/heap_snapshots.js +3 -0
- package/packages/dd-trace/src/index.js +5 -2
- package/packages/dd-trace/src/lambda/runtime/ritm.js +6 -6
- package/packages/dd-trace/src/llmobs/index.js +4 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +5 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +60 -12
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +4 -2
- package/packages/dd-trace/src/llmobs/sdk.js +12 -8
- package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +9 -6
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -0
- package/packages/dd-trace/src/llmobs/writers/util.js +3 -0
- package/packages/dd-trace/src/log/index.js +20 -59
- package/packages/dd-trace/src/log/writer.js +7 -19
- package/packages/dd-trace/src/noop/proxy.js +8 -0
- package/packages/dd-trace/src/openfeature/remote_config.js +6 -1
- package/packages/dd-trace/src/opentelemetry/context_manager.js +6 -4
- package/packages/dd-trace/src/opentelemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +17 -2
- package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +14 -2
- package/packages/dd-trace/src/opentelemetry/otlp/trace.proto +358 -0
- package/packages/dd-trace/src/opentelemetry/otlp/trace_service.proto +78 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +75 -0
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +66 -0
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +332 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +9 -4
- package/packages/dd-trace/src/opentracing/tracer.js +9 -4
- package/packages/dd-trace/src/payload-tagging/config/index.js +6 -5
- package/packages/dd-trace/src/plugin_manager.js +8 -6
- package/packages/dd-trace/src/plugins/ci_plugin.js +4 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -0
- package/packages/dd-trace/src/plugins/plugin.js +11 -13
- package/packages/dd-trace/src/plugins/storage.js +2 -2
- package/packages/dd-trace/src/plugins/tracing.js +22 -5
- package/packages/dd-trace/src/plugins/util/test.js +2 -0
- package/packages/dd-trace/src/plugins/util/web.js +6 -88
- package/packages/dd-trace/src/process-tags/index.js +3 -0
- package/packages/dd-trace/src/profiler.js +27 -2
- package/packages/dd-trace/src/profiling/config.js +73 -241
- package/packages/dd-trace/src/profiling/exporter_cli.js +1 -4
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +6 -2
- package/packages/dd-trace/src/profiling/profiler.js +78 -109
- package/packages/dd-trace/src/profiling/profilers/events.js +2 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +89 -6
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +4 -1
- package/packages/dd-trace/src/propagation-hash/index.js +2 -1
- package/packages/dd-trace/src/proxy.js +40 -6
- package/packages/dd-trace/src/remote_config/index.js +3 -0
- package/packages/dd-trace/src/require-package-json.js +8 -4
- package/packages/dd-trace/src/ritm.js +58 -26
- package/packages/dd-trace/src/runtime_metrics/index.js +3 -0
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +18 -11
- package/packages/dd-trace/src/sampler.js +1 -1
- package/packages/dd-trace/src/service-naming/index.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/definition.js +4 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +15 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +24 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +60 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +17 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/websocket.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +17 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +11 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/websocket.js +6 -0
- package/packages/dd-trace/src/span_stats.js +5 -1
- package/packages/dd-trace/src/standalone/index.js +3 -0
- package/packages/dd-trace/src/telemetry/index.js +2 -3
- package/packages/dd-trace/src/telemetry/send-data.js +5 -19
- package/packages/dd-trace/src/telemetry/session-propagation.js +19 -44
- package/packages/dd-trace/src/telemetry/telemetry.js +28 -171
- package/packages/dd-trace/src/tracer.js +2 -2
- package/packages/dd-trace/src/util.js +0 -9
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +28 -6
- package/vendor/dist/protobufjs/index.js +1 -1
- package/packages/dd-trace/src/log/utils.js +0 -16
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// Capture real timers at module load time, before any test can install fake timers.
|
|
4
|
+
const realSetTimeout = setTimeout
|
|
5
|
+
|
|
3
6
|
const path = require('path')
|
|
4
7
|
const shimmer = require('../../datadog-shimmer')
|
|
5
8
|
const log = require('../../dd-trace/src/log')
|
|
@@ -8,6 +11,7 @@ const {
|
|
|
8
11
|
JEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
9
12
|
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
|
|
10
13
|
JEST_WORKER_TELEMETRY_PAYLOAD_CODE,
|
|
14
|
+
JEST_WORKER_QUARANTINE_PAYLOAD_CODE,
|
|
11
15
|
getTestLineStart,
|
|
12
16
|
getTestSuitePath,
|
|
13
17
|
getTestParametersString,
|
|
@@ -111,6 +115,8 @@ const efdDeterminedRetries = new Map()
|
|
|
111
115
|
const efdSlowAbortedTests = new Set()
|
|
112
116
|
// Tests added as EFD new-test candidates (not ATF, not impacted).
|
|
113
117
|
const efdNewTestCandidates = new Set()
|
|
118
|
+
// Tests that are genuinely new (not in known tests list).
|
|
119
|
+
const newTests = new Set()
|
|
114
120
|
const testSuiteAbsolutePathsWithFastCheck = new Set()
|
|
115
121
|
const testSuiteJestObjects = new Map()
|
|
116
122
|
|
|
@@ -118,6 +124,38 @@ const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
|
|
|
118
124
|
const ATR_RETRY_SUPPRESSION_FLAG = '_ddDisableAtrRetry'
|
|
119
125
|
const atrSuppressedErrors = new Map()
|
|
120
126
|
|
|
127
|
+
// Track quarantined tests whose errors were suppressed, keyed by "suite › testName"
|
|
128
|
+
const quarantinedFailingTests = new Set()
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Sends suppressed quarantine test names from a worker process to the main process.
|
|
132
|
+
* Supports both child_process (process.send) and worker_threads (parentPort.postMessage).
|
|
133
|
+
* Returns true if the data was sent (worker mode), false if in main process (runInBand).
|
|
134
|
+
*
|
|
135
|
+
* @param {string[]} testNames
|
|
136
|
+
* @returns {boolean}
|
|
137
|
+
*/
|
|
138
|
+
function sendQuarantineInfoToMainProcess (testNames) {
|
|
139
|
+
const payload = [JEST_WORKER_QUARANTINE_PAYLOAD_CODE, JSON.stringify(testNames)]
|
|
140
|
+
|
|
141
|
+
if (process.send) {
|
|
142
|
+
process.send(payload)
|
|
143
|
+
return true
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
const { isMainThread, parentPort } = require('node:worker_threads')
|
|
148
|
+
if (!isMainThread && parentPort) {
|
|
149
|
+
parentPort.postMessage(payload)
|
|
150
|
+
return true
|
|
151
|
+
}
|
|
152
|
+
} catch {
|
|
153
|
+
// Not in a worker context
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return false
|
|
157
|
+
}
|
|
158
|
+
|
|
121
159
|
// based on https://github.com/facebook/jest/blob/main/packages/jest-circus/src/formatNodeAssertErrors.ts#L41
|
|
122
160
|
function formatJestError (errors) {
|
|
123
161
|
let error
|
|
@@ -485,7 +523,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
485
523
|
}
|
|
486
524
|
|
|
487
525
|
if (this.isKnownTestsEnabled) {
|
|
488
|
-
isNewTest =
|
|
526
|
+
isNewTest = newTests.has(testName)
|
|
489
527
|
}
|
|
490
528
|
|
|
491
529
|
const willRunEfd = this.isEarlyFlakeDetectionEnabled && (isNewTest || isModified)
|
|
@@ -605,6 +643,9 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
605
643
|
}
|
|
606
644
|
if (!isAttemptToFix && this.isKnownTestsEnabled) {
|
|
607
645
|
const isNew = !this.knownTestsForThisSuite.includes(testFullName)
|
|
646
|
+
if (isNew && !isSkipped) {
|
|
647
|
+
newTests.add(testFullName)
|
|
648
|
+
}
|
|
608
649
|
if (isNew && !isSkipped && !retriedTestsToNumAttempts.has(testFullName)) {
|
|
609
650
|
if (DYNAMIC_NAME_RE.test(testFullName)) {
|
|
610
651
|
// Populated directly for runInBand; for parallel workers the main process
|
|
@@ -715,7 +756,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
715
756
|
let isEfdRetry = false
|
|
716
757
|
// We'll store the test statuses of the retries
|
|
717
758
|
if (this.isKnownTestsEnabled) {
|
|
718
|
-
const isNewTest =
|
|
759
|
+
const isNewTest = newTests.has(testName)
|
|
719
760
|
if (isNewTest) {
|
|
720
761
|
if (newTestsTestStatuses.has(testName)) {
|
|
721
762
|
newTestsTestStatuses.get(testName).push(status)
|
|
@@ -748,6 +789,18 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
748
789
|
const willBeRetriedByFailedTestReplay = numRetries > 0 && numTestExecutions - 1 < numRetries
|
|
749
790
|
const mightHitBreakpoint = this.isDiEnabled && numTestExecutions >= 2
|
|
750
791
|
|
|
792
|
+
// For quarantined tests, suppress errors so Jest doesn't count them as failures.
|
|
793
|
+
// This prevents --bail from stopping the test run on quarantined test failures.
|
|
794
|
+
// The actual status ('fail') is already captured above for dd-trace reporting.
|
|
795
|
+
// Only suppress on the final execution — not when ATR/EFD/ATF will retry the test.
|
|
796
|
+
if (!event.test?.[ATR_RETRY_SUPPRESSION_FLAG] && !willBeRetriedByFailedTestReplay) {
|
|
797
|
+
const quarantineCtx = testContexts.get(event.test)
|
|
798
|
+
if (quarantineCtx?.isQuarantined && event.test.errors?.length) {
|
|
799
|
+
quarantinedFailingTests.add(`${quarantineCtx.suite} › ${quarantineCtx.name}`)
|
|
800
|
+
event.test.errors = []
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
751
804
|
const ctx = testContexts.get(event.test)
|
|
752
805
|
if (!ctx) {
|
|
753
806
|
log.warn('"ci:jest:test_done": no context found for test "%s"', testName)
|
|
@@ -776,7 +829,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
776
829
|
// This means that tests retried with DI are BREAKPOINT_HIT_GRACE_PERIOD_MS slower at least.
|
|
777
830
|
if (status === 'fail' && mightHitBreakpoint) {
|
|
778
831
|
await new Promise(resolve => {
|
|
779
|
-
|
|
832
|
+
realSetTimeout(() => {
|
|
780
833
|
resolve()
|
|
781
834
|
}, BREAKPOINT_HIT_GRACE_PERIOD_MS)
|
|
782
835
|
})
|
|
@@ -805,12 +858,29 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
805
858
|
}
|
|
806
859
|
if (event.name === 'run_finish') {
|
|
807
860
|
for (const [test, errors] of atrSuppressedErrors) {
|
|
808
|
-
|
|
861
|
+
// Do not restore errors for quarantined tests — they should stay suppressed
|
|
862
|
+
// so Jest doesn't see the failure (prevents --bail from stopping the run).
|
|
863
|
+
const ctx = testContexts.get(test)
|
|
864
|
+
if (ctx?.isQuarantined) {
|
|
865
|
+
const testName = getJestTestName(test, this.getShouldStripSeedFromTestName())
|
|
866
|
+
quarantinedFailingTests.add(`${ctx.suite} › ${testName}`)
|
|
867
|
+
} else {
|
|
868
|
+
test.errors = errors
|
|
869
|
+
}
|
|
809
870
|
}
|
|
810
871
|
atrSuppressedErrors.clear()
|
|
872
|
+
|
|
873
|
+
// In parallel mode, send suppressed quarantine info to the main process
|
|
874
|
+
// so it can include them in the session summary.
|
|
875
|
+
// In runInBand mode, keep the set — it will be consumed by the session-level code directly.
|
|
876
|
+
if (quarantinedFailingTests.size > 0 && sendQuarantineInfoToMainProcess([...quarantinedFailingTests])) {
|
|
877
|
+
quarantinedFailingTests.clear()
|
|
878
|
+
}
|
|
879
|
+
|
|
811
880
|
efdDeterminedRetries.clear()
|
|
812
881
|
efdSlowAbortedTests.clear()
|
|
813
882
|
efdNewTestCandidates.clear()
|
|
883
|
+
newTests.clear()
|
|
814
884
|
retriedTestsToNumAttempts.clear()
|
|
815
885
|
attemptToFixRetriedTestsStatuses.clear()
|
|
816
886
|
testsToBeRetried.clear()
|
|
@@ -1246,6 +1316,7 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1246
1316
|
|
|
1247
1317
|
let numFailedQuarantinedTests = 0
|
|
1248
1318
|
let numFailedQuarantinedOrDisabledAttemptedToFixTests = 0
|
|
1319
|
+
let numSuppressedQuarantinedTests = 0
|
|
1249
1320
|
if (isTestManagementTestsEnabled) {
|
|
1250
1321
|
const failedTests = result
|
|
1251
1322
|
.results
|
|
@@ -1282,45 +1353,69 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1282
1353
|
}
|
|
1283
1354
|
}
|
|
1284
1355
|
|
|
1356
|
+
// Include quarantined tests whose errors were suppressed at test_done time.
|
|
1357
|
+
// These tests don't appear as failed in Jest's results because their errors were cleared
|
|
1358
|
+
// to prevent --bail from stopping the run, but they should still be counted for the summary.
|
|
1359
|
+
for (const name of quarantinedFailingTests) {
|
|
1360
|
+
if (!quarantineIgnoredNames.includes(name)) {
|
|
1361
|
+
numSuppressedQuarantinedTests++
|
|
1362
|
+
quarantineIgnoredNames.push(name)
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
quarantinedFailingTests.clear()
|
|
1366
|
+
|
|
1285
1367
|
// If every test that failed was quarantined, we'll consider the suite passed
|
|
1286
1368
|
// Note that if a test is attempted to fix,
|
|
1287
1369
|
// it's considered quarantined both if it's disabled and if it's quarantined
|
|
1288
1370
|
// (it'll run but its status is ignored)
|
|
1289
1371
|
// Skip if EFD block already flipped (to avoid logging twice)
|
|
1372
|
+
// Only use visible failures (from Jest results) for the flip check.
|
|
1373
|
+
// Suppressed quarantine failures are not in numFailedTests.
|
|
1374
|
+
const visibleQuarantineFailures = numFailedQuarantinedTests + numFailedQuarantinedOrDisabledAttemptedToFixTests
|
|
1290
1375
|
if (
|
|
1291
1376
|
!result.results.success &&
|
|
1292
1377
|
!mustNotFlipSuccess &&
|
|
1293
|
-
|
|
1294
|
-
result.results.numFailedTests ===
|
|
1295
|
-
numFailedQuarantinedTests + numFailedQuarantinedOrDisabledAttemptedToFixTests
|
|
1378
|
+
visibleQuarantineFailures !== 0 &&
|
|
1379
|
+
result.results.numFailedTests === visibleQuarantineFailures
|
|
1296
1380
|
) {
|
|
1297
1381
|
result.results.success = true
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
const totalQuarantineFailures = visibleQuarantineFailures + numSuppressedQuarantinedTests
|
|
1385
|
+
if (totalQuarantineFailures > 0) {
|
|
1386
|
+
if (ignoredFailuresSummary) {
|
|
1387
|
+
ignoredFailuresSummary.quarantineNames = quarantineIgnoredNames
|
|
1388
|
+
ignoredFailuresSummary.totalCount += totalQuarantineFailures
|
|
1389
|
+
} else {
|
|
1390
|
+
ignoredFailuresSummary = {
|
|
1391
|
+
efdNames: [],
|
|
1392
|
+
quarantineNames: quarantineIgnoredNames,
|
|
1393
|
+
totalCount: totalQuarantineFailures,
|
|
1394
|
+
}
|
|
1302
1395
|
}
|
|
1303
1396
|
}
|
|
1304
1397
|
}
|
|
1305
1398
|
|
|
1306
1399
|
// Combined check: if all failed tests are accounted for by EFD (flaky retries) and/or quarantine,
|
|
1307
1400
|
// we should consider the suite passed even when neither check alone covers all failures.
|
|
1401
|
+
// Only visible failures (in Jest results) are compared — suppressed quarantine failures
|
|
1402
|
+
// are already removed from numFailedTests at test_done time.
|
|
1308
1403
|
if (
|
|
1309
1404
|
!result.results.success &&
|
|
1310
1405
|
!mustNotFlipSuccess &&
|
|
1311
1406
|
(isEarlyFlakeDetectionEnabled || isTestManagementTestsEnabled)
|
|
1312
1407
|
) {
|
|
1313
|
-
const
|
|
1408
|
+
const visibleIgnoredFailures =
|
|
1314
1409
|
numEfdFailedTestsToIgnore + numFailedQuarantinedTests + numFailedQuarantinedOrDisabledAttemptedToFixTests
|
|
1315
1410
|
if (
|
|
1316
|
-
|
|
1317
|
-
result.results.numFailedTests ===
|
|
1411
|
+
visibleIgnoredFailures !== 0 &&
|
|
1412
|
+
result.results.numFailedTests === visibleIgnoredFailures
|
|
1318
1413
|
) {
|
|
1319
1414
|
result.results.success = true
|
|
1320
1415
|
ignoredFailuresSummary = {
|
|
1321
1416
|
efdNames: efdIgnoredNames,
|
|
1322
1417
|
quarantineNames: quarantineIgnoredNames,
|
|
1323
|
-
totalCount:
|
|
1418
|
+
totalCount: visibleIgnoredFailures + numSuppressedQuarantinedTests,
|
|
1324
1419
|
}
|
|
1325
1420
|
}
|
|
1326
1421
|
}
|
|
@@ -1345,7 +1440,7 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
1345
1440
|
})
|
|
1346
1441
|
|
|
1347
1442
|
const timeoutPromise = new Promise((resolve) => {
|
|
1348
|
-
timeoutId =
|
|
1443
|
+
timeoutId = realSetTimeout(() => {
|
|
1349
1444
|
resolve('timeout')
|
|
1350
1445
|
}, FLUSH_TIMEOUT).unref()
|
|
1351
1446
|
})
|
|
@@ -1856,6 +1951,12 @@ function onMessageWrapper (onMessage) {
|
|
|
1856
1951
|
workerReportTelemetryCh.publish(data)
|
|
1857
1952
|
return
|
|
1858
1953
|
}
|
|
1954
|
+
if (code === JEST_WORKER_QUARANTINE_PAYLOAD_CODE) { // quarantined test failures suppressed in worker
|
|
1955
|
+
for (const name of JSON.parse(data)) {
|
|
1956
|
+
quarantinedFailingTests.add(name)
|
|
1957
|
+
}
|
|
1958
|
+
return
|
|
1959
|
+
}
|
|
1859
1960
|
return onMessage.apply(this, arguments)
|
|
1860
1961
|
}
|
|
1861
1962
|
}
|
|
@@ -14,7 +14,7 @@ function wrapRequest (original) {
|
|
|
14
14
|
addHook({
|
|
15
15
|
name: 'limitd-client',
|
|
16
16
|
versions: ['>=2.8'],
|
|
17
|
-
file:
|
|
17
|
+
file: 'client.js',
|
|
18
18
|
}, LimitdClient => {
|
|
19
19
|
shimmer.wrap(LimitdClient.prototype, '_directRequest', wrapRequest)
|
|
20
20
|
shimmer.wrap(LimitdClient.prototype, '_retriedRequest', wrapRequest)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// Capture real timers at module load time, before any test can install fake timers.
|
|
4
|
+
const realSetTimeout = setTimeout
|
|
5
|
+
|
|
3
6
|
const { getTestSuitePath, DYNAMIC_NAME_RE } = require('../../../dd-trace/src/plugins/util/test')
|
|
4
7
|
const { channel } = require('../helpers/instrument')
|
|
5
8
|
const shimmer = require('../../../datadog-shimmer')
|
|
@@ -261,6 +264,14 @@ function getFinalStatus ({
|
|
|
261
264
|
}) {
|
|
262
265
|
// Note that intermediate executions DO NOT report a final status tag
|
|
263
266
|
|
|
267
|
+
// Intermediate EFD and ATF executions must not carry a final status, regardless of quarantine/disabled state
|
|
268
|
+
const isIntermediateExecution =
|
|
269
|
+
(isEfdRetry && !isLastEfdRetry) ||
|
|
270
|
+
(isAttemptToFix && !isLastAttemptToFix)
|
|
271
|
+
if (isIntermediateExecution) {
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
|
|
264
275
|
// If the test is quarantined or disabled, regardless of its actual execution result or active retry features,
|
|
265
276
|
// the final status of its last execution should be reported as 'skip'.
|
|
266
277
|
if (isQuarantined || isDisabled) {
|
|
@@ -293,7 +304,7 @@ function getOnTestEndHandler (config) {
|
|
|
293
304
|
// This means that tests retried with DI are BREAKPOINT_HIT_GRACE_PERIOD_MS slower at least.
|
|
294
305
|
if (test._ddShouldWaitForHitProbe || test._retriedTest?._ddShouldWaitForHitProbe) {
|
|
295
306
|
await new Promise((resolve) => {
|
|
296
|
-
|
|
307
|
+
realSetTimeout(() => {
|
|
297
308
|
resolve()
|
|
298
309
|
}, BREAKPOINT_HIT_GRACE_PERIOD_MS)
|
|
299
310
|
})
|
|
@@ -16,16 +16,10 @@ const errorTCPCh = channel('apm:net:tcp:error')
|
|
|
16
16
|
const readyCh = channel('apm:net:tcp:ready')
|
|
17
17
|
const connectionCh = channel('apm:net:tcp:connection')
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
addHook({ name: names }, (net, version, name) => {
|
|
19
|
+
addHook({ name: 'net' }, (net) => {
|
|
22
20
|
// explicitly require dns so that net gets an instrumented instance
|
|
23
21
|
// so that we don't miss the dns calls
|
|
24
|
-
|
|
25
|
-
require('dns')
|
|
26
|
-
} else {
|
|
27
|
-
require('node:dns')
|
|
28
|
-
}
|
|
22
|
+
require('node:dns')
|
|
29
23
|
|
|
30
24
|
shimmer.wrap(net.Socket.prototype, 'connect', connect => function () {
|
|
31
25
|
if (!startICPCh.hasSubscribers || !startTCPCh.hasSubscribers) {
|
|
@@ -97,7 +97,7 @@ addHook({ name: 'pino', versions: ['>=5.14.0 <6.8.0'] }, (pino) => {
|
|
|
97
97
|
return wrapped
|
|
98
98
|
})
|
|
99
99
|
|
|
100
|
-
addHook({ name: 'pino', versions: ['>=6.8.0'], patchDefault: false }, (pino
|
|
100
|
+
addHook({ name: 'pino', versions: ['>=6.8.0'], patchDefault: false }, (pino) => {
|
|
101
101
|
const mixinSym = pino.symbols.mixinSym
|
|
102
102
|
|
|
103
103
|
const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, pino))
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// Capture real timers at module load time, before any test can install fake timers.
|
|
4
|
+
const realSetTimeout = setTimeout
|
|
5
|
+
|
|
3
6
|
const satisfies = require('../../../vendor/dist/semifies')
|
|
4
7
|
|
|
5
8
|
const shimmer = require('../../datadog-shimmer')
|
|
@@ -1216,7 +1219,7 @@ addHook({
|
|
|
1216
1219
|
|
|
1217
1220
|
if (isRumActive) {
|
|
1218
1221
|
// Give some time RUM to flush data, similar to what we do in selenium
|
|
1219
|
-
await new Promise(resolve =>
|
|
1222
|
+
await new Promise(resolve => realSetTimeout(resolve, RUM_FLUSH_WAIT_TIME))
|
|
1220
1223
|
const url = page.url()
|
|
1221
1224
|
if (url) {
|
|
1222
1225
|
const domain = new URL(url).hostname
|
|
@@ -136,11 +136,10 @@ function resolveClientDbConfig (clientConfig, datasourceName, runtimeDbConfig) {
|
|
|
136
136
|
/**
|
|
137
137
|
* @param {unknown} runtime
|
|
138
138
|
* @param {string} versions
|
|
139
|
-
* @param {string} [name]
|
|
140
139
|
* @param {boolean} [isIitm]
|
|
141
140
|
* @returns {object}
|
|
142
141
|
*/
|
|
143
|
-
const prismaHook = (runtime, versions,
|
|
142
|
+
const prismaHook = (runtime, versions, isIitm) => {
|
|
144
143
|
/**
|
|
145
144
|
* @typedef {{ getPrismaClient?: (config: PrismaRuntimeConfig, ...args: unknown[]) => Function }} PrismaRuntime
|
|
146
145
|
*/
|
|
@@ -11,6 +11,8 @@ const finishCh = channel('apm:redis:command:finish')
|
|
|
11
11
|
const errorCh = channel('apm:redis:command:error')
|
|
12
12
|
|
|
13
13
|
let createClientUrl
|
|
14
|
+
let createClientName
|
|
15
|
+
const instanceInfo = new WeakMap()
|
|
14
16
|
|
|
15
17
|
function wrapAddCommand (addCommand) {
|
|
16
18
|
return function (command) {
|
|
@@ -21,7 +23,7 @@ function wrapAddCommand (addCommand) {
|
|
|
21
23
|
const name = command[0]
|
|
22
24
|
const args = command.slice(1)
|
|
23
25
|
|
|
24
|
-
const ctx = getStartCtx(this, name, args
|
|
26
|
+
const ctx = getStartCtx(this, name, args)
|
|
25
27
|
return startCh.runStores(ctx, () => {
|
|
26
28
|
const res = addCommand.apply(this, arguments)
|
|
27
29
|
|
|
@@ -36,17 +38,16 @@ function wrapCommandQueueClass (cls) {
|
|
|
36
38
|
const ret = class RedisCommandQueue extends cls {
|
|
37
39
|
constructor (...args) {
|
|
38
40
|
super(...args)
|
|
41
|
+
let url = { host: 'localhost', port: 6379 }
|
|
39
42
|
if (createClientUrl) {
|
|
40
43
|
try {
|
|
41
44
|
const parsed = new URL(createClientUrl)
|
|
42
|
-
|
|
43
|
-
this._url = { host: parsed.hostname, port: Number(parsed.port) || 6379 }
|
|
44
|
-
}
|
|
45
|
+
url = { host: parsed.hostname, port: Number(parsed.port) || 6379 }
|
|
45
46
|
} catch {
|
|
46
47
|
// ignore
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
+
instanceInfo.set(this, { connectionName: createClientName, url })
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
return ret
|
|
@@ -55,8 +56,10 @@ function wrapCommandQueueClass (cls) {
|
|
|
55
56
|
function wrapCreateClient (request) {
|
|
56
57
|
return function (opts) {
|
|
57
58
|
createClientUrl = opts && opts.url
|
|
59
|
+
createClientName = opts && opts.name
|
|
58
60
|
const ret = request.apply(this, arguments)
|
|
59
61
|
createClientUrl = undefined
|
|
62
|
+
createClientName = undefined
|
|
60
63
|
return ret
|
|
61
64
|
}
|
|
62
65
|
}
|
|
@@ -134,12 +137,15 @@ addHook({ name: 'redis', versions: ['>=0.12 <2.6'] }, redis => {
|
|
|
134
137
|
return redis
|
|
135
138
|
})
|
|
136
139
|
|
|
137
|
-
function getStartCtx (client, command, args
|
|
140
|
+
function getStartCtx (client, command, args) {
|
|
141
|
+
const { url, connectionName } = instanceInfo.get(client) || {}
|
|
142
|
+
|
|
138
143
|
return {
|
|
139
144
|
db: client.selected_db,
|
|
140
145
|
command,
|
|
141
146
|
args,
|
|
142
147
|
connectionOptions: client.connection_options || client.connection_option || client.connectionOption || url,
|
|
148
|
+
connectionName,
|
|
143
149
|
}
|
|
144
150
|
}
|
|
145
151
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// Capture real timers at module load time, before any test can install fake timers.
|
|
4
|
+
const realSetTimeout = setTimeout
|
|
5
|
+
|
|
3
6
|
const shimmer = require('../../datadog-shimmer')
|
|
4
7
|
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
5
8
|
const { addHook, channel } = require('./helpers/instrument')
|
|
@@ -66,7 +69,7 @@ addHook({
|
|
|
66
69
|
if (isRumActive) {
|
|
67
70
|
// We'll have time for RUM to flush the events (there's no callback to know when it's done)
|
|
68
71
|
await new Promise(resolve => {
|
|
69
|
-
|
|
72
|
+
realSetTimeout(() => {
|
|
70
73
|
resolve()
|
|
71
74
|
}, DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS)
|
|
72
75
|
})
|
|
@@ -6,7 +6,7 @@ const {
|
|
|
6
6
|
addHook,
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
8
|
|
|
9
|
-
addHook({ name: 'sequelize', versions: ['>=4'], file:
|
|
9
|
+
addHook({ name: 'sequelize', versions: ['>=4'], file: 'lib/sequelize.js' }, Sequelize => {
|
|
10
10
|
const startCh = channel('datadog:sequelize:query:start')
|
|
11
11
|
const finishCh = channel('datadog:sequelize:query:finish')
|
|
12
12
|
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
4
|
const { addHook, channel } = require('./helpers/instrument')
|
|
5
|
-
const names = ['url', 'node:url']
|
|
6
|
-
|
|
7
5
|
const parseFinishedChannel = channel('datadog:url:parse:finish')
|
|
8
6
|
const urlGetterChannel = channel('datadog:url:getter:finish')
|
|
9
7
|
const instrumentedGetters = ['host', 'origin', 'hostname']
|
|
10
8
|
|
|
11
|
-
addHook({ name:
|
|
9
|
+
addHook({ name: 'url' }, function (url) {
|
|
12
10
|
shimmer.wrap(url, 'parse', (parse) => {
|
|
13
11
|
return function wrappedParse (input) {
|
|
14
12
|
const parsedValue = parse.apply(this, arguments)
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
|
|
3
|
+
// Capture real timers at module load time, before any test can install fake timers.
|
|
4
|
+
const realSetTimeout = setTimeout
|
|
5
|
+
|
|
2
6
|
const path = require('node:path')
|
|
3
7
|
|
|
4
8
|
const shimmer = require('../../datadog-shimmer')
|
|
@@ -83,7 +87,7 @@ function getTestCommand () {
|
|
|
83
87
|
|
|
84
88
|
function waitForHitProbe () {
|
|
85
89
|
return new Promise(resolve => {
|
|
86
|
-
|
|
90
|
+
realSetTimeout(() => {
|
|
87
91
|
resolve()
|
|
88
92
|
}, BREAKPOINT_HIT_GRACE_PERIOD_MS)
|
|
89
93
|
})
|
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
4
|
const { channel, addHook } = require('./helpers/instrument')
|
|
5
|
-
const names = ['vm', 'node:vm']
|
|
6
|
-
|
|
7
5
|
const runScriptStartChannel = channel('datadog:vm:run-script:start')
|
|
8
6
|
const sourceTextModuleStartChannel = channel('datadog:vm:source-text-module:start')
|
|
9
7
|
|
|
10
|
-
addHook({ name:
|
|
8
|
+
addHook({ name: 'vm' }, function (vm) {
|
|
11
9
|
vm.Script = class extends vm.Script {
|
|
12
10
|
constructor (code) {
|
|
13
11
|
super(...arguments)
|
|
@@ -23,12 +23,13 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
23
23
|
return id
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/** @type {import('../../dd-trace/src/config/config-types').ConfigProperties['cloudPayloadTagging']} */
|
|
26
27
|
get cloudTaggingConfig () {
|
|
27
28
|
return this._tracerConfig.cloudPayloadTagging
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
get payloadTaggingRules () {
|
|
31
|
-
return this.cloudTaggingConfig.rules
|
|
32
|
+
return this.cloudTaggingConfig.rules?.aws?.[this.constructor.id]
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
constructor (...args) {
|
|
@@ -55,7 +56,6 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
55
56
|
|
|
56
57
|
const meta = {
|
|
57
58
|
'span.kind': 'client',
|
|
58
|
-
'service.name': this.serviceName(),
|
|
59
59
|
'aws.operation': operation,
|
|
60
60
|
'aws.region': awsRegion,
|
|
61
61
|
region: awsRegion,
|
|
@@ -69,6 +69,7 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
69
69
|
const span = this.startSpan(this.operationFromRequest(request), {
|
|
70
70
|
childOf,
|
|
71
71
|
meta,
|
|
72
|
+
service: this.serviceName(),
|
|
72
73
|
integrationName: 'aws-sdk',
|
|
73
74
|
}, ctx)
|
|
74
75
|
|
|
@@ -78,7 +79,7 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
78
79
|
this.requestInject(span, request)
|
|
79
80
|
})
|
|
80
81
|
|
|
81
|
-
if (this.constructor.isPayloadReporter && this.cloudTaggingConfig.
|
|
82
|
+
if (this.constructor.isPayloadReporter && this.cloudTaggingConfig.request) {
|
|
82
83
|
const maxDepth = this.cloudTaggingConfig.maxDepth
|
|
83
84
|
const requestTags = tagsFromRequest(this.payloadTaggingRules, request.params, { maxDepth })
|
|
84
85
|
span.addTags(requestTags)
|
|
@@ -215,7 +216,7 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
215
216
|
|
|
216
217
|
span.addTags(tags)
|
|
217
218
|
|
|
218
|
-
if (this.constructor.isPayloadReporter && this.cloudTaggingConfig.
|
|
219
|
+
if (this.constructor.isPayloadReporter && this.cloudTaggingConfig.response) {
|
|
219
220
|
const maxDepth = this.cloudTaggingConfig.maxDepth
|
|
220
221
|
const responseBody = this.extractResponseBody(response)
|
|
221
222
|
const responseTags = tagsFromResponse(this.payloadTaggingRules, responseBody, { maxDepth })
|
|
@@ -12,6 +12,7 @@ class EventBridge extends BaseAwsSdkPlugin {
|
|
|
12
12
|
return {
|
|
13
13
|
'resource.name': operation ? `${operation} ${params.source}` : params.source,
|
|
14
14
|
'aws.eventbridge.source': `${params.source}`,
|
|
15
|
+
'messaging.system': 'aws_eventbridge',
|
|
15
16
|
rulename: `${rulename}`,
|
|
16
17
|
}
|
|
17
18
|
}
|
|
@@ -11,6 +11,7 @@ class Redshift extends BaseAwsSdkPlugin {
|
|
|
11
11
|
return {
|
|
12
12
|
'resource.name': `${operation} ${params.ClusterIdentifier}`,
|
|
13
13
|
'aws.redshift.cluster_identifier': params.ClusterIdentifier,
|
|
14
|
+
'db.system': 'aws.redshift',
|
|
14
15
|
clusteridentifier: params.ClusterIdentifier,
|
|
15
16
|
}
|
|
16
17
|
}
|
|
@@ -100,6 +100,7 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
100
100
|
const tags = {
|
|
101
101
|
'resource.name': `${operation} ${params.QueueName || params.QueueUrl}`,
|
|
102
102
|
'aws.sqs.queue_name': params.QueueName || params.QueueUrl,
|
|
103
|
+
'messaging.system': 'aws_sqs',
|
|
103
104
|
queuename: queueName,
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// Capture real timers at module load time, before any test can install fake timers.
|
|
4
|
+
const realDateNow = Date.now.bind(Date)
|
|
5
|
+
const realSetTimeout = setTimeout
|
|
6
|
+
|
|
3
7
|
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
4
8
|
const { storage } = require('../../datadog-core')
|
|
5
9
|
const { getEnvironmentVariable, getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
@@ -33,6 +37,7 @@ const {
|
|
|
33
37
|
TEST_SOURCE_FILE,
|
|
34
38
|
TEST_SOURCE_START,
|
|
35
39
|
TEST_STATUS,
|
|
40
|
+
TEST_FINAL_STATUS,
|
|
36
41
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
37
42
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
38
43
|
const { COMPONENT, ERROR_MESSAGE } = require('../../dd-trace/src/constants')
|
|
@@ -229,7 +234,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
229
234
|
// Time we give the breakpoint to be hit
|
|
230
235
|
if (promises && this.runningTestProbe) {
|
|
231
236
|
promises.hitBreakpointPromise = new Promise((resolve) => {
|
|
232
|
-
|
|
237
|
+
realSetTimeout(resolve, BREAKPOINT_HIT_GRACE_PERIOD_MS)
|
|
233
238
|
})
|
|
234
239
|
}
|
|
235
240
|
|
|
@@ -252,8 +257,8 @@ class CucumberPlugin extends CiPlugin {
|
|
|
252
257
|
const { file, line, stackIndex } = probeInformation
|
|
253
258
|
this.runningTestProbe = { file, line }
|
|
254
259
|
this.testErrorStackIndex = stackIndex
|
|
255
|
-
const waitUntil =
|
|
256
|
-
while (
|
|
260
|
+
const waitUntil = realDateNow() + BREAKPOINT_SET_GRACE_PERIOD_MS
|
|
261
|
+
while (realDateNow() < waitUntil) {
|
|
257
262
|
// TODO: To avoid a race condition, we should wait until `probeInformation.setProbePromise` has resolved.
|
|
258
263
|
// However, Cucumber doesn't have a mechanism for waiting asyncrounously here, so for now, we'll have to
|
|
259
264
|
// fall back to a fixed syncronous delay.
|
|
@@ -303,11 +308,16 @@ class CucumberPlugin extends CiPlugin {
|
|
|
303
308
|
isDisabled,
|
|
304
309
|
isQuarantined,
|
|
305
310
|
isModified,
|
|
311
|
+
finalStatus,
|
|
306
312
|
}) => {
|
|
307
313
|
const statusTag = isStep ? 'step.status' : TEST_STATUS
|
|
308
314
|
|
|
309
315
|
span.setTag(statusTag, status)
|
|
310
316
|
|
|
317
|
+
if (finalStatus) {
|
|
318
|
+
span.setTag(TEST_FINAL_STATUS, finalStatus)
|
|
319
|
+
}
|
|
320
|
+
|
|
311
321
|
if (isNew) {
|
|
312
322
|
span.setTag(TEST_IS_NEW, 'true')
|
|
313
323
|
if (isEfdRetry) {
|