Skip to content

Commit 86db239

Browse files
[test optimization] Fix TIA in parallel mocha (#7773)
1 parent 9eaa736 commit 86db239

File tree

3 files changed

+89
-17
lines changed

3 files changed

+89
-17
lines changed

integration-tests/mocha/mocha.spec.js

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,6 +2100,60 @@ describe(`mocha@${MOCHA_VERSION}`, function () {
21002100
}).catch(done)
21012101
})
21022102
})
2103+
2104+
onlyLatestIt('can skip suites in parallel mode', async () => {
2105+
receiver.setSuitesToSkip([{
2106+
type: 'suite',
2107+
attributes: {
2108+
suite: 'ci-visibility/test/ci-visibility-test.js',
2109+
},
2110+
}])
2111+
2112+
const eventsPromise = receiver
2113+
.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('/api/v2/citestcycle'), (payloads) => {
2114+
const events = payloads.flatMap(({ payload }) => payload.events)
2115+
const testSession = events.find(event => event.type === 'test_session_end').content
2116+
assert.strictEqual(testSession.meta[MOCHA_IS_PARALLEL], 'true')
2117+
assert.strictEqual(testSession.meta[TEST_ITR_SKIPPING_ENABLED], 'true')
2118+
assert.strictEqual(testSession.meta[TEST_ITR_TESTS_SKIPPED], 'true')
2119+
assert.strictEqual(testSession.meta[TEST_ITR_SKIPPING_TYPE], 'suite')
2120+
assert.strictEqual(testSession.metrics[TEST_ITR_SKIPPING_COUNT], 1)
2121+
2122+
const suites = events.filter(event => event.type === 'test_suite_end').map(event => event.content)
2123+
assert.strictEqual(suites.length, 2)
2124+
2125+
const skippedSuite = suites.find(s =>
2126+
s.resource === 'test_suite.ci-visibility/test/ci-visibility-test.js'
2127+
)
2128+
assert.strictEqual(skippedSuite.meta[TEST_STATUS], 'skip')
2129+
assert.strictEqual(skippedSuite.meta[TEST_SKIPPED_BY_ITR], 'true')
2130+
2131+
const runningSuite = suites.find(s =>
2132+
s.resource === 'test_suite.ci-visibility/test/ci-visibility-test-2.js'
2133+
)
2134+
assert.strictEqual(runningSuite.meta[TEST_STATUS], 'pass')
2135+
2136+
// Only 1 test ran (from the non-skipped suite)
2137+
const tests = events.filter(event => event.type === 'test').map(event => event.content)
2138+
assert.strictEqual(tests.length, 1)
2139+
assert.strictEqual(tests[0].meta[TEST_STATUS], 'pass')
2140+
})
2141+
2142+
childProcess = exec(
2143+
'node node_modules/mocha/bin/mocha --parallel --jobs 2' +
2144+
' ./ci-visibility/test/ci-visibility-test.js' +
2145+
' ./ci-visibility/test/ci-visibility-test-2.js',
2146+
{
2147+
cwd,
2148+
env: getCiVisAgentlessConfig(receiver.port),
2149+
}
2150+
)
2151+
2152+
await Promise.all([
2153+
eventsPromise,
2154+
once(childProcess, 'exit'),
2155+
])
2156+
})
21032157
})
21042158

