dd-trace 5.82.0 → 5.84.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/LICENSE-3rdparty.csv +77 -79
- package/ci/init.js +6 -6
- package/index.d.ts +213 -4
- package/loader-hook.mjs +1 -1
- package/package.json +59 -56
- package/packages/datadog-core/src/storage.js +7 -7
- package/packages/datadog-esbuild/index.js +6 -0
- package/packages/datadog-instrumentations/src/ai.js +7 -3
- package/packages/datadog-instrumentations/src/child_process.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +1 -1
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/instrumentations.js +4 -3
- package/packages/datadog-instrumentations/src/helpers/register.js +3 -7
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +6 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +73 -16
- package/packages/datadog-instrumentations/src/http/client.js +2 -2
- package/packages/datadog-instrumentations/src/jest.js +124 -64
- package/packages/datadog-instrumentations/src/koa.js +2 -1
- package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/worker.js +1 -1
- package/packages/datadog-instrumentations/src/mocha.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/mysql2.js +2 -2
- package/packages/datadog-instrumentations/src/net.js +13 -5
- package/packages/datadog-instrumentations/src/nyc.js +1 -1
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -4
- package/packages/datadog-instrumentations/src/pg.js +4 -2
- package/packages/datadog-instrumentations/src/playwright.js +15 -11
- package/packages/datadog-instrumentations/src/selenium.js +2 -2
- package/packages/datadog-instrumentations/src/undici.js +12 -1
- package/packages/datadog-plugin-aws-sdk/src/base.js +4 -4
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +2 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +2 -2
- package/packages/datadog-plugin-cucumber/src/index.js +35 -34
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -2
- package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -2
- package/packages/datadog-plugin-express/src/code_origin.js +21 -15
- package/packages/datadog-plugin-fastify/src/code_origin.js +17 -4
- package/packages/datadog-plugin-jest/src/index.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +26 -26
- package/packages/datadog-plugin-undici/src/index.js +305 -2
- package/packages/datadog-plugin-vitest/src/index.js +5 -5
- package/packages/datadog-shimmer/src/shimmer.js +2 -5
- package/packages/dd-trace/index.js +19 -0
- package/packages/dd-trace/src/agent/info.js +57 -0
- package/packages/dd-trace/src/agent/url.js +28 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +47 -7
- package/packages/dd-trace/src/appsec/rasp/index.js +2 -4
- package/packages/dd-trace/src/azure_metadata.js +8 -3
- package/packages/dd-trace/src/baggage.js +36 -11
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +5 -1
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +5 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +5 -11
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -4
- package/packages/dd-trace/src/ci-visibility/telemetry.js +6 -2
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
- package/packages/dd-trace/src/{config_defaults.js → config/defaults.js} +3 -3
- package/packages/dd-trace/src/{config-helper.js → config/helper.js} +88 -15
- package/packages/dd-trace/src/{config.js → config/index.js} +107 -46
- package/packages/dd-trace/src/config/remote_config.js +188 -19
- package/packages/dd-trace/src/{config_stable.js → config/stable.js} +20 -32
- package/packages/dd-trace/src/{supported-configurations.json → config/supported-configurations.json} +3 -1
- package/packages/dd-trace/src/crashtracking/crashtracker.js +2 -5
- package/packages/dd-trace/src/datastreams/processor.js +1 -1
- package/packages/dd-trace/src/datastreams/writer.js +2 -8
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -7
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +10 -11
- package/packages/dd-trace/src/debugger/devtools_client/send.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +1 -1
- package/packages/dd-trace/src/debugger/index.js +83 -15
- package/packages/dd-trace/src/dogstatsd.js +5 -11
- package/packages/dd-trace/src/encode/0.4.js +2 -2
- package/packages/dd-trace/src/exporter.js +1 -1
- package/packages/dd-trace/src/exporters/agent/index.js +5 -11
- package/packages/dd-trace/src/exporters/agent/writer.js +12 -16
- package/packages/dd-trace/src/exporters/common/{agent-info-exporter.js → buffering-exporter.js} +10 -37
- package/packages/dd-trace/src/exporters/common/docker.js +2 -2
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/common/util.js +2 -2
- package/packages/dd-trace/src/exporters/span-stats/index.js +3 -10
- package/packages/dd-trace/src/flare/index.js +1 -1
- package/packages/dd-trace/src/guardrails/telemetry.js +1 -1
- package/packages/dd-trace/src/index.js +4 -4
- package/packages/dd-trace/src/lambda/handler.js +2 -2
- package/packages/dd-trace/src/lambda/index.js +2 -2
- package/packages/dd-trace/src/lambda/runtime/patch.js +2 -2
- package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +8 -1
- package/packages/dd-trace/src/llmobs/index.js +2 -2
- package/packages/dd-trace/src/llmobs/noop.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +3 -4
- package/packages/dd-trace/src/llmobs/sdk.js +33 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +17 -7
- package/packages/dd-trace/src/llmobs/tagger.js +175 -1
- package/packages/dd-trace/src/llmobs/writers/base.js +118 -45
- package/packages/dd-trace/src/llmobs/writers/spans.js +4 -3
- package/packages/dd-trace/src/llmobs/writers/util.js +3 -9
- package/packages/dd-trace/src/log/index.js +50 -35
- package/packages/dd-trace/src/log/writer.js +13 -78
- package/packages/dd-trace/src/noop/proxy.js +3 -3
- package/packages/dd-trace/src/openfeature/writers/base.js +9 -16
- package/packages/dd-trace/src/openfeature/writers/util.js +3 -8
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +48 -6
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +45 -21
- package/packages/dd-trace/src/opentracing/span.js +4 -4
- package/packages/dd-trace/src/plugin_manager.js +8 -6
- package/packages/dd-trace/src/plugins/util/ci.js +5 -8
- package/packages/dd-trace/src/plugins/util/git-cache.js +3 -3
- package/packages/dd-trace/src/plugins/util/test.js +1 -1
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +41 -43
- package/packages/dd-trace/src/profiler.js +4 -39
- package/packages/dd-trace/src/profiling/config.js +74 -34
- package/packages/dd-trace/src/profiling/exporter_cli.js +5 -5
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +9 -2
- package/packages/dd-trace/src/profiling/index.js +1 -1
- package/packages/dd-trace/src/profiling/libuv-size.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +57 -2
- package/packages/dd-trace/src/proxy.js +34 -5
- package/packages/dd-trace/src/remote_config/capabilities.js +4 -0
- package/packages/dd-trace/src/remote_config/index.js +2 -7
- package/packages/dd-trace/src/ritm.js +8 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
- package/packages/dd-trace/src/serverless.js +2 -2
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/startup-log.js +7 -16
- package/packages/dd-trace/src/telemetry/endpoints.js +67 -5
- package/packages/dd-trace/src/telemetry/send-data.js +103 -4
- package/packages/dd-trace/src/telemetry/telemetry.js +229 -110
- package/vendor/dist/@isaacs/ttlcache/index.js +1 -1
- package/vendor/dist/esquery/index.js +1 -1
- package/vendor/dist/meriyah/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- /package/packages/dd-trace/src/{git_properties.js → config/git_properties.js} +0 -0
|
@@ -91,8 +91,11 @@ const wrappedWorkers = new WeakSet()
|
|
|
91
91
|
const testSuiteMockedFiles = new Map()
|
|
92
92
|
const testsToBeRetried = new Set()
|
|
93
93
|
const testSuiteAbsolutePathsWithFastCheck = new Set()
|
|
94
|
+
const testSuiteJestObjects = new Map()
|
|
94
95
|
|
|
95
96
|
const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
|
|
97
|
+
const ATR_RETRY_SUPPRESSION_FLAG = '_ddDisableAtrRetry'
|
|
98
|
+
const atrSuppressedErrors = new Map()
|
|
96
99
|
|
|
97
100
|
// based on https://github.com/facebook/jest/blob/main/packages/jest-circus/src/formatNodeAssertErrors.ts#L41
|
|
98
101
|
function formatJestError (errors) {
|
|
@@ -235,6 +238,28 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
235
238
|
}
|
|
236
239
|
}
|
|
237
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Jest mock state issue during test retries
|
|
243
|
+
*
|
|
244
|
+
* Problem:
|
|
245
|
+
* - Jest tracks mock function calls using internal state (call count, call arguments, etc.)
|
|
246
|
+
* - When a test is retried, the mock state is not automatically reset
|
|
247
|
+
* - This causes assertions like `toHaveBeenCalledTimes(1)` to fail because the call count
|
|
248
|
+
* accumulates across retries
|
|
249
|
+
*
|
|
250
|
+
* The solution is to clear all mocks before each retry attempt.
|
|
251
|
+
*/
|
|
252
|
+
resetMockState () {
|
|
253
|
+
try {
|
|
254
|
+
const jestObject = testSuiteJestObjects.get(this.testSuiteAbsolutePath)
|
|
255
|
+
if (jestObject?.clearAllMocks) {
|
|
256
|
+
jestObject.clearAllMocks()
|
|
257
|
+
}
|
|
258
|
+
} catch (e) {
|
|
259
|
+
log.warn('Error resetting mock state', e)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
238
263
|
// This function returns an array if the known tests are valid and null otherwise.
|
|
239
264
|
getKnownTestsForSuite (suiteKnownTests) {
|
|
240
265
|
// `suiteKnownTests` is `this.testEnvironmentOptions._ddKnownTests`,
|
|
@@ -337,8 +362,9 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
337
362
|
if (event.name === 'test_start') {
|
|
338
363
|
const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
|
|
339
364
|
if (testsToBeRetried.has(testName)) {
|
|
340
|
-
// This is needed because we're
|
|
365
|
+
// This is needed because we're retrying tests with the same name
|
|
341
366
|
this.resetSnapshotState()
|
|
367
|
+
this.resetMockState()
|
|
342
368
|
}
|
|
343
369
|
|
|
344
370
|
let isNewTest = false
|
|
@@ -378,7 +404,10 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
378
404
|
isNewTest = retriedTestsToNumAttempts.has(testName)
|
|
379
405
|
}
|
|
380
406
|
|
|
381
|
-
|
|
407
|
+
const willRunEfd = this.isEarlyFlakeDetectionEnabled && (isNewTest || isModified)
|
|
408
|
+
event.test[ATR_RETRY_SUPPRESSION_FLAG] = Boolean(isAttemptToFix || willRunEfd)
|
|
409
|
+
|
|
410
|
+
if (!isAttemptToFix && willRunEfd) {
|
|
382
411
|
numEfdRetry = retriedTestsToNumAttempts.get(testName)
|
|
383
412
|
retriedTestsToNumAttempts.set(testName, numEfdRetry + 1)
|
|
384
413
|
}
|
|
@@ -434,19 +463,22 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
434
463
|
|
|
435
464
|
const testFullName = this.getTestNameFromAddTestEvent(event, state)
|
|
436
465
|
const isSkipped = event.mode === 'todo' || event.mode === 'skip'
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
466
|
+
const isAttemptToFix = this.isTestManagementTestsEnabled &&
|
|
467
|
+
this.testManagementTestsForThisSuite?.attemptToFix?.includes(testFullName)
|
|
468
|
+
if (
|
|
469
|
+
isAttemptToFix &&
|
|
470
|
+
!isSkipped &&
|
|
471
|
+
!retriedTestsToNumAttempts.has(testFullName)
|
|
472
|
+
) {
|
|
473
|
+
retriedTestsToNumAttempts.set(testFullName, 0)
|
|
474
|
+
testsToBeRetried.add(testFullName)
|
|
475
|
+
this.retryTest({
|
|
476
|
+
jestEvent: event,
|
|
477
|
+
retryCount: testManagementAttemptToFixRetries,
|
|
478
|
+
retryType: 'Test Management (Attempt to Fix)'
|
|
479
|
+
})
|
|
448
480
|
}
|
|
449
|
-
if (this.isImpactedTestsEnabled) {
|
|
481
|
+
if (!isAttemptToFix && this.isImpactedTestsEnabled) {
|
|
450
482
|
const testStartLine = getTestLineStart(event.asyncError, this.testSuite)
|
|
451
483
|
const testEndLine = getTestEndLine(event.fn, testStartLine)
|
|
452
484
|
const isModified = isModifiedTest(
|
|
@@ -466,7 +498,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
466
498
|
})
|
|
467
499
|
}
|
|
468
500
|
}
|
|
469
|
-
if (this.isKnownTestsEnabled) {
|
|
501
|
+
if (!isAttemptToFix && this.isKnownTestsEnabled) {
|
|
470
502
|
const isNew = !this.knownTestsForThisSuite.includes(testFullName)
|
|
471
503
|
if (isNew && !isSkipped && !retriedTestsToNumAttempts.has(testFullName)) {
|
|
472
504
|
retriedTestsToNumAttempts.set(testFullName, 0)
|
|
@@ -488,6 +520,13 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
488
520
|
}
|
|
489
521
|
// restore in case it is retried
|
|
490
522
|
event.test.fn = originalTestFns.get(event.test)
|
|
523
|
+
// If ATR retry is being suppressed for this test (due to EFD or Attempt to Fix taking precedence)
|
|
524
|
+
// and the test has errors for this attempt, store the errors temporarily and clear them
|
|
525
|
+
// so Jest won't treat this attempt as failed (the real status will be reported after retries).
|
|
526
|
+
if (event.test?.[ATR_RETRY_SUPPRESSION_FLAG] && event.test.errors?.length) {
|
|
527
|
+
atrSuppressedErrors.set(event.test, event.test.errors)
|
|
528
|
+
event.test.errors = []
|
|
529
|
+
}
|
|
491
530
|
|
|
492
531
|
let attemptToFixPassed = false
|
|
493
532
|
let attemptToFixFailed = false
|
|
@@ -581,6 +620,12 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
581
620
|
await promises.isProbeReady
|
|
582
621
|
}
|
|
583
622
|
}
|
|
623
|
+
if (event.name === 'run_finish') {
|
|
624
|
+
for (const [test, errors] of atrSuppressedErrors) {
|
|
625
|
+
test.errors = errors
|
|
626
|
+
}
|
|
627
|
+
atrSuppressedErrors.clear()
|
|
628
|
+
}
|
|
584
629
|
if (event.name === 'test_skip' || event.name === 'test_todo') {
|
|
585
630
|
const testName = getJestTestName(event.test, this.getShouldStripSeedFromTestName())
|
|
586
631
|
testSkippedCh.publish({
|
|
@@ -843,7 +888,6 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
843
888
|
|
|
844
889
|
const {
|
|
845
890
|
results: {
|
|
846
|
-
success,
|
|
847
891
|
coverageMap,
|
|
848
892
|
numFailedTestSuites,
|
|
849
893
|
numFailedTests,
|
|
@@ -862,53 +906,6 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
862
906
|
// ignore errors
|
|
863
907
|
}
|
|
864
908
|
}
|
|
865
|
-
let status, error
|
|
866
|
-
|
|
867
|
-
if (success) {
|
|
868
|
-
status = numTotalTests === 0 && numTotalTestSuites === 0 ? 'skip' : 'pass'
|
|
869
|
-
} else {
|
|
870
|
-
status = 'fail'
|
|
871
|
-
error = new Error(`Failed test suites: ${numFailedTestSuites}. Failed tests: ${numFailedTests}`)
|
|
872
|
-
}
|
|
873
|
-
let timeoutId
|
|
874
|
-
|
|
875
|
-
// Pass the resolve callback to defer it to DC listener
|
|
876
|
-
const flushPromise = new Promise((resolve) => {
|
|
877
|
-
onDone = () => {
|
|
878
|
-
clearTimeout(timeoutId)
|
|
879
|
-
resolve()
|
|
880
|
-
}
|
|
881
|
-
})
|
|
882
|
-
|
|
883
|
-
const timeoutPromise = new Promise((resolve) => {
|
|
884
|
-
timeoutId = setTimeout(() => {
|
|
885
|
-
resolve('timeout')
|
|
886
|
-
}, FLUSH_TIMEOUT).unref()
|
|
887
|
-
})
|
|
888
|
-
|
|
889
|
-
testSessionFinishCh.publish({
|
|
890
|
-
status,
|
|
891
|
-
isSuitesSkipped,
|
|
892
|
-
isSuitesSkippingEnabled,
|
|
893
|
-
isCodeCoverageEnabled,
|
|
894
|
-
testCodeCoverageLinesTotal,
|
|
895
|
-
numSkippedSuites,
|
|
896
|
-
hasUnskippableSuites,
|
|
897
|
-
hasForcedToRunSuites,
|
|
898
|
-
error,
|
|
899
|
-
isEarlyFlakeDetectionEnabled,
|
|
900
|
-
isEarlyFlakeDetectionFaulty,
|
|
901
|
-
isTestManagementTestsEnabled,
|
|
902
|
-
onDone
|
|
903
|
-
})
|
|
904
|
-
|
|
905
|
-
const waitingResult = await Promise.race([flushPromise, timeoutPromise])
|
|
906
|
-
|
|
907
|
-
if (waitingResult === 'timeout') {
|
|
908
|
-
log.error('Timeout waiting for the tracer to flush')
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
numSkippedSuites = 0
|
|
912
909
|
|
|
913
910
|
/**
|
|
914
911
|
* If Early Flake Detection (EFD) is enabled the logic is as follows:
|
|
@@ -917,7 +914,6 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
917
914
|
* The rationale behind is the following: you may still be able to block your CI pipeline by gating
|
|
918
915
|
* on flakiness (the test will be considered flaky), but you may choose to unblock the pipeline too.
|
|
919
916
|
*/
|
|
920
|
-
|
|
921
917
|
if (isEarlyFlakeDetectionEnabled) {
|
|
922
918
|
let numFailedTestsToIgnore = 0
|
|
923
919
|
for (const testStatuses of newTestsTestStatuses.values()) {
|
|
@@ -975,6 +971,55 @@ function getCliWrapper (isNewJestVersion) {
|
|
|
975
971
|
}
|
|
976
972
|
}
|
|
977
973
|
|
|
974
|
+
// Determine session status after EFD and quarantine checks have potentially modified success
|
|
975
|
+
let status, error
|
|
976
|
+
if (result.results.success) {
|
|
977
|
+
status = numTotalTests === 0 && numTotalTestSuites === 0 ? 'skip' : 'pass'
|
|
978
|
+
} else {
|
|
979
|
+
status = 'fail'
|
|
980
|
+
error = new Error(`Failed test suites: ${numFailedTestSuites}. Failed tests: ${numFailedTests}`)
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
let timeoutId
|
|
984
|
+
|
|
985
|
+
// Pass the resolve callback to defer it to DC listener
|
|
986
|
+
const flushPromise = new Promise((resolve) => {
|
|
987
|
+
onDone = () => {
|
|
988
|
+
clearTimeout(timeoutId)
|
|
989
|
+
resolve()
|
|
990
|
+
}
|
|
991
|
+
})
|
|
992
|
+
|
|
993
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
994
|
+
timeoutId = setTimeout(() => {
|
|
995
|
+
resolve('timeout')
|
|
996
|
+
}, FLUSH_TIMEOUT).unref()
|
|
997
|
+
})
|
|
998
|
+
|
|
999
|
+
testSessionFinishCh.publish({
|
|
1000
|
+
status,
|
|
1001
|
+
isSuitesSkipped,
|
|
1002
|
+
isSuitesSkippingEnabled,
|
|
1003
|
+
isCodeCoverageEnabled,
|
|
1004
|
+
testCodeCoverageLinesTotal,
|
|
1005
|
+
numSkippedSuites,
|
|
1006
|
+
hasUnskippableSuites,
|
|
1007
|
+
hasForcedToRunSuites,
|
|
1008
|
+
error,
|
|
1009
|
+
isEarlyFlakeDetectionEnabled,
|
|
1010
|
+
isEarlyFlakeDetectionFaulty,
|
|
1011
|
+
isTestManagementTestsEnabled,
|
|
1012
|
+
onDone
|
|
1013
|
+
})
|
|
1014
|
+
|
|
1015
|
+
const waitingResult = await Promise.race([flushPromise, timeoutPromise])
|
|
1016
|
+
|
|
1017
|
+
if (waitingResult === 'timeout') {
|
|
1018
|
+
log.error('Timeout waiting for the tracer to flush')
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
numSkippedSuites = 0
|
|
1022
|
+
|
|
978
1023
|
return result
|
|
979
1024
|
}, {
|
|
980
1025
|
replaceGetter: true
|
|
@@ -1127,9 +1172,19 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
1127
1172
|
})
|
|
1128
1173
|
}
|
|
1129
1174
|
testSuiteFinishCh.publish({ status, errorMessage, testSuiteAbsolutePath: environment.testSuiteAbsolutePath })
|
|
1175
|
+
|
|
1176
|
+
// Cleanup per-suite state to avoid memory leaks
|
|
1177
|
+
testSuiteMockedFiles.delete(environment.testSuiteAbsolutePath)
|
|
1178
|
+
testSuiteJestObjects.delete(environment.testSuiteAbsolutePath)
|
|
1179
|
+
|
|
1130
1180
|
return suiteResults
|
|
1131
1181
|
}).catch(error => {
|
|
1132
1182
|
testSuiteFinishCh.publish({ status: 'fail', error, testSuiteAbsolutePath: environment.testSuiteAbsolutePath })
|
|
1183
|
+
|
|
1184
|
+
// Cleanup per-suite state to avoid memory leaks
|
|
1185
|
+
testSuiteMockedFiles.delete(environment.testSuiteAbsolutePath)
|
|
1186
|
+
testSuiteJestObjects.delete(environment.testSuiteAbsolutePath)
|
|
1187
|
+
|
|
1133
1188
|
throw error
|
|
1134
1189
|
})
|
|
1135
1190
|
})
|
|
@@ -1291,6 +1346,11 @@ addHook({
|
|
|
1291
1346
|
const result = _createJestObjectFor.apply(this, arguments)
|
|
1292
1347
|
const suiteFilePath = this._testPath || from
|
|
1293
1348
|
|
|
1349
|
+
// Store the jest object so we can access it later for resetting mock state
|
|
1350
|
+
if (suiteFilePath) {
|
|
1351
|
+
testSuiteJestObjects.set(suiteFilePath, result)
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1294
1354
|
shimmer.wrap(result, 'mock', mock => function (moduleName) {
|
|
1295
1355
|
// If the library is mocked with `jest.mock`, we don't want to bypass jest's own require engine
|
|
1296
1356
|
if (LIBRARIES_BYPASSING_JEST_REQUIRE_ENGINE.has(moduleName)) {
|
|
@@ -90,7 +90,8 @@ function wrapMiddleware (fn, layer) {
|
|
|
90
90
|
const req = ctx.req
|
|
91
91
|
|
|
92
92
|
const path = layer && layer.path
|
|
93
|
-
const route = typeof path === 'string' && !path.endsWith('(.*)') && !path.endsWith('([^/]*)') &&
|
|
93
|
+
const route = typeof path === 'string' && !path.endsWith('(.*)') && !path.endsWith('([^/]*)') &&
|
|
94
|
+
!path.includes('(?:') && path
|
|
94
95
|
|
|
95
96
|
enterChannel.publish({ req, name, route })
|
|
96
97
|
|
|
@@ -62,8 +62,8 @@ function wrapDispatchFunc (dispatchFunc) {
|
|
|
62
62
|
|
|
63
63
|
// light-my-request Response emits 'finish' when done
|
|
64
64
|
if (res.on && typeof res.on === 'function') {
|
|
65
|
-
res.
|
|
66
|
-
res.
|
|
65
|
+
res.once('finish', onFinish)
|
|
66
|
+
res.once('close', onFinish)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// Also wrap end() as fallback
|
|
@@ -5,7 +5,7 @@ const { addHook, channel } = require('../helpers/instrument')
|
|
|
5
5
|
const shimmer = require('../../../datadog-shimmer')
|
|
6
6
|
const { isMarkedAsUnskippable } = require('../../../datadog-plugin-jest/src/util')
|
|
7
7
|
const log = require('../../../dd-trace/src/log')
|
|
8
|
-
const { getEnvironmentVariable } = require('../../../dd-trace/src/config
|
|
8
|
+
const { getEnvironmentVariable } = require('../../../dd-trace/src/config/helper')
|
|
9
9
|
const {
|
|
10
10
|
getTestSuitePath,
|
|
11
11
|
MOCHA_WORKER_TRACE_PAYLOAD_CODE,
|
|
@@ -282,7 +282,7 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
|
|
|
282
282
|
if (config.isTestManagementTestsEnabled) {
|
|
283
283
|
ctx.onDone = onReceivedTestManagementTests
|
|
284
284
|
testManagementTestsCh.runStores(ctx, () => {})
|
|
285
|
-
} if (config.isImpactedTestsEnabled) {
|
|
285
|
+
} else if (config.isImpactedTestsEnabled) {
|
|
286
286
|
ctx.onDone = onReceivedImpactedTests
|
|
287
287
|
modifiedFilesCh.runStores(ctx, () => {})
|
|
288
288
|
} else if (config.isSuitesSkippingEnabled) {
|
|
@@ -67,7 +67,7 @@ addHook({
|
|
|
67
67
|
return run.apply(this, arguments)
|
|
68
68
|
}
|
|
69
69
|
// We flush when the worker ends with its test file (a mocha instance in a worker runs a single test file)
|
|
70
|
-
this.
|
|
70
|
+
this.once('end', () => {
|
|
71
71
|
workerFinishCh.publish()
|
|
72
72
|
})
|
|
73
73
|
this.on('test', getOnTestHandler(false))
|
|
@@ -39,7 +39,7 @@ addHook({ name: 'mysql', file: 'lib/Connection.js', versions: ['>=2'] }, Connect
|
|
|
39
39
|
return finishCh.runStores(ctx, cb, this, error, result)
|
|
40
40
|
})
|
|
41
41
|
} else {
|
|
42
|
-
res.
|
|
42
|
+
res.once('end', () => finishCh.publish(ctx))
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
return res
|
|
@@ -141,11 +141,11 @@ function wrapConnection (Connection, version) {
|
|
|
141
141
|
finishCh.runStores(ctx, onResult, this, ...arguments)
|
|
142
142
|
})
|
|
143
143
|
} else {
|
|
144
|
-
this.
|
|
144
|
+
this.once(errorMonitor, error => {
|
|
145
145
|
ctx.error = error
|
|
146
146
|
errorCh.publish(ctx)
|
|
147
147
|
})
|
|
148
|
-
this.
|
|
148
|
+
this.once('end', () => finishCh.publish(ctx))
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
this.execute = execute
|
|
@@ -101,7 +101,7 @@ function getOptions (args) {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
function setupListeners (socket, protocol, ctx, finishCh, errorCh) {
|
|
104
|
-
const events = [
|
|
104
|
+
const events = [errorMonitor, 'close', 'timeout']
|
|
105
105
|
|
|
106
106
|
const wrapListener = function (error) {
|
|
107
107
|
if (error) {
|
|
@@ -109,27 +109,35 @@ function setupListeners (socket, protocol, ctx, finishCh, errorCh) {
|
|
|
109
109
|
errorCh.publish(ctx)
|
|
110
110
|
}
|
|
111
111
|
finishCh.runStores(ctx, () => {})
|
|
112
|
+
cleanupOtherListeners()
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
const localListener = function () {
|
|
115
|
+
const localListener = function (error) {
|
|
115
116
|
ctx.socket = socket
|
|
116
117
|
connectionCh.publish(ctx)
|
|
118
|
+
if (error) {
|
|
119
|
+
ctx.error = error
|
|
120
|
+
errorCh.publish(ctx)
|
|
121
|
+
}
|
|
122
|
+
finishCh.runStores(ctx, () => {})
|
|
123
|
+
cleanupOtherListeners()
|
|
117
124
|
}
|
|
118
125
|
|
|
119
|
-
const
|
|
126
|
+
const cleanupOtherListeners = function () {
|
|
120
127
|
socket.removeListener('connect', localListener)
|
|
121
128
|
events.forEach(event => {
|
|
122
129
|
socket.removeListener(event, wrapListener)
|
|
123
|
-
socket.removeListener(event, cleanupListener)
|
|
124
130
|
})
|
|
125
131
|
}
|
|
126
132
|
|
|
133
|
+
// TODO: Identify why the connect listener should remove the other listeners.
|
|
127
134
|
if (protocol === 'tcp') {
|
|
128
135
|
socket.once('connect', localListener)
|
|
136
|
+
} else {
|
|
137
|
+
events.push('connect')
|
|
129
138
|
}
|
|
130
139
|
|
|
131
140
|
events.forEach(event => {
|
|
132
141
|
socket.once(event, wrapListener)
|
|
133
|
-
socket.once(event, cleanupListener)
|
|
134
142
|
})
|
|
135
143
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
|
-
const { getEnvironmentVariable } = require('../../dd-trace/src/config
|
|
4
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config/helper')
|
|
5
5
|
const { addHook, channel } = require('./helpers/instrument')
|
|
6
6
|
|
|
7
7
|
const codeCoverageWrapCh = channel('ci:nyc:wrap')
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
4
|
const tracer = require('../../dd-trace')
|
|
5
|
-
const {
|
|
5
|
+
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
6
6
|
const { addHook } = require('./helpers/instrument')
|
|
7
7
|
|
|
8
|
-
const otelSdkEnabled =
|
|
9
|
-
|
|
10
|
-
? !
|
|
8
|
+
const otelSdkEnabled = getValueFromEnvSources('DD_TRACE_OTEL_ENABLED') ||
|
|
9
|
+
getValueFromEnvSources('OTEL_SDK_DISABLED')
|
|
10
|
+
? !getValueFromEnvSources('OTEL_SDK_DISABLED')
|
|
11
11
|
: undefined
|
|
12
12
|
|
|
13
13
|
if (otelSdkEnabled) {
|
|
@@ -112,8 +112,10 @@ function wrapQuery (query) {
|
|
|
112
112
|
arguments[0] = pgQuery
|
|
113
113
|
|
|
114
114
|
const retval = query.apply(this, arguments)
|
|
115
|
-
|
|
116
|
-
const
|
|
115
|
+
|
|
116
|
+
const deperecated = Object.hasOwn(this, '_activeQuery')
|
|
117
|
+
const queryQueue = deperecated ? this._queryQueue : this.queryQueue
|
|
118
|
+
const activeQuery = deperecated ? this._activeQuery : this.activeQuery
|
|
117
119
|
|
|
118
120
|
const newQuery = queryQueue.at(-1) || activeQuery
|
|
119
121
|
|
|
@@ -11,8 +11,8 @@ const {
|
|
|
11
11
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
12
12
|
const log = require('../../dd-trace/src/log')
|
|
13
13
|
const {
|
|
14
|
-
|
|
15
|
-
} = require('../../dd-trace/src/config
|
|
14
|
+
getValueFromEnvSources
|
|
15
|
+
} = require('../../dd-trace/src/config/helper')
|
|
16
16
|
const { DD_MAJOR } = require('../../../version')
|
|
17
17
|
const { addHook, channel } = require('./helpers/instrument')
|
|
18
18
|
|
|
@@ -41,7 +41,7 @@ const testSuiteToTestStatuses = new Map()
|
|
|
41
41
|
const testSuiteToErrors = new Map()
|
|
42
42
|
const testsToTestStatuses = new Map()
|
|
43
43
|
|
|
44
|
-
const RUM_FLUSH_WAIT_TIME = Number(
|
|
44
|
+
const RUM_FLUSH_WAIT_TIME = Number(getValueFromEnvSources('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')) || 1000
|
|
45
45
|
|
|
46
46
|
let applyRepeatEachIndex = null
|
|
47
47
|
|
|
@@ -484,10 +484,11 @@ function dispatcherRunWrapper (run) {
|
|
|
484
484
|
|
|
485
485
|
function dispatcherRunWrapperNew (run) {
|
|
486
486
|
return function (testGroups) {
|
|
487
|
-
// Filter out disabled tests from testGroups before they get scheduled
|
|
487
|
+
// Filter out disabled tests from testGroups before they get scheduled,
|
|
488
|
+
// unless they have attemptToFix (in which case they should still run and be retried)
|
|
488
489
|
if (isTestManagementTestsEnabled) {
|
|
489
490
|
testGroups.forEach(group => {
|
|
490
|
-
group.tests = group.tests.filter(test => !test._ddIsDisabled)
|
|
491
|
+
group.tests = group.tests.filter(test => !test._ddIsDisabled || test._ddIsAttemptToFix)
|
|
491
492
|
})
|
|
492
493
|
// Remove empty groups
|
|
493
494
|
testGroups = testGroups.filter(group => group.tests.length > 0)
|
|
@@ -911,14 +912,16 @@ addHook({
|
|
|
911
912
|
const fileSuitesWithManagedTestsToProjects = new Map()
|
|
912
913
|
for (const test of allTests) {
|
|
913
914
|
const testProperties = getTestProperties(test)
|
|
914
|
-
// Disabled tests are skipped
|
|
915
|
+
// Disabled tests are skipped unless they have attemptToFix
|
|
915
916
|
if (testProperties.disabled) {
|
|
916
917
|
test._ddIsDisabled = true
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
918
|
+
if (!testProperties.attemptToFix) {
|
|
919
|
+
test.expectedStatus = 'skipped'
|
|
920
|
+
// setting test.expectedStatus to 'skipped' does not work for every case,
|
|
921
|
+
// so we need to filter out disabled tests in dispatcherRunWrapperNew,
|
|
922
|
+
// so they don't get to the workers
|
|
923
|
+
continue
|
|
924
|
+
}
|
|
922
925
|
}
|
|
923
926
|
if (testProperties.quarantined) {
|
|
924
927
|
test._ddIsQuarantined = true
|
|
@@ -947,6 +950,7 @@ addHook({
|
|
|
947
950
|
(test) => test._ddIsAttemptToFix,
|
|
948
951
|
[
|
|
949
952
|
(test) => test._ddIsQuarantined && '_ddIsQuarantined',
|
|
953
|
+
(test) => test._ddIsDisabled && '_ddIsDisabled',
|
|
950
954
|
'_ddIsAttemptToFix',
|
|
951
955
|
'_ddIsAttemptToFixRetry'
|
|
952
956
|
],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const shimmer = require('../../datadog-shimmer')
|
|
4
|
-
const {
|
|
4
|
+
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
5
5
|
const { addHook, channel } = require('./helpers/instrument')
|
|
6
6
|
|
|
7
7
|
const ciSeleniumDriverGetStartCh = channel('ci:selenium:driver:get')
|
|
@@ -17,7 +17,7 @@ if (window.DD_RUM && window.DD_RUM.stopSession) {
|
|
|
17
17
|
const IS_RUM_ACTIVE_SCRIPT = 'return !!window.DD_RUM'
|
|
18
18
|
|
|
19
19
|
const DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS =
|
|
20
|
-
Number(
|
|
20
|
+
Number(getValueFromEnvSources('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')) || 500
|
|
21
21
|
const DD_CIVISIBILITY_TEST_EXECUTION_ID_COOKIE_NAME = 'datadog-ci-visibility-test-execution-id'
|
|
22
22
|
|
|
23
23
|
// TODO: can we increase the supported version range?
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const tracingChannel = require('dc-polyfill').tracingChannel
|
|
4
4
|
|
|
5
5
|
const shimmer = require('../../datadog-shimmer')
|
|
6
|
+
const satisfies = require('../../../vendor/dist/semifies')
|
|
6
7
|
const {
|
|
7
8
|
addHook
|
|
8
9
|
} = require('./helpers/instrument')
|
|
@@ -10,9 +11,19 @@ const { createWrapFetch } = require('./helpers/fetch')
|
|
|
10
11
|
|
|
11
12
|
const ch = tracingChannel('apm:undici:fetch')
|
|
12
13
|
|
|
14
|
+
// Undici 5.0.x has a bug where fetch doesn't preserve AggregateError in the error cause chain
|
|
15
|
+
// Use native DC only for versions where error handling works correctly
|
|
16
|
+
const NATIVE_DC_VERSION = '>=4.7.0 <5.0.0 || >=5.1.0'
|
|
17
|
+
|
|
13
18
|
addHook({
|
|
14
19
|
name: 'undici',
|
|
15
20
|
versions: ['^4.4.1', '5', '>=6.0.0']
|
|
16
|
-
}, undici => {
|
|
21
|
+
}, (undici, version) => {
|
|
22
|
+
// For versions with working native DC, let the plugin subscribe directly
|
|
23
|
+
if (satisfies(version, NATIVE_DC_VERSION)) {
|
|
24
|
+
return undici
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// For older versions or those with buggy error handling, wrap fetch
|
|
17
28
|
return shimmer.wrap(undici, 'fetch', createWrapFetch(undici.Request, ch))
|
|
18
29
|
})
|
|
@@ -5,7 +5,7 @@ const ClientPlugin = require('../../dd-trace/src/plugins/client')
|
|
|
5
5
|
const { storage } = require('../../datadog-core')
|
|
6
6
|
const { isTrue } = require('../../dd-trace/src/util')
|
|
7
7
|
const { tagsFromRequest, tagsFromResponse } = require('../../dd-trace/src/payload-tagging')
|
|
8
|
-
const {
|
|
8
|
+
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
9
9
|
|
|
10
10
|
class BaseAwsSdkPlugin extends ClientPlugin {
|
|
11
11
|
static id = 'aws'
|
|
@@ -190,7 +190,7 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
190
190
|
|
|
191
191
|
isEnabled (request) {
|
|
192
192
|
const serviceId = this.serviceIdentifier.toUpperCase()
|
|
193
|
-
const envVarValue =
|
|
193
|
+
const envVarValue = getValueFromEnvSources(`DD_TRACE_AWS_SDK_${serviceId}_ENABLED`)
|
|
194
194
|
return envVarValue ? isTrue(envVarValue) : true
|
|
195
195
|
}
|
|
196
196
|
|
|
@@ -273,9 +273,9 @@ function normalizeConfig (config, serviceIdentifier) {
|
|
|
273
273
|
const serviceId = serviceIdentifier.toUpperCase()
|
|
274
274
|
const batchPropagationEnabled = isTrue(
|
|
275
275
|
specificConfig.batchPropagationEnabled ??
|
|
276
|
-
|
|
276
|
+
getValueFromEnvSources(`DD_TRACE_AWS_SDK_${serviceId}_BATCH_PROPAGATION_ENABLED`) ??
|
|
277
277
|
config.batchPropagationEnabled ??
|
|
278
|
-
|
|
278
|
+
getValueFromEnvSources('DD_TRACE_AWS_SDK_BATCH_PROPAGATION_ENABLED')
|
|
279
279
|
)
|
|
280
280
|
|
|
281
281
|
// Merge the specific config back into the main config
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
4
4
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
5
5
|
|
|
6
6
|
const spanContexts = new WeakMap()
|
|
@@ -89,7 +89,7 @@ function injectTraceContext (tracer, span, event) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
function batchLinksAreEnabled () {
|
|
92
|
-
const eh =
|
|
92
|
+
const eh = getValueFromEnvSources('DD_TRACE_AZURE_EVENTHUBS_BATCH_LINKS_ENABLED')
|
|
93
93
|
return eh !== 'false'
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
4
4
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
5
5
|
const spanContexts = new WeakMap()
|
|
6
6
|
|
|
@@ -90,7 +90,7 @@ function injectTraceContext (tracer, span, msg) {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
function batchLinksAreEnabled () {
|
|
93
|
-
const sb =
|
|
93
|
+
const sb = getValueFromEnvSources('DD_TRACE_AZURE_SERVICEBUS_BATCH_LINKS_ENABLED')
|
|
94
94
|
return sb !== 'false'
|
|
95
95
|
}
|
|
96
96
|
|