Skip to content

Commit c58e59c

Browse files
[test optimization] Fix errors not being reported in jest when EFD and ATR is enabled (#7451)
1 parent 0fa5dc2 commit c58e59c

2 files changed

Lines changed: 121 additions & 1 deletion

File tree

integration-tests/jest/jest.spec.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,6 +2155,62 @@ describe(`jest@${JEST_VERSION} commonJS`, () => {
21552155
])
21562156
})
21572157

2158+
it('preserves test errors when ATR retry suppression is active due to EFD', async () => {
2159+
receiver.setInfoResponse({ endpoints: ['/evp_proxy/v4'] })
2160+
// All tests are considered new, so EFD will be active
2161+
receiver.setKnownTests({ jest: {} })
2162+
const NUM_RETRIES_EFD = 2
2163+
receiver.setSettings({
2164+
early_flake_detection: {
2165+
enabled: true,
2166+
slow_test_retries: {
2167+
'5s': NUM_RETRIES_EFD,
2168+
},
2169+
faulty_session_threshold: 100,
2170+
},
2171+
known_tests_enabled: true,
2172+
flaky_test_retries_enabled: true,
2173+
})
2174+
2175+
const eventsPromise = receiver
2176+
.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('/api/v2/citestcycle'), (payloads) => {
2177+
const events = payloads.flatMap(({ payload }) => payload.events)
2178+
const tests = events.filter(event => event.type === 'test').map(event => event.content)
2179+
const failingTests = tests.filter(test => test.meta[TEST_STATUS] === 'fail')
2180+
2181+
// Verify that all failing tests have error messages preserved
2182+
// even though ATR retry suppression is active (due to EFD)
2183+
failingTests.forEach(test => {
2184+
assert.ok(
2185+
ERROR_MESSAGE in test.meta,
2186+
'Test error message should be preserved when ATR retry suppression is active'
2187+
)
2188+
assert.ok(test.meta[ERROR_MESSAGE].length > 0, 'Test error message should not be empty')
2189+
// The error should contain information about the assertion failure
2190+
assert.match(test.meta[ERROR_MESSAGE], /deepStrictEqual|Expected|actual/i)
2191+
})
2192+
2193+
// Verify EFD is active (ATR should be suppressed)
2194+
const efdRetries = tests.filter(t => t.meta[TEST_RETRY_REASON] === TEST_RETRY_REASON_TYPES.efd)
2195+
const atrRetries = tests.filter(t => t.meta[TEST_RETRY_REASON] === TEST_RETRY_REASON_TYPES.atr)
2196+
assert.strictEqual(efdRetries.length, NUM_RETRIES_EFD)
2197+
assert.strictEqual(atrRetries.length, 0)
2198+
})
2199+
2200+
childProcess = exec(
2201+
runTestsCommand,
2202+
{
2203+
cwd,
2204+
env: { ...getCiVisAgentlessConfig(receiver.port), TESTS_TO_RUN: 'jest-flaky/flaky-fails.js' },
2205+
}
2206+
)
2207+
2208+
await Promise.all([
2209+
once(childProcess, 'exit'),
2210+
eventsPromise,
2211+
])
2212+
})
2213+
21582214
it(
21592215
'sets final_status tag only on last ATR retry when EFD is enabled but not active and ATR is active',
21602216
async () => {
@@ -4494,6 +4550,69 @@ describe(`jest@${JEST_VERSION} commonJS`, () => {
44944550
])
44954551
})
44964552

4553+
it('preserves test errors when ATR retry suppression is active due to attempt to fix', async () => {
4554+
receiver.setSettings({
4555+
test_management: { enabled: true, attempt_to_fix_retries: 2 },
4556+
flaky_test_retries_enabled: true,
4557+
})
4558+
4559+
receiver.setTestManagementTests({
4560+
jest: {
4561+
suites: {
4562+
'ci-visibility/jest-flaky/flaky-fails.js': {
4563+
tests: {
4564+
'test-flaky-test-retries can retry failed tests': {
4565+
properties: {
4566+
attempt_to_fix: true,
4567+
},
4568+
},
4569+
},
4570+
},
4571+
},
4572+
},
4573+
})
4574+
const eventsPromise = receiver
4575+
.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('/api/v2/citestcycle'), (payloads) => {
4576+
const events = payloads.flatMap(({ payload }) => payload.events)
4577+
const tests = events.filter(event => event.type === 'test').map(event => event.content)
4578+
const failingTests = tests.filter(test => test.meta[TEST_STATUS] === 'fail')
4579+
4580+
// Verify that all failing tests have error messages preserved
4581+
// even though ATR retry suppression is active (due to attempt to fix)
4582+
failingTests.forEach(test => {
4583+
assert.ok(
4584+
ERROR_MESSAGE in test.meta,
4585+
'Test error message should be preserved when ATR retry suppression is active due to attempt to fix'
4586+
)
4587+
assert.ok(test.meta[ERROR_MESSAGE].length > 0, 'Test error message should not be empty')
4588+
// The error should contain information about the assertion failure
4589+
assert.match(test.meta[ERROR_MESSAGE], /deepStrictEqual|Expected|actual/i)
4590+
})
4591+
4592+
// Verify attempt to fix is active (ATR should be suppressed)
4593+
const atfRetries = tests.filter(t => t.meta[TEST_RETRY_REASON] === TEST_RETRY_REASON_TYPES.atf)
4594+
const atrRetries = tests.filter(t => t.meta[TEST_RETRY_REASON] === TEST_RETRY_REASON_TYPES.atr)
4595+
assert.strictEqual(atfRetries.length, 2)
4596+
assert.strictEqual(atrRetries.length, 0)
4597+
})
4598+
4599+
childProcess = exec(
4600+
runTestsCommand,
4601+
{
4602+
cwd,
4603+
env: {
4604+
...getCiVisAgentlessConfig(receiver.port),
4605+
TESTS_TO_RUN: 'jest-flaky/flaky-fails.js',
4606+
},
4607+
}
4608+
)
4609+
4610+
await Promise.all([
4611+
once(childProcess, 'exit'),
4612+
eventsPromise,
4613+
])
4614+
})
4615+
44974616
it('attempt to fix takes precedence over EFD for new tests', async () => {
44984617
const NUM_RETRIES_EFD = 2
44994618
receiver.setKnownTests({ jest: {} })

packages/datadog-instrumentations/src/jest.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
515515
}
516516
}
517517
if (event.name === 'test_done') {
518+
const originalError = event.test?.errors?.[0]
518519
let status = 'pass'
519520
if (event.test.errors && event.test.errors.length) {
520521
status = 'fail'
@@ -594,7 +595,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
594595
const shouldSetProbe = this.isDiEnabled && willBeRetriedByFailedTestReplay && numTestExecutions === 1
595596
testErrCh.publish({
596597
...ctx.currentStore,
597-
error: formatJestError(event.test.errors[0]),
598+
error: formatJestError(originalError),
598599
shouldSetProbe,
599600
promises,
600601
finalStatus,

0 commit comments

Comments
 (0)