21052159
context('error tags', () => {
@@ -4477,17 +4531,13 @@ describe(`mocha@${MOCHA_VERSION}`, function () {
44774531
})
44784532

44794533
context('libraries capabilities', () => {
4480-
const getTestAssertions = (isParallel) =>
4534+
const getTestAssertions = () =>
44814535
receiver.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('citestcycle'), (payloads) => {
44824536
const metadataDicts = payloads.flatMap(({ payload }) => payload.metadata)
44834537

44844538
assert.ok(metadataDicts.length > 0)
44854539
metadataDicts.forEach(metadata => {
4486-
if (isParallel) {
4487-
assert.strictEqual(metadata.test[DD_CAPABILITIES_TEST_IMPACT_ANALYSIS], undefined)
4488-
} else {
4489-
assert.strictEqual(metadata.test[DD_CAPABILITIES_TEST_IMPACT_ANALYSIS], '1')
4490-
}
4540+
assert.strictEqual(metadata.test[DD_CAPABILITIES_TEST_IMPACT_ANALYSIS], '1')
44914541
assert.strictEqual(metadata.test[DD_CAPABILITIES_TEST_MANAGEMENT_ATTEMPT_TO_FIX], '5')
44924542
assert.strictEqual(metadata.test[DD_CAPABILITIES_EARLY_FLAKE_DETECTION], '1')
44934543
assert.strictEqual(metadata.test[DD_CAPABILITIES_AUTO_TEST_RETRIES], '1')
@@ -4499,8 +4549,8 @@ describe(`mocha@${MOCHA_VERSION}`, function () {
44994549
})
45004550
})
45014551

4502-
const runTest = (done, isParallel, extraEnvVars = {}) => {
4503-
const testAssertionsPromise = getTestAssertions(isParallel)
4552+
const runTest = (done, extraEnvVars = {}) => {
4553+
const testAssertionsPromise = getTestAssertions()
45044554

45054555
childProcess = exec(
45064556
runTestsCommand,
@@ -4519,13 +4569,11 @@ describe(`mocha@${MOCHA_VERSION}`, function () {
45194569
}
45204570

45214571
it('adds capabilities to tests', (done) => {
4522-
runTest(done, false)
4572+
runTest(done)
45234573
})
45244574

45254575
onlyLatestIt('adds capabilities to tests (parallel)', (done) => {
4526-
runTest(done, true, {
4527-
RUN_IN_PARALLEL: '1',
4528-
})
4576+
runTest(done, { RUN_IN_PARALLEL: '1' })
45294577
})
45304578
})
45314579

packages/datadog-instrumentations/src/mocha/main.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ function getOnStartHandler (isParallel, frameworkVersion) {
106106
const processArgv = process.argv.slice(2).join(' ')
107107
const command = `mocha ${processArgv}`
108108
testSessionStartCh.publish({ command, frameworkVersion })
109-
if (!isParallel && skippedSuites.length) {
109+
if (skippedSuites.length) {
110110
itrSkippedSuitesCh.publish({ skippedSuites, frameworkVersion })
111111
}
112112
}
@@ -315,8 +315,7 @@ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFini
315315
config.isTestManagementTestsEnabled = libraryConfig.isTestManagementEnabled
316316
config.testManagementAttemptToFixRetries = libraryConfig.testManagementAttemptToFixRetries
317317
config.isImpactedTestsEnabled = libraryConfig.isImpactedTestsEnabled
318-
// ITR is not supported in parallel mode yet
319-
config.isSuitesSkippingEnabled = !isParallel && libraryConfig.isSuitesSkippingEnabled
318+
config.isSuitesSkippingEnabled = libraryConfig.isSuitesSkippingEnabled
320319
config.isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
321320
config.flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
322321

@@ -626,6 +625,13 @@ addHook({
626625
this.once('start', getOnStartHandler(true, frameworkVersion))
627626
this.once('end', getOnEndHandler(true))
628627

628+
// Populate unskippable suites before config is fetched (matches serial mode at Mocha.prototype.run)
629+
for (const filePath of files) {
630+
if (isMarkedAsUnskippable({ path: filePath })) {
631+
unskippableSuites.push(filePath)
632+
}
633+
}
634+
629635
getExecutionConfiguration(this, true, frameworkVersion, () => {
630636
if (config.isKnownTestsEnabled) {
631637
const testSuites = files.map(file => getTestSuitePath(file, process.cwd()))
@@ -640,7 +646,25 @@ addHook({
640646
config.isEarlyFlakeDetectionFaulty = true
641647
}
642648
}
643-
run.apply(this, arguments)
649+
if (config.isSuitesSkippingEnabled && suitesToSkip.length) {
650+
const filteredFiles = []
651+
const skippedFiles = []
652+
for (const file of files) {
653+
const testPath = getTestSuitePath(file, process.cwd())
654+
const shouldSkip = suitesToSkip.includes(testPath)
655+
const isUnskippable = unskippableSuites.includes(file)
656+
if (shouldSkip && !isUnskippable) {
657+
skippedFiles.push(testPath)
658+
} else {
659+
filteredFiles.push(file)
660+
}
661+
}
662+
isSuitesSkipped = skippedFiles.length > 0
663+
skippedSuites = skippedFiles
664+
run.apply(this, [cb, { files: filteredFiles }])
665+
} else {
666+
run.apply(this, arguments)
667+
}
644668
})
645669

646670
return this

packages/dd-trace/src/plugins/util/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ const DD_CAPABILITIES_FAILED_TEST_REPLAY = '_dd.library_capabilities.failed_test
150150
const DD_CI_LIBRARY_CONFIGURATION_ERROR = '_dd.ci.library_configuration_error'
151151

152152
const UNSUPPORTED_TIA_FRAMEWORKS = new Set(['playwright', 'vitest'])
153-
const UNSUPPORTED_TIA_FRAMEWORKS_PARALLEL_MODE = new Set(['cucumber', 'mocha'])
153+
const UNSUPPORTED_TIA_FRAMEWORKS_PARALLEL_MODE = new Set(['cucumber'])
154154
const MINIMUM_FRAMEWORK_VERSION_FOR_EFD = {
155155
playwright: '>=1.38.0',
156156
}

0 commit comments

Comments
 (0)