dd-trace 6.8.0 → 6.10.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 +140 -42
- package/index.d.ts +140 -1
- package/init.js +1 -17
- package/initialize.mjs +11 -0
- package/loader-hook.mjs +6 -4
- package/package.json +8 -5
- 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/confluentinc-kafka-javascript.js +111 -6
- 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/pool-acquire.js +629 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +34 -9
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +199 -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 +62 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +83 -1
- 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 +980 -234
- package/packages/datadog-instrumentations/src/mocha/main.js +108 -10
- package/packages/datadog-instrumentations/src/mocha/utils.js +66 -50
- 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 +46 -16
- package/packages/datadog-instrumentations/src/mysql2.js +119 -18
- package/packages/datadog-instrumentations/src/next.js +155 -23
- package/packages/datadog-instrumentations/src/openai.js +14 -0
- package/packages/datadog-instrumentations/src/path-to-regexp.js +67 -1
- package/packages/datadog-instrumentations/src/pg.js +209 -11
- 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 +85 -13
- package/packages/datadog-instrumentations/src/vitest-main.js +528 -72
- package/packages/datadog-instrumentations/src/vitest-util.js +106 -12
- package/packages/datadog-instrumentations/src/vitest-worker.js +382 -40
- package/packages/datadog-instrumentations/src/webdriverio.js +212 -22
- package/packages/datadog-instrumentations/src/when.js +3 -3
- package/packages/datadog-instrumentations/src/ws.js +5 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +12 -6
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +59 -48
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -5
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -5
- 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 +51 -47
- package/packages/datadog-plugin-cypress/src/support.js +7 -4
- package/packages/datadog-plugin-electron/src/net.js +10 -4
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +31 -17
- 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 +6 -22
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/producer.js +5 -3
- package/packages/datadog-plugin-kafkajs/src/utils.js +65 -7
- package/packages/datadog-plugin-mocha/src/index.js +832 -4
- package/packages/datadog-plugin-mysql/src/index.js +37 -0
- package/packages/datadog-plugin-next/src/index.js +51 -21
- package/packages/datadog-plugin-openai/src/tracing.js +4 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +278 -69
- package/packages/datadog-plugin-openai-agents/src/processor.js +16 -4
- package/packages/datadog-plugin-pg/src/index.js +66 -1
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +103 -27
- package/packages/datadog-plugin-ws/src/util.js +2 -1
- 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/api_security/normalized-route.js +453 -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 +228 -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/carrier.js +356 -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 +5 -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 +18 -0
- package/packages/dd-trace/src/datastreams/context.js +6 -1
- package/packages/dd-trace/src/datastreams/manager.js +5 -1
- package/packages/dd-trace/src/datastreams/pathway.js +23 -22
- package/packages/dd-trace/src/datastreams/processor.js +3 -2
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
- package/packages/dd-trace/src/guardrails/apply-pm2-env.js +16 -0
- package/packages/dd-trace/src/guardrails/log.js +1 -10
- package/packages/dd-trace/src/llmobs/constants/tags.js +5 -0
- 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/index.js +34 -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/span_processor.js +16 -0
- package/packages/dd-trace/src/llmobs/tagger.js +96 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +18 -0
- package/packages/dd-trace/src/llmobs/util.js +78 -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/opentracing/propagation/text_map.js +126 -120
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +4 -8
- package/packages/dd-trace/src/plugin_manager.js +2 -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/{datadog-plugin-jest/src/util.js → dd-trace/src/plugins/util/jest.js} +3 -62
- package/packages/dd-trace/src/plugins/util/stacktrace.js +3 -0
- package/packages/dd-trace/src/plugins/util/test.js +397 -74
- package/packages/dd-trace/src/plugins/util/url.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +76 -3
- package/packages/dd-trace/src/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +2 -2
- package/packages/dd-trace/src/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
|
@@ -10,12 +10,13 @@ const {
|
|
|
10
10
|
} = require('../helpers/channel')
|
|
11
11
|
const { addHook, channel } = require('../helpers/instrument')
|
|
12
12
|
const shimmer = require('../../../datadog-shimmer')
|
|
13
|
-
const {
|
|
13
|
+
const { EMPTY_EFD_RETRY_POLICY } = require('../../../dd-trace/src/ci-visibility/efd-retry-policy')
|
|
14
14
|
const { writeCoverageBackfillToCache } = require('../../../dd-trace/src/ci-visibility/test-optimization-cache')
|
|
15
15
|
const log = require('../../../dd-trace/src/log')
|
|
16
16
|
const { getEnvironmentVariable } = require('../../../dd-trace/src/config/helper')
|
|
17
17
|
const {
|
|
18
18
|
getTestSuitePath,
|
|
19
|
+
MOCHA_WORKER_TELEMETRY_PAYLOAD_CODE,
|
|
19
20
|
MOCHA_WORKER_TRACE_PAYLOAD_CODE,
|
|
20
21
|
fromCoverageMapToCoverage,
|
|
21
22
|
getCoveredFilesFromCoverage,
|
|
@@ -28,8 +29,10 @@ const {
|
|
|
28
29
|
getTestCoverageLinesPercentage,
|
|
29
30
|
collectTestOptimizationSummariesFromTraces,
|
|
30
31
|
logTestOptimizationSummary,
|
|
32
|
+
TEST_IMPACT_ANALYSIS_ALL_TESTS_SKIPPED_MESSAGE,
|
|
31
33
|
getTestOptimizationRequestResults,
|
|
32
34
|
isModifiedTest,
|
|
35
|
+
isMarkedAsUnskippable,
|
|
33
36
|
} = require('../../../dd-trace/src/plugins/util/test')
|
|
34
37
|
|
|
35
38
|
const {
|
|
@@ -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,17 @@
|
|
|
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
|
-
|
|
14
|
+
getFailedTestReplayPromise,
|
|
15
|
+
recordTestManagementExecution,
|
|
10
16
|
recordAttemptToFixExecution,
|
|
11
17
|
logAttemptToFixTestExecution,
|
|
12
18
|
} = require('../../../dd-trace/src/plugins/util/test')
|
|
@@ -26,6 +32,8 @@ const isModifiedCh = channel('ci:mocha:test:is-modified')
|
|
|
26
32
|
// suite channels
|
|
27
33
|
const testSuiteErrorCh = channel('ci:mocha:test-suite:error')
|
|
28
34
|
|
|
35
|
+
/** @typedef {{ length: number, [index: number]: unknown } & Iterable<unknown>} ArgumentsLike */
|
|
36
|
+
|
|
29
37
|
const testToContext = new WeakMap()
|
|
30
38
|
const originalFns = new WeakMap()
|
|
31
39
|
const testToStartLine = new WeakMap()
|
|
@@ -40,6 +48,7 @@ const testsStatuses = new Map()
|
|
|
40
48
|
const efdRetryCountByTestFullName = new Map()
|
|
41
49
|
const efdSlowAbortedTests = new Set()
|
|
42
50
|
const attemptToFixExecutions = new Map()
|
|
51
|
+
const isMochaWorker = !!getEnvironmentVariable('MOCHA_WORKER_ID')
|
|
43
52
|
|
|
44
53
|
function waitForHitProbe () {
|
|
45
54
|
const promises = {}
|
|
@@ -133,19 +142,28 @@ function isNewTest (test, knownTests) {
|
|
|
133
142
|
return !testsForSuite.includes(testName)
|
|
134
143
|
}
|
|
135
144
|
|
|
136
|
-
|
|
145
|
+
/**
|
|
146
|
+
* @param {import('mocha').Test} test
|
|
147
|
+
* @param {number} duration
|
|
148
|
+
* @param {import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy} retryPolicy
|
|
149
|
+
*/
|
|
150
|
+
function setEfdRetryCountForTest (test, duration, retryPolicy) {
|
|
137
151
|
const testName = getTestFullName(test)
|
|
138
152
|
if (efdRetryCountByTestFullName.has(testName)) {
|
|
139
153
|
return
|
|
140
154
|
}
|
|
141
|
-
const retryCount =
|
|
155
|
+
const retryCount = getEfdRetryCountForDuration(duration, retryPolicy)
|
|
142
156
|
efdRetryCountByTestFullName.set(testName, retryCount)
|
|
143
157
|
if (retryCount === 0) {
|
|
144
158
|
efdSlowAbortedTests.add(testName)
|
|
145
159
|
}
|
|
146
160
|
}
|
|
147
161
|
|
|
148
|
-
|
|
162
|
+
/**
|
|
163
|
+
* @param {import('mocha').Test} test
|
|
164
|
+
* @param {import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy} retryPolicy
|
|
165
|
+
*/
|
|
166
|
+
function wrapOriginalEfdTest (test, retryPolicy) {
|
|
149
167
|
if (test._ddEfdDurationWrapped || typeof test.fn !== 'function') {
|
|
150
168
|
return
|
|
151
169
|
}
|
|
@@ -154,7 +172,7 @@ function wrapOriginalEfdTest (test, slowTestRetries) {
|
|
|
154
172
|
test.fn = shimmer.wrapFunction(originalFn, originalFn => function () {
|
|
155
173
|
const start = performance.now()
|
|
156
174
|
const recordDuration = () => {
|
|
157
|
-
setEfdRetryCountForTest(test, performance.now() - start,
|
|
175
|
+
setEfdRetryCountForTest(test, performance.now() - start, retryPolicy)
|
|
158
176
|
}
|
|
159
177
|
|
|
160
178
|
if (originalFn.length > 0) {
|
|
@@ -205,13 +223,14 @@ function disableMochaRetries (test) {
|
|
|
205
223
|
* _ddIsModified?: boolean,
|
|
206
224
|
* _ddIsNew?: boolean
|
|
207
225
|
* }} test
|
|
208
|
-
* @param {{
|
|
226
|
+
* @param {{
|
|
227
|
+
* isEarlyFlakeDetectionEnabled?: boolean,
|
|
228
|
+
* earlyFlakeDetectionRetryPolicy?: import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy
|
|
229
|
+
* }} config
|
|
209
230
|
* @returns {boolean}
|
|
210
231
|
*/
|
|
211
232
|
function isDatadogManagedRetryTest (test, config) {
|
|
212
|
-
return test._ddIsAttemptToFix ||
|
|
213
|
-
test._ddIsEfdRetry ||
|
|
214
|
-
(config.isEarlyFlakeDetectionEnabled && (test._ddIsNew || test._ddIsModified))
|
|
233
|
+
return test._ddIsAttemptToFix || isEarlyFlakeDetectionTest(test, config)
|
|
215
234
|
}
|
|
216
235
|
|
|
217
236
|
/**
|
|
@@ -223,22 +242,32 @@ function isDatadogManagedRetryTest (test, config) {
|
|
|
223
242
|
* _ddIsModified?: boolean,
|
|
224
243
|
* _ddIsNew?: boolean
|
|
225
244
|
* }} test
|
|
226
|
-
* @param {{
|
|
245
|
+
* @param {{
|
|
246
|
+
* isEarlyFlakeDetectionEnabled?: boolean,
|
|
247
|
+
* earlyFlakeDetectionRetryPolicy?: import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy
|
|
248
|
+
* }} config
|
|
227
249
|
* @returns {boolean}
|
|
228
250
|
*/
|
|
229
251
|
function isEarlyFlakeDetectionTest (test, config) {
|
|
230
252
|
return !test._ddIsAttemptToFix &&
|
|
231
253
|
!test._ddIsDisabled &&
|
|
232
254
|
config.isEarlyFlakeDetectionEnabled &&
|
|
255
|
+
hasEfdRetries(config.earlyFlakeDetectionRetryPolicy) &&
|
|
233
256
|
(test._ddIsEfdRetry || test._ddIsNew || test._ddIsModified)
|
|
234
257
|
}
|
|
235
258
|
|
|
236
|
-
|
|
259
|
+
/**
|
|
260
|
+
* @param {import('mocha').Test} test
|
|
261
|
+
* @param {number} numRetries
|
|
262
|
+
* @param {string[]} tags
|
|
263
|
+
* @param {import('../../../dd-trace/src/ci-visibility/efd-retry-policy').EfdRetryPolicy} retryPolicy
|
|
264
|
+
*/
|
|
265
|
+
function retryTest (test, numRetries, tags, retryPolicy) {
|
|
237
266
|
const suite = test.parent
|
|
238
267
|
const isEfdRetry = tags.includes('_ddIsEfdRetry')
|
|
239
268
|
disableMochaRetries(test)
|
|
240
269
|
if (isEfdRetry) {
|
|
241
|
-
wrapOriginalEfdTest(test,
|
|
270
|
+
wrapOriginalEfdTest(test, retryPolicy)
|
|
242
271
|
}
|
|
243
272
|
for (let retryIndex = 0; retryIndex < numRetries; retryIndex++) {
|
|
244
273
|
const clonedTest = test.clone()
|
|
@@ -250,7 +279,7 @@ function retryTest (test, numRetries, tags, slowTestRetries) {
|
|
|
250
279
|
if (typeof originalFn === 'function') {
|
|
251
280
|
clonedTest.fn = shimmer.wrapFunction(originalFn, originalFn => function (...args) {
|
|
252
281
|
const efdRetryCount = efdRetryCountByTestFullName.get(getTestFullName(clonedTest))
|
|
253
|
-
if (
|
|
282
|
+
if (shouldSkipEfdRetry(clonedTest._ddEfdRetryIndex, efdRetryCount)) {
|
|
254
283
|
clonedTest._ddShouldSkipEfdRetry = true
|
|
255
284
|
this.skip()
|
|
256
285
|
}
|
|
@@ -266,14 +295,6 @@ function retryTest (test, numRetries, tags, slowTestRetries) {
|
|
|
266
295
|
}
|
|
267
296
|
}
|
|
268
297
|
|
|
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
298
|
function getSuitesByTestFile (root) {
|
|
278
299
|
const suitesByTestFile = {}
|
|
279
300
|
function getSuites (suite) {
|
|
@@ -462,7 +483,7 @@ function getOnTestHandler (isMain) {
|
|
|
462
483
|
|
|
463
484
|
if (isEfdRetry) {
|
|
464
485
|
const efdRetryCount = efdRetryCountByTestFullName.get(getTestFullName(test))
|
|
465
|
-
if (
|
|
486
|
+
if (shouldSkipEfdRetry(test._ddEfdRetryIndex, efdRetryCount)) {
|
|
466
487
|
test.pending = true
|
|
467
488
|
test._ddShouldSkipEfdRetry = true
|
|
468
489
|
return
|
|
@@ -576,7 +597,7 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
576
597
|
!efdRetryCountByTestFullName.has(testName)
|
|
577
598
|
) {
|
|
578
599
|
const duration = test.duration > 0 ? test.duration : performance.now() - test._ddStartTime
|
|
579
|
-
setEfdRetryCountForTest(test, duration, config.
|
|
600
|
+
setEfdRetryCountForTest(test, duration, config.earlyFlakeDetectionRetryPolicy)
|
|
580
601
|
}
|
|
581
602
|
|
|
582
603
|
if (testsStatuses.get(testName)) {
|
|
@@ -587,7 +608,8 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
587
608
|
const testStatuses = testsStatuses.get(testName)
|
|
588
609
|
|
|
589
610
|
const isLastAttempt = testStatuses.length === config.testManagementAttemptToFixRetries + 1
|
|
590
|
-
const efdRetryCount = efdRetryCountByTestFullName.get(testName) ??
|
|
611
|
+
const efdRetryCount = efdRetryCountByTestFullName.get(testName) ??
|
|
612
|
+
config.earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
591
613
|
const isLastEfdRetry = testStatuses.length === efdRetryCount + 1
|
|
592
614
|
const isLastAtrAttempt = getIsLastRetry(test) || (config.isFlakyTestRetriesEnabled && status === 'pass')
|
|
593
615
|
|
|
@@ -642,6 +664,17 @@ function getTestFinishInfo (test, status, config, error) {
|
|
|
642
664
|
isFinalAttempt,
|
|
643
665
|
})
|
|
644
666
|
|
|
667
|
+
if (!isMochaWorker) {
|
|
668
|
+
recordTestManagementExecution({
|
|
669
|
+
testSuite: getTestSuitePath(test.file, process.cwd()),
|
|
670
|
+
testName: test.fullTitle(),
|
|
671
|
+
status,
|
|
672
|
+
isAttemptToFix: _ddIsAttemptToFix,
|
|
673
|
+
isDisabled: _ddIsDisabled,
|
|
674
|
+
isQuarantined: _ddIsQuarantined,
|
|
675
|
+
})
|
|
676
|
+
}
|
|
677
|
+
|
|
645
678
|
if (_ddIsAttemptToFix) {
|
|
646
679
|
recordAttemptToFixExecution(attemptToFixExecutions, {
|
|
647
680
|
testSuite: getTestSuitePath(test.file, process.cwd()),
|
|
@@ -788,7 +821,7 @@ function finishDeferredHookEnd (test) {
|
|
|
788
821
|
* @param {object} test - Mocha test currently owning the hook.
|
|
789
822
|
* @param {Promise<void>|undefined} failedTestReplayPromise - Pending Failed Test Replay wait, if any.
|
|
790
823
|
* @param {unknown} hookThis - Callback receiver.
|
|
791
|
-
* @param {
|
|
824
|
+
* @param {ArgumentsLike} args - Arguments passed by Mocha.
|
|
792
825
|
* @returns {unknown}
|
|
793
826
|
*/
|
|
794
827
|
function runFailedTestReplayHookUpCallback (fn, test, failedTestReplayPromise, hookThis, args) {
|
|
@@ -921,14 +954,7 @@ function getOnTestRetryHandler (config) {
|
|
|
921
954
|
promises,
|
|
922
955
|
...ctx.currentStore,
|
|
923
956
|
})
|
|
924
|
-
|
|
925
|
-
test._ddFailedTestReplayPromise = Promise.all([
|
|
926
|
-
promises.setProbePromise,
|
|
927
|
-
promises.finishTestPromise,
|
|
928
|
-
]).then(() => {})
|
|
929
|
-
} else if (promises.setProbePromise || promises.finishTestPromise) {
|
|
930
|
-
test._ddFailedTestReplayPromise = promises.setProbePromise || promises.finishTestPromise
|
|
931
|
-
}
|
|
957
|
+
test._ddFailedTestReplayPromise = getFailedTestReplayPromise(promises)
|
|
932
958
|
}
|
|
933
959
|
const key = getTestToContextKey(test)
|
|
934
960
|
testToContext.delete(key)
|
|
@@ -1004,17 +1030,12 @@ function getRunTestsWrapper (runTests, config) {
|
|
|
1004
1030
|
onDone: (isModified) => {
|
|
1005
1031
|
if (isModified) {
|
|
1006
1032
|
test._ddIsModified = true
|
|
1007
|
-
if (
|
|
1008
|
-
!test.isPending() &&
|
|
1009
|
-
!test._ddIsDisabled &&
|
|
1010
|
-
!test._ddIsAttemptToFix &&
|
|
1011
|
-
config.isEarlyFlakeDetectionEnabled
|
|
1012
|
-
) {
|
|
1033
|
+
if (!test.isPending() && isEarlyFlakeDetectionTest(test, config)) {
|
|
1013
1034
|
retryTest(
|
|
1014
1035
|
test,
|
|
1015
|
-
|
|
1036
|
+
config.earlyFlakeDetectionRetryPolicy.schedulingRetryCount,
|
|
1016
1037
|
['_ddIsModified', '_ddIsEfdRetry'],
|
|
1017
|
-
config.
|
|
1038
|
+
config.earlyFlakeDetectionRetryPolicy
|
|
1018
1039
|
)
|
|
1019
1040
|
}
|
|
1020
1041
|
}
|
|
@@ -1028,17 +1049,12 @@ function getRunTestsWrapper (runTests, config) {
|
|
|
1028
1049
|
suite.tests.forEach((test) => {
|
|
1029
1050
|
if (!test.isPending() && isNewTest(test, config.knownTests)) {
|
|
1030
1051
|
test._ddIsNew = true
|
|
1031
|
-
if (
|
|
1032
|
-
config.isEarlyFlakeDetectionEnabled &&
|
|
1033
|
-
!test._ddIsDisabled &&
|
|
1034
|
-
!test._ddIsAttemptToFix &&
|
|
1035
|
-
!test._ddIsModified
|
|
1036
|
-
) {
|
|
1052
|
+
if (!test._ddIsModified && isEarlyFlakeDetectionTest(test, config)) {
|
|
1037
1053
|
retryTest(
|
|
1038
1054
|
test,
|
|
1039
|
-
|
|
1055
|
+
config.earlyFlakeDetectionRetryPolicy.schedulingRetryCount,
|
|
1040
1056
|
['_ddIsNew', '_ddIsEfdRetry'],
|
|
1041
|
-
config.
|
|
1057
|
+
config.earlyFlakeDetectionRetryPolicy
|
|
1042
1058
|
)
|
|
1043
1059
|
}
|
|
1044
1060
|
}
|
|
@@ -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'
|