dd-trace 6.8.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 +9 -3
- 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/vitest.js +517 -0
- package/ci/test-optimization-validation/generated-files.js +38 -28
- package/ci/test-optimization-validation/generated-test-contract.js +8 -4
- 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 +300 -50
- 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/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 +40 -20
- package/ci/test-optimization-validation/runner-contract.js +79 -43
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +59 -5
- 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/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 +30 -34
- package/index.d.ts +98 -1
- package/init.js +1 -17
- package/initialize.mjs +11 -0
- package/loader-hook.mjs +6 -4
- package/package.json +5 -3
- package/packages/datadog-core/src/utils/src/parse-tags.js +0 -1
- package/packages/datadog-esbuild/src/utils.js +16 -1
- 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 +81 -5
- package/packages/datadog-instrumentations/src/cucumber.js +124 -47
- 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/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +33 -9
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +118 -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/router-helper.js +37 -6
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +979 -233
- package/packages/datadog-instrumentations/src/mocha/main.js +107 -9
- package/packages/datadog-instrumentations/src/mocha/utils.js +64 -42
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +25 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +12 -18
- 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 +173 -79
- package/packages/datadog-instrumentations/src/promise-js.js +4 -4
- package/packages/datadog-instrumentations/src/promise.js +3 -3
- package/packages/datadog-instrumentations/src/router.js +195 -19
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +43 -10
- package/packages/datadog-instrumentations/src/vitest-main.js +360 -56
- 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 +194 -18
- package/packages/datadog-instrumentations/src/when.js +3 -3
- package/packages/datadog-instrumentations/src/ws.js +5 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +59 -48
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -3
- 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/support.js +7 -4
- package/packages/datadog-plugin-electron/src/net.js +10 -4
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +1 -18
- package/packages/datadog-plugin-jest/src/util.js +2 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +2 -1
- package/packages/datadog-plugin-mocha/src/index.js +318 -1
- 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-vitest/src/index.js +95 -7
- package/packages/datadog-shimmer/src/shimmer.js +6 -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/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/hsts-header-missing-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +48 -476
- package/packages/dd-trace/src/appsec/sdk/track_event.js +9 -0
- 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-visibility-exporter.js +27 -13
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +17 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +21 -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/upload-coverage-report.js +21 -5
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +5 -1
- package/packages/dd-trace/src/config/generated-config-types.d.ts +2 -0
- package/packages/dd-trace/src/config/helper.js +2 -0
- package/packages/dd-trace/src/config/index.js +16 -5
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +8 -0
- 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/guardrails/apply-pm2-env.js +16 -0
- package/packages/dd-trace/src/guardrails/log.js +1 -10
- package/packages/dd-trace/src/llmobs/eval-metric.js +249 -0
- package/packages/dd-trace/src/llmobs/experiments/index.js +33 -25
- package/packages/dd-trace/src/llmobs/experiments/util.js +4 -2
- 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/bedrockruntime.js +5 -5
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +149 -68
- 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/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/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/periodic_metric_reader.js +1 -1
- package/packages/dd-trace/src/opentelemetry/span.js +4 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +21 -5
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +6 -0
- package/packages/dd-trace/src/plugins/util/git.js +6 -4
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +2 -2
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/stacktrace.js +3 -0
- package/packages/dd-trace/src/plugins/util/test.js +319 -75
- package/packages/dd-trace/src/plugins/util/url.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +23 -1
- 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/proxy.js +1 -0
- package/packages/dd-trace/src/ritm.js +5 -0
- 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/telemetry/logs/index.js +3 -0
- package/packages/dd-trace/src/telemetry/telemetry.js +1 -1
- package/vendor/dist/pprof-format/index.js +1 -1
- package/version.js +10 -8
- /package/packages/dd-trace/src/appsec/{blocked_templates.js → blocking/templates.js} +0 -0
|
@@ -11,11 +11,13 @@ const {
|
|
|
11
11
|
const { addHook, channel } = require('../helpers/instrument')
|
|
12
12
|
const shimmer = require('../../../datadog-shimmer')
|
|
13
13
|
const { isMarkedAsUnskippable } = require('../../../datadog-plugin-jest/src/util')
|
|
14
|
+
const { EMPTY_EFD_RETRY_POLICY } = require('../../../dd-trace/src/ci-visibility/efd-retry-policy')
|
|
14
15
|
const { writeCoverageBackfillToCache } = require('../../../dd-trace/src/ci-visibility/test-optimization-cache')
|
|
15
16
|
const log = require('../../../dd-trace/src/log')
|
|
16
17
|
const { getEnvironmentVariable } = require('../../../dd-trace/src/config/helper')
|
|
17
18
|
const {
|
|
18
19
|
getTestSuitePath,
|
|
20
|
+
MOCHA_WORKER_TELEMETRY_PAYLOAD_CODE,
|
|
19
21
|
MOCHA_WORKER_TRACE_PAYLOAD_CODE,
|
|
20
22
|
fromCoverageMapToCoverage,
|
|
21
23
|
getCoveredFilesFromCoverage,
|
|
@@ -28,6 +30,7 @@ const {
|
|
|
28
30
|
getTestCoverageLinesPercentage,
|
|
29
31
|
collectTestOptimizationSummariesFromTraces,
|
|
30
32
|
logTestOptimizationSummary,
|
|
33
|
+
TEST_IMPACT_ANALYSIS_ALL_TESTS_SKIPPED_MESSAGE,
|
|
31
34
|
getTestOptimizationRequestResults,
|
|
32
35
|
isModifiedTest,
|
|
33
36
|
} = require('../../../dd-trace/src/plugins/util/test')
|
|
@@ -66,12 +69,15 @@ let hasWarnedDeprecatedMochaVersion = false
|
|
|
66
69
|
const unskippableSuites = []
|
|
67
70
|
let suitesToSkip = []
|
|
68
71
|
let isSuitesSkipped = false
|
|
72
|
+
let areAllSuitesSkipped = false
|
|
69
73
|
let skippedSuites = []
|
|
70
74
|
let skippableSuitesCoverage = {}
|
|
71
75
|
let skippedSuitesCoverage = {}
|
|
72
76
|
let itrCorrelationId = ''
|
|
73
77
|
let isForcedToRun = false
|
|
74
|
-
const config = {
|
|
78
|
+
const config = {
|
|
79
|
+
earlyFlakeDetectionRetryPolicy: EMPTY_EFD_RETRY_POLICY,
|
|
80
|
+
}
|
|
75
81
|
|
|
76
82
|
// We'll preserve the original coverage here
|
|
77
83
|
const originalCoverageMap = createCoverageMap()
|
|
@@ -95,6 +101,7 @@ const mochaGlobalRunCh = channel('ci:mocha:global:run')
|
|
|
95
101
|
const testManagementTestsCh = channel('ci:mocha:test-management-tests')
|
|
96
102
|
const modifiedFilesCh = channel('ci:mocha:modified-files')
|
|
97
103
|
const workerReportTraceCh = channel('ci:mocha:worker-report:trace')
|
|
104
|
+
const workerReportTelemetryCh = channel('ci:mocha:worker-report:telemetry')
|
|
98
105
|
const testSessionStartCh = channel('ci:mocha:session:start')
|
|
99
106
|
const testSessionFinishCh = channel('ci:mocha:session:finish')
|
|
100
107
|
const itrSkippedSuitesCh = channel('ci:mocha:itr:skipped-suites')
|
|
@@ -227,6 +234,7 @@ function getMochaTestSessionCoverageFiles () {
|
|
|
227
234
|
|
|
228
235
|
function resetSuiteSkippingRunState () {
|
|
229
236
|
isSuitesSkipped = false
|
|
237
|
+
areAllSuitesSkipped = false
|
|
230
238
|
skippedSuites = []
|
|
231
239
|
skippableSuitesCoverage = {}
|
|
232
240
|
skippedSuitesCoverage = {}
|
|
@@ -357,7 +365,11 @@ function getOnEndHandler (isParallel, onDone) {
|
|
|
357
365
|
isParallel,
|
|
358
366
|
}, onDone)
|
|
359
367
|
|
|
360
|
-
logTestOptimizationSummary({
|
|
368
|
+
logTestOptimizationSummary({
|
|
369
|
+
attemptToFixExecutions,
|
|
370
|
+
newTestsWithDynamicNames,
|
|
371
|
+
extraSections: areAllSuitesSkipped ? [TEST_IMPACT_ANALYSIS_ALL_TESTS_SKIPPED_MESSAGE] : [],
|
|
372
|
+
})
|
|
361
373
|
loggedAttemptToFixTests.clear()
|
|
362
374
|
}
|
|
363
375
|
}
|
|
@@ -386,6 +398,57 @@ function isFailedTestReplayEnabled () {
|
|
|
386
398
|
return config.isTestDynamicInstrumentationEnabled && config.isDiEnabled
|
|
387
399
|
}
|
|
388
400
|
|
|
401
|
+
/**
|
|
402
|
+
* @typedef {object} MochaSuite
|
|
403
|
+
* @property {MochaSuite[]} suites
|
|
404
|
+
* @property {import('mocha').Test[]} tests
|
|
405
|
+
* @property {MochaSuite[]} _onlySuites
|
|
406
|
+
* @property {import('mocha').Test[]} _onlyTests
|
|
407
|
+
*/
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Mirrors Mocha 5's private exclusivity check.
|
|
411
|
+
*
|
|
412
|
+
* @param {MochaSuite} suite
|
|
413
|
+
* @returns {boolean}
|
|
414
|
+
*/
|
|
415
|
+
function hasOnly (suite) {
|
|
416
|
+
if (suite._onlyTests.length || suite._onlySuites.length) return true
|
|
417
|
+
|
|
418
|
+
for (const childSuite of suite.suites) {
|
|
419
|
+
if (hasOnly(childSuite)) return true
|
|
420
|
+
}
|
|
421
|
+
return false
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Mirrors Mocha 5's private exclusivity filter.
|
|
426
|
+
*
|
|
427
|
+
* @param {MochaSuite} suite
|
|
428
|
+
* @returns {boolean}
|
|
429
|
+
*/
|
|
430
|
+
function filterOnly (suite) {
|
|
431
|
+
if (suite._onlyTests.length) {
|
|
432
|
+
suite.tests = suite._onlyTests
|
|
433
|
+
suite.suites = []
|
|
434
|
+
} else {
|
|
435
|
+
suite.tests = []
|
|
436
|
+
|
|
437
|
+
for (const onlySuite of suite._onlySuites) {
|
|
438
|
+
if (hasOnly(onlySuite)) filterOnly(onlySuite)
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const filteredSuites = []
|
|
442
|
+
for (const childSuite of suite.suites) {
|
|
443
|
+
if (suite._onlySuites.includes(childSuite) || filterOnly(childSuite)) {
|
|
444
|
+
filteredSuites.push(childSuite)
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
suite.suites = filteredSuites
|
|
448
|
+
}
|
|
449
|
+
return suite.tests.length > 0 || suite.suites.length > 0
|
|
450
|
+
}
|
|
451
|
+
|
|
389
452
|
function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFinishRequest, localSuites) {
|
|
390
453
|
const ctx = {
|
|
391
454
|
isParallel,
|
|
@@ -418,6 +481,13 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
|
|
|
418
481
|
}
|
|
419
482
|
|
|
420
483
|
// We remove the suites that we skip through ITR
|
|
484
|
+
// Mocha normally applies exclusivity after this asynchronous configuration step.
|
|
485
|
+
if (typeof runner.suite.hasOnly === 'function') {
|
|
486
|
+
if (runner.suite.hasOnly()) runner.suite.filterOnly()
|
|
487
|
+
} else if (hasOnly(runner.suite)) {
|
|
488
|
+
filterOnly(runner.suite)
|
|
489
|
+
}
|
|
490
|
+
const numTestsToRun = runner.grepTotal(runner.suite)
|
|
421
491
|
const filteredSuites = getFilteredSuites(runner.suite.suites)
|
|
422
492
|
const { suitesToRun, suitesToSkipForRun } = filteredSuites
|
|
423
493
|
|
|
@@ -426,6 +496,7 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
|
|
|
426
496
|
log.debug('%d out of %d suites are going to run.', suitesToRun.length, runner.suite.suites.length)
|
|
427
497
|
|
|
428
498
|
runner.suite.suites = suitesToRun
|
|
499
|
+
areAllSuitesSkipped = isSuitesSkipped && numTestsToRun > 0 && runner.grepTotal(runner.suite) === 0
|
|
429
500
|
|
|
430
501
|
skippedSuites = [...filteredSuites.skippedSuites]
|
|
431
502
|
suitesToSkip = suitesToSkipForRun
|
|
@@ -489,8 +560,8 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
|
|
|
489
560
|
}
|
|
490
561
|
config.repositoryRoot = repositoryRoot
|
|
491
562
|
config.isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
|
|
492
|
-
config.
|
|
493
|
-
|
|
563
|
+
config.earlyFlakeDetectionRetryPolicy =
|
|
564
|
+
libraryConfig.earlyFlakeDetectionRetryPolicy ?? EMPTY_EFD_RETRY_POLICY
|
|
494
565
|
config.earlyFlakeDetectionFaultyThreshold = libraryConfig.earlyFlakeDetectionFaultyThreshold
|
|
495
566
|
config.isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
|
|
496
567
|
config.isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
|
|
@@ -978,6 +1049,8 @@ function onMessage (message) {
|
|
|
978
1049
|
attemptToFixExecutions,
|
|
979
1050
|
})
|
|
980
1051
|
workerReportTraceCh.publish(payload)
|
|
1052
|
+
} else if (messageCode === MOCHA_WORKER_TELEMETRY_PAYLOAD_CODE) {
|
|
1053
|
+
workerReportTelemetryCh.publish(payload)
|
|
981
1054
|
}
|
|
982
1055
|
}
|
|
983
1056
|
}
|
|
@@ -1042,7 +1115,7 @@ addHook({
|
|
|
1042
1115
|
versions: ['>=8.0.0'],
|
|
1043
1116
|
file: 'lib/nodejs/parallel-buffered-runner.js',
|
|
1044
1117
|
}, (ParallelBufferedRunner, frameworkVersion) => {
|
|
1045
|
-
shimmer.wrap(ParallelBufferedRunner.prototype, 'run', run => function (cb, { files }) {
|
|
1118
|
+
shimmer.wrap(ParallelBufferedRunner.prototype, 'run', run => function (cb, { files, options = {} }) {
|
|
1046
1119
|
if (!testFinishCh.hasSubscribers) {
|
|
1047
1120
|
return run.apply(this, arguments)
|
|
1048
1121
|
}
|
|
@@ -1088,10 +1161,11 @@ addHook({
|
|
|
1088
1161
|
}
|
|
1089
1162
|
}
|
|
1090
1163
|
isSuitesSkipped = skippedFiles.length > 0
|
|
1164
|
+
areAllSuitesSkipped = options.grep === undefined && files.length > 0 && filteredFiles.length === 0
|
|
1091
1165
|
skippedSuites = skippedFiles
|
|
1092
1166
|
skippedSuitesCoverage = getSkippedSuitesCoverageForRun()
|
|
1093
1167
|
writeCoverageBackfillToCache(skippedSuitesCoverage, getCoverageRootDir())
|
|
1094
|
-
run.apply(this, [onRunDone, { files: filteredFiles }])
|
|
1168
|
+
run.apply(this, [onRunDone, { files: filteredFiles, options }])
|
|
1095
1169
|
} else {
|
|
1096
1170
|
run.apply(this, arguments)
|
|
1097
1171
|
}
|
|
@@ -1110,9 +1184,34 @@ addHook({
|
|
|
1110
1184
|
name: 'mocha',
|
|
1111
1185
|
versions: ['>=8.0.0'],
|
|
1112
1186
|
file: 'lib/nodejs/buffered-worker-pool.js',
|
|
1113
|
-
}, (BufferedWorkerPoolPackage) => {
|
|
1187
|
+
}, (BufferedWorkerPoolPackage, frameworkVersion) => {
|
|
1114
1188
|
const { BufferedWorkerPool } = BufferedWorkerPoolPackage
|
|
1115
1189
|
|
|
1190
|
+
if (satisfies(frameworkVersion, '<9.2.0')) {
|
|
1191
|
+
// Shimmer is required because the worker environment must be changed before workerpool forks,
|
|
1192
|
+
// before any test lifecycle hook can run. Mocha added this worker ID itself in 9.2.0.
|
|
1193
|
+
shimmer.wrap(BufferedWorkerPool, 'create', create => function () {
|
|
1194
|
+
const pool = create.apply(this, arguments)
|
|
1195
|
+
|
|
1196
|
+
if (!testFinishCh.hasSubscribers) return pool
|
|
1197
|
+
|
|
1198
|
+
let workerId = 0
|
|
1199
|
+
shimmer.wrap(pool._pool, '_createWorkerHandler', createWorkerHandler => function () {
|
|
1200
|
+
this.forkOpts = {
|
|
1201
|
+
...this.forkOpts,
|
|
1202
|
+
env: {
|
|
1203
|
+
// eslint-disable-next-line eslint-rules/eslint-process-env
|
|
1204
|
+
...(this.forkOpts.env || process.env),
|
|
1205
|
+
MOCHA_WORKER_ID: String(workerId++),
|
|
1206
|
+
},
|
|
1207
|
+
}
|
|
1208
|
+
return createWorkerHandler.apply(this, arguments)
|
|
1209
|
+
})
|
|
1210
|
+
|
|
1211
|
+
return pool
|
|
1212
|
+
})
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1116
1215
|
shimmer.wrap(BufferedWorkerPool.prototype, 'run', run => async function (testSuiteAbsolutePath, workerArgs) {
|
|
1117
1216
|
if (!testFinishCh.hasSubscribers ||
|
|
1118
1217
|
(!config.isKnownTestsEnabled &&
|
|
@@ -1130,8 +1229,7 @@ addHook({
|
|
|
1130
1229
|
if (config.isKnownTestsEnabled) {
|
|
1131
1230
|
if (config.knownTests?.mocha) {
|
|
1132
1231
|
const testSuiteKnownTests = config.knownTests.mocha[testPath] || []
|
|
1133
|
-
newWorkerArgs.
|
|
1134
|
-
newWorkerArgs._ddEfdSlowTestRetries = config.earlyFlakeDetectionSlowTestRetries
|
|
1232
|
+
newWorkerArgs._ddEfdRetryPolicy = config.earlyFlakeDetectionRetryPolicy
|
|
1135
1233
|
newWorkerArgs._ddIsEfdEnabled = config.isEarlyFlakeDetectionEnabled
|
|
1136
1234
|
newWorkerArgs._ddIsKnownTestsEnabled = true
|
|
1137
1235
|
newWorkerArgs._ddKnownTests = {
|
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
const { performance } = require('node:perf_hooks')
|
|
4
4
|
|
|
5
|
+
const { getEnvironmentVariable } = require('../../../dd-trace/src/config/helper')
|
|
6
|
+
const {
|
|
7
|
+
getEfdRetryCountForDuration,
|
|
8
|
+
hasEfdRetries,
|
|
9
|
+
shouldSkipEfdRetry,
|
|
10
|
+
} = require('../../../dd-trace/src/ci-visibility/efd-retry-policy')
|
|
5
11
|
const {
|
|
6
12
|
getTestSuitePath,
|
|
7
13
|
DYNAMIC_NAME_RE,
|
|
8
|
-
|
|
9
|
-
getMaxEfdRetryCount,
|
|
14
|
+
recordTestManagementExecution,
|
|
10
15
|
recordAttemptToFixExecution,
|
|
11
16
|
logAttemptToFixTestExecution,
|
|
12
17
|
} = require('../../../dd-trace/src/plugins/util/test')
|
|
@@ -26,6 +31,8 @@ const isModifiedCh = channel('ci:mocha:test:is-modified')
|
|
|
26
31
|
// suite channels
|
|
27
32
|
const testSuiteErrorCh = channel('ci:mocha:test-suite:error')
|
|
28
33
|
|
|
34
|
+
/** @typedef {{ length: number, [index: number]: unknown } & Iterable<unknown>} ArgumentsLike */
|
|
35
|
+
|
|
29
36
|
const testToContext = new WeakMap()
|
|
30
37
|
const originalFns = new WeakMap()
|
|
31
38
|
const testToStartLine = new WeakMap()
|
|
@@ -40,6 +47,7 @@ const testsStatuses = new Map()
|
|
|
40
47
|
const efdRetryCountByTestFullName = new Map()
|
|
41
48
|
const efdSlowAbortedTests = new Set()
|
|
42
49
|
const attemptToFixExecutions = new Map()
|
|
50
|
+
const isMochaWorker = !!getEnvironmentVariable('MOCHA_WORKER_ID')
|
|
43
51
|
|
|
44
52
|
function waitForHitProbe () {
|
|
45
53
|
const promises = {}
|
|
@@ -133,19 +141,28 @@ function isNewTest (test, knownTests) {
|
|
|
133
141
|
return !testsForSuite.includes(testName)
|
|
134
142
|
}
|
|
135
143
|
|
|
136
|
-
|
|
144
|
+
/**
|
|
145
|
+
* @param {import('mocha').Test} test
|
|
146
|
+
* @param {number} duration
|
|
147
|
+
* @param {import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy} retryPolicy
|
|
148
|
+
*/
|
|
149
|
+
function setEfdRetryCountForTest (test, duration, retryPolicy) {
|
|
137
150
|
const testName = getTestFullName(test)
|
|
138
151
|
if (efdRetryCountByTestFullName.has(testName)) {
|
|
139
152
|
return
|
|
140
153
|
}
|
|
141
|
-
const retryCount =
|
|
154
|
+
const retryCount = getEfdRetryCountForDuration(duration, retryPolicy)
|
|
142
155
|
efdRetryCountByTestFullName.set(testName, retryCount)
|
|
143
156
|
if (retryCount === 0) {
|
|
144
157
|
efdSlowAbortedTests.add(testName)
|
|
145
158
|
}
|
|
146
159
|
}
|
|
147
160
|
|
|
148
|
-
|
|
161
|
+
/**
|
|
162
|
+
* @param {import('mocha').Test} test
|
|
163
|
+
* @param {import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy} retryPolicy
|
|
164
|
+
*/
|
|
165
|
+
function wrapOriginalEfdTest (test, retryPolicy) {
|
|
149
166
|
if (test._ddEfdDurationWrapped || typeof test.fn !== 'function') {
|
|
150
167
|
return
|
|
151
168
|
}
|
|
@@ -154,7 +171,7 @@ function wrapOriginalEfdTest (test, slowTestRetries) {
|
|
|
154
171
|
test.fn = shimmer.wrapFunction(originalFn, originalFn => function () {
|
|
155
172
|
const start = performance.now()
|
|
156
173
|
const recordDuration = () => {
|
|
157
|
-
setEfdRetryCountForTest(test, performance.now() - start,
|
|
174
|
+
setEfdRetryCountForTest(test, performance.now() - start, retryPolicy)
|
|
158
175
|
}
|
|
159
176
|
|
|
160
177
|
if (originalFn.length > 0) {
|
|
@@ -205,13 +222,14 @@ function disableMochaRetries (test) {
|
|
|
205
222
|
* _ddIsModified?: boolean,
|
|
206
223
|
* _ddIsNew?: boolean
|
|
207
224
|
* }} test
|
|
208
|
-
* @param {{
|
|
225
|
+
* @param {{
|
|
226
|
+
* isEarlyFlakeDetectionEnabled?: boolean,
|
|
227
|
+
* earlyFlakeDetectionRetryPolicy?: import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy
|
|
228
|
+
* }} config
|
|
209
229
|
* @returns {boolean}
|
|
210
230
|
*/
|
|
211
231
|
function isDatadogManagedRetryTest (test, config) {
|
|
212
|
-
return test._ddIsAttemptToFix ||
|
|
213
|
-
test._ddIsEfdRetry ||
|
|
214
|
-
(config.isEarlyFlakeDetectionEnabled && (test._ddIsNew || test._ddIsModified))
|
|
232
|
+
return test._ddIsAttemptToFix || isEarlyFlakeDetectionTest(test, config)
|
|
215
233
|
}
|
|
216
234
|
|
|
217
235
|
/**
|
|
@@ -223,22 +241,32 @@ function isDatadogManagedRetryTest (test, config) {
|
|
|
223
241
|
* _ddIsModified?: boolean,
|
|
224
242
|
* _ddIsNew?: boolean
|
|
225
243
|
* }} test
|
|
226
|
-
* @param {{
|
|
244
|
+
* @param {{
|
|
245
|
+
* isEarlyFlakeDetectionEnabled?: boolean,
|
|
246
|
+
* earlyFlakeDetectionRetryPolicy?: import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy
|
|
247
|
+
* }} config
|
|
227
248
|
* @returns {boolean}
|
|
228
249
|
*/
|
|
229
250
|
function isEarlyFlakeDetectionTest (test, config) {
|
|
230
251
|
return !test._ddIsAttemptToFix &&
|
|
231
252
|
!test._ddIsDisabled &&
|
|
232
253
|
config.isEarlyFlakeDetectionEnabled &&
|
|
254
|
+
hasEfdRetries(config.earlyFlakeDetectionRetryPolicy) &&
|
|
233
255
|
(test._ddIsEfdRetry || test._ddIsNew || test._ddIsModified)
|
|
234
256
|
}
|
|
235
257
|
|
|
236
|
-
|
|
258
|
+
/**
|
|
259
|
+
* @param {import('mocha').Test} test
|
|
260
|
+
* @param {number} numRetries
|
|
261
|
+
* @param {string[]} tags
|
|
262
|
+
* @param {import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy} retryPolicy
|
|
263
|
+
*/
|
|
264
|
+
function retryTest (test, numRetries, tags, retryPolicy) {
|
|
237
265
|
const suite = test.parent
|
|
238
266
|
const isEfdRetry = tags.includes('_ddIsEfdRetry')
|
|
239
267
|
disableMochaRetries(test)
|
|
240
268
|
if (isEfdRetry) {
|
|
241
|
-
wrapOriginalEfdTest(test,
|
|
269
|
+
wrapOriginalEfdTest(test, retryPolicy)
|
|
242
270
|
}
|
|
243
271
|
for (let retryIndex = 0; retryIndex < numRetries; retryIndex++) {
|
|
244
272
|
const clonedTest = test.clone()
|
|
@@ -250,7 +278,7 @@ function retryTest (test, numRetries, tags, slowTestRetries) {
|
|
|
250
278
|
if (typeof originalFn === 'function') {
|
|
251
279
|
clonedTest.fn = shimmer.wrapFunction(originalFn, originalFn => function (...args) {
|
|
252
280
|
const efdRetryCount = efdRetryCountByTestFullName.get(getTestFullName(clonedTest))
|
|
253
|
-
if (
|
|
281
|
+
if (shouldSkipEfdRetry(clonedTest._ddEfdRetryIndex, efdRetryCount)) {
|
|
254
282
|
clonedTest._ddShouldSkipEfdRetry = true
|
|
255
283
|
this.skip()
|
|
256
284
|
}
|
|
@@ -266,14 +294,6 @@ function retryTest (test, numRetries, tags, slowTestRetries) {
|
|
|
266
294
|
}
|
|
267
295
|
}
|
|
268
296
|
|
|
269
|
-
function getConfiguredEfdRetryCount (config) {
|
|
270
|
-
const { earlyFlakeDetectionSlowTestRetries } = config
|
|
271
|
-
if (!earlyFlakeDetectionSlowTestRetries || !Object.keys(earlyFlakeDetectionSlowTestRetries).length) {
|
|
272
|
-
return config.earlyFlakeDetectionNumRetries
|
|
273
|
-
}
|
|
274
|
-
return getMaxEfdRetryCount(earlyFlakeDetectionSlowTestRetries)
|
|
275
|
-
}
|
|
276
|
-
|
|
277
297
|
function getSuitesByTestFile (root) {
|
|
278
298
|
const suitesByTestFile = {}
|
|
279
299
|
function getSuites (suite) {
|
|
@@ -462,7 +482,7 @@ function getOnTestHandler (isMain) {
|
|
|
462
482
|
|
|
463
483
|
if (isEfdRetry) {
|
|
464
484
|
const efdRetryCount = efdRetryCountByTestFullName.get(getTestFullName(test))
|
|
465
|
-
if (
|
|
485
|
+
if (shouldSkipEfdRetry(test._ddEfdRetryIndex, efdRetryCount)) {
|
|
466
486
|
test.pending = true
|
|
467
487
|
test._ddShouldSkipEfdRetry = true
|
|
468
488
|
return
|
|
@@ -576,7 +596,7 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
576
596
|
!efdRetryCountByTestFullName.has(testName)
|
|
577
597
|
) {
|
|
578
598
|
const duration = test.duration > 0 ? test.duration : performance.now() - test._ddStartTime
|
|
579
|
-
setEfdRetryCountForTest(test, duration, config.
|
|
599
|
+
setEfdRetryCountForTest(test, duration, config.earlyFlakeDetectionRetryPolicy)
|
|
580
600
|
}
|
|
581
601
|
|
|
582
602
|
if (testsStatuses.get(testName)) {
|
|
@@ -587,7 +607,8 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
587
607
|
const testStatuses = testsStatuses.get(testName)
|
|
588
608
|
|
|
589
609
|
const isLastAttempt = testStatuses.length === config.testManagementAttemptToFixRetries + 1
|
|
590
|
-
const efdRetryCount = efdRetryCountByTestFullName.get(testName) ??
|
|
610
|
+
const efdRetryCount = efdRetryCountByTestFullName.get(testName) ??
|
|
611
|
+
config.earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
591
612
|
const isLastEfdRetry = testStatuses.length === efdRetryCount + 1
|
|
592
613
|
const isLastAtrAttempt = getIsLastRetry(test) || (config.isFlakyTestRetriesEnabled && status === 'pass')
|
|
593
614
|
|
|
@@ -642,6 +663,17 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
642
663
|
isFinalAttempt,
|
|
643
664
|
})
|
|
644
665
|
|
|
666
|
+
if (!isMochaWorker) {
|
|
667
|
+
recordTestManagementExecution({
|
|
668
|
+
testSuite: getTestSuitePath(test.file, process.cwd()),
|
|
669
|
+
testName: test.fullTitle(),
|
|
670
|
+
status,
|
|
671
|
+
isAttemptToFix: _ddIsAttemptToFix,
|
|
672
|
+
isDisabled: _ddIsDisabled,
|
|
673
|
+
isQuarantined: _ddIsQuarantined,
|
|
674
|
+
})
|
|
675
|
+
}
|
|
676
|
+
|
|
645
677
|
if (_ddIsAttemptToFix) {
|
|
646
678
|
recordAttemptToFixExecution(attemptToFixExecutions, {
|
|
647
679
|
testSuite: getTestSuitePath(test.file, process.cwd()),
|
|
@@ -788,7 +820,7 @@ function finishDeferredHookEnd (test) {
|
|
|
788
820
|
* @param {object} test - Mocha test currently owning the hook.
|
|
789
821
|
* @param {Promise<void>|undefined} failedTestReplayPromise - Pending Failed Test Replay wait, if any.
|
|
790
822
|
* @param {unknown} hookThis - Callback receiver.
|
|
791
|
-
* @param {
|
|
823
|
+
* @param {ArgumentsLike} args - Arguments passed by Mocha.
|
|
792
824
|
* @returns {unknown}
|
|
793
825
|
*/
|
|
794
826
|
function runFailedTestReplayHookUpCallback (fn, test, failedTestReplayPromise, hookThis, args) {
|
|
@@ -1004,17 +1036,12 @@ function getRunTestsWrapper (runTests, config) {
|
|
|
1004
1036
|
onDone: (isModified) => {
|
|
1005
1037
|
if (isModified) {
|
|
1006
1038
|
test._ddIsModified = true
|
|
1007
|
-
if (
|
|
1008
|
-
!test.isPending() &&
|
|
1009
|
-
!test._ddIsDisabled &&
|
|
1010
|
-
!test._ddIsAttemptToFix &&
|
|
1011
|
-
config.isEarlyFlakeDetectionEnabled
|
|
1012
|
-
) {
|
|
1039
|
+
if (!test.isPending() && isEarlyFlakeDetectionTest(test, config)) {
|
|
1013
1040
|
retryTest(
|
|
1014
1041
|
test,
|
|
1015
|
-
|
|
1042
|
+
config.earlyFlakeDetectionRetryPolicy.schedulingRetryCount,
|
|
1016
1043
|
['_ddIsModified', '_ddIsEfdRetry'],
|
|
1017
|
-
config.
|
|
1044
|
+
config.earlyFlakeDetectionRetryPolicy
|
|
1018
1045
|
)
|
|
1019
1046
|
}
|
|
1020
1047
|
}
|
|
@@ -1028,17 +1055,12 @@ function getRunTestsWrapper (runTests, config) {
|
|
|
1028
1055
|
suite.tests.forEach((test) => {
|
|
1029
1056
|
if (!test.isPending() && isNewTest(test, config.knownTests)) {
|
|
1030
1057
|
test._ddIsNew = true
|
|
1031
|
-
if (
|
|
1032
|
-
config.isEarlyFlakeDetectionEnabled &&
|
|
1033
|
-
!test._ddIsDisabled &&
|
|
1034
|
-
!test._ddIsAttemptToFix &&
|
|
1035
|
-
!test._ddIsModified
|
|
1036
|
-
) {
|
|
1058
|
+
if (!test._ddIsModified && isEarlyFlakeDetectionTest(test, config)) {
|
|
1037
1059
|
retryTest(
|
|
1038
1060
|
test,
|
|
1039
|
-
|
|
1061
|
+
config.earlyFlakeDetectionRetryPolicy.schedulingRetryCount,
|
|
1040
1062
|
['_ddIsNew', '_ddIsEfdRetry'],
|
|
1041
|
-
config.
|
|
1063
|
+
config.earlyFlakeDetectionRetryPolicy
|
|
1042
1064
|
)
|
|
1043
1065
|
}
|
|
1044
1066
|
}
|
|
@@ -7,12 +7,37 @@ const {
|
|
|
7
7
|
WEBDRIVERIO_WORKER_ORIGIN,
|
|
8
8
|
} = require('../../../dd-trace/src/ci-visibility/exporters/test-worker/webdriverio')
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Sends a message over WebdriverIO's worker IPC envelope.
|
|
12
|
+
*
|
|
13
|
+
* @param {object} message
|
|
14
|
+
* @param {(error?: Error) => void} [onError]
|
|
15
|
+
* @param {() => void} [onDone]
|
|
16
|
+
* @returns {void}
|
|
17
|
+
*/
|
|
18
|
+
function sendWebdriverioWorkerMessage (message, onError, onDone) {
|
|
19
|
+
if (!process.send || !process.connected) {
|
|
20
|
+
onError?.()
|
|
21
|
+
onDone?.()
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
process.send(createWebdriverioWorkerMessage(message), (error) => {
|
|
26
|
+
if (error) {
|
|
27
|
+
onError?.(error)
|
|
28
|
+
}
|
|
29
|
+
onDone?.()
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
10
33
|
module.exports = {
|
|
11
34
|
CONFIGURATION_REQUEST: 'dd:test-optimization:webdriverio:configuration:request',
|
|
12
35
|
CONFIGURATION_RESPONSE: 'dd:test-optimization:webdriverio:configuration:response',
|
|
13
36
|
createWebdriverioWorkerMessage,
|
|
37
|
+
sendWebdriverioWorkerMessage,
|
|
14
38
|
SUITE_FINISH: 'dd:test-optimization:webdriverio:test-suite:finish',
|
|
15
39
|
WORKER_READY: 'dd:test-optimization:webdriverio:worker:ready',
|
|
40
|
+
WORKER_READY_RESPONSE: 'dd:test-optimization:webdriverio:worker:ready:response',
|
|
16
41
|
WEBDRIVERIO_WORKER_ENV,
|
|
17
42
|
WEBDRIVERIO_WORKER_EVENT,
|
|
18
43
|
WEBDRIVERIO_WORKER_ORIGIN,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { addHook, channel } = require('../helpers/instrument')
|
|
4
4
|
const shimmer = require('../../../datadog-shimmer')
|
|
5
|
+
const { EMPTY_EFD_RETRY_POLICY } = require('../../../dd-trace/src/ci-visibility/efd-retry-policy')
|
|
5
6
|
const { getEnvironmentVariable } = require('../../../dd-trace/src/config/helper')
|
|
6
7
|
const log = require('../../../dd-trace/src/log')
|
|
7
8
|
const { DD_MAJOR } = require('../../../../version')
|
|
@@ -23,7 +24,7 @@ const {
|
|
|
23
24
|
const {
|
|
24
25
|
CONFIGURATION_REQUEST,
|
|
25
26
|
CONFIGURATION_RESPONSE,
|
|
26
|
-
|
|
27
|
+
sendWebdriverioWorkerMessage,
|
|
27
28
|
SUITE_FINISH,
|
|
28
29
|
WEBDRIVERIO_WORKER_ENV,
|
|
29
30
|
WORKER_READY,
|
|
@@ -35,7 +36,9 @@ const MINIMUM_MOCHA_VERSION = DD_MAJOR >= 6 ? '>=8.0.0' : '>=5.2.0'
|
|
|
35
36
|
const workerFinishCh = channel('ci:mocha:worker:finish')
|
|
36
37
|
const workerConfigurationCh = channel('ci:mocha:worker:configuration')
|
|
37
38
|
|
|
38
|
-
const config = {
|
|
39
|
+
const config = {
|
|
40
|
+
earlyFlakeDetectionRetryPolicy: EMPTY_EFD_RETRY_POLICY,
|
|
41
|
+
}
|
|
39
42
|
const runnerToFiles = new WeakMap()
|
|
40
43
|
const runnerToFailedHooks = new WeakMap()
|
|
41
44
|
const isWebdriverioWorker = !!getEnvironmentVariable(WEBDRIVERIO_WORKER_ENV)
|
|
@@ -50,19 +53,12 @@ let configurationRequestId = 0
|
|
|
50
53
|
* @returns {void}
|
|
51
54
|
*/
|
|
52
55
|
function sendWebdriverioMessage (message, onError, onDone) {
|
|
53
|
-
|
|
54
|
-
onError?.()
|
|
55
|
-
onDone?.()
|
|
56
|
-
return
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
process.send(createWebdriverioWorkerMessage(message), (error) => {
|
|
56
|
+
sendWebdriverioWorkerMessage(message, error => {
|
|
60
57
|
if (error) {
|
|
61
58
|
log.error('WebdriverIO Test Optimization IPC error', error)
|
|
62
|
-
onError?.()
|
|
63
59
|
}
|
|
64
|
-
|
|
65
|
-
})
|
|
60
|
+
onError?.()
|
|
61
|
+
}, onDone)
|
|
66
62
|
}
|
|
67
63
|
|
|
68
64
|
/**
|
|
@@ -76,12 +72,10 @@ function applyMochaOptions (options) {
|
|
|
76
72
|
config.isKnownTestsEnabled = true
|
|
77
73
|
config.isEarlyFlakeDetectionEnabled = options._ddIsEfdEnabled
|
|
78
74
|
config.knownTests = options._ddKnownTests
|
|
79
|
-
config.
|
|
80
|
-
config.earlyFlakeDetectionSlowTestRetries = options._ddEfdSlowTestRetries ?? {}
|
|
75
|
+
config.earlyFlakeDetectionRetryPolicy = options._ddEfdRetryPolicy ?? EMPTY_EFD_RETRY_POLICY
|
|
81
76
|
delete options._ddIsEfdEnabled
|
|
82
77
|
delete options._ddKnownTests
|
|
83
|
-
delete options.
|
|
84
|
-
delete options._ddEfdSlowTestRetries
|
|
78
|
+
delete options._ddEfdRetryPolicy
|
|
85
79
|
delete options._ddIsKnownTestsEnabled
|
|
86
80
|
}
|
|
87
81
|
if (options._ddIsImpactedTestsEnabled) {
|
|
@@ -245,7 +239,7 @@ function getWebdriverioHookTest (hook) {
|
|
|
245
239
|
*/
|
|
246
240
|
function adjustWebdriverioHookFailures (runner) {
|
|
247
241
|
let suppressedFailures = 0
|
|
248
|
-
for (const { test } of runnerToFailedHooks.get(runner)
|
|
242
|
+
for (const { test } of runnerToFailedHooks.get(runner)) {
|
|
249
243
|
if (isWebdriverioFailureSuppressed(test)) {
|
|
250
244
|
suppressedFailures++
|
|
251
245
|
}
|
|
@@ -287,7 +281,7 @@ function getWebdriverioSuiteResults (runner) {
|
|
|
287
281
|
}
|
|
288
282
|
})
|
|
289
283
|
|
|
290
|
-
for (const { file, test } of runnerToFailedHooks.get(runner)
|
|
284
|
+
for (const { file, test } of runnerToFailedHooks.get(runner)) {
|
|
291
285
|
const result = resultsByFile.get(file)
|
|
292
286
|
if (result && !isWebdriverioFailureSuppressed(test)) {
|
|
293
287
|
result.status = 'fail'
|
|
@@ -36,7 +36,7 @@ addHook({ name: 'mysql', file: 'lib/Connection.js', versions: ['>=2'] }, Connect
|
|
|
36
36
|
}
|
|
37
37
|
ctx.result = result
|
|
38
38
|
|
|
39
|
-
return finishCh.runStores(ctx, cb, this,
|
|
39
|
+
return finishCh.runStores(ctx, cb, this, ...arguments)
|
|
40
40
|
})
|
|
41
41
|
} else {
|
|
42
42
|
res.once('end', () => finishCh.publish(ctx))
|