Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions integration-tests/cucumber/cucumber.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2596,6 +2596,54 @@ describe(`cucumber@${version} commonJS`, () => {
})
})

it('does not tag known attempt to fix tests as new', async () => {
receiver.setKnownTests({
cucumber: {
'ci-visibility/features-test-management/attempt-to-fix.feature': [
'Say attempt to fix',
],
},
})
receiver.setSettings({
test_management: { enabled: true, attempt_to_fix_retries: 2 },
early_flake_detection: {
enabled: true,
slow_test_retries: { '5s': 2 },
faulty_session_threshold: 100,
},
known_tests_enabled: true,
})

const eventsPromise = receiver
.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('/api/v2/citestcycle'), (payloads) => {
const events = payloads.flatMap(({ payload }) => payload.events)
const tests = events.filter(event => event.type === 'test').map(event => event.content)
const atfTests = tests.filter(
t => t.meta[TEST_MANAGEMENT_IS_ATTEMPT_TO_FIX] === 'true'
)
assert.ok(atfTests.length > 0)
for (const test of atfTests) {
assert.ok(
!(TEST_IS_NEW in test.meta),
'ATF test that is in known tests should not be tagged as new'
)
}
})

childProcess = exec(
'./node_modules/.bin/cucumber-js ci-visibility/features-test-management/attempt-to-fix.feature',
{
cwd,
env: getCiVisAgentlessConfig(receiver.port),
}
)

await Promise.all([
once(childProcess, 'exit'),
eventsPromise,
])
})

it('does not fail retry if a test is quarantined', (done) => {
receiver.setSettings({ test_management: { enabled: true, attempt_to_fix_retries: 3 } })
receiver.setTestManagementTests({
Expand Down
56 changes: 56 additions & 0 deletions integration-tests/cypress/cypress.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3274,6 +3274,62 @@ moduleTypes.forEach(({
await runAttemptToFixTest({ extraEnvVars: { DD_TEST_MANAGEMENT_ENABLED: '0' } })
})

it('does not tag known attempt to fix tests as new', async () => {
receiver.setKnownTests({
cypress: {
'cypress/e2e/attempt-to-fix.js': [
'attempt to fix is attempt to fix',
],
},
})
receiver.setSettings({
test_management: { enabled: true, attempt_to_fix_retries: 2 },
early_flake_detection: {
enabled: true,
slow_test_retries: { '5s': 2 },
faulty_session_threshold: 100,
},
known_tests_enabled: true,
})

const eventsPromise = receiver
.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('/api/v2/citestcycle'), (payloads) => {
const events = payloads.flatMap(({ payload }) => payload.events)
const tests = events.filter(event => event.type === 'test').map(event => event.content)
const atfTests = tests.filter(
t => t.meta[TEST_MANAGEMENT_IS_ATTEMPT_TO_FIX] === 'true'
)
assert.ok(atfTests.length > 0)
for (const test of atfTests) {
assert.ok(
!(TEST_IS_NEW in test.meta),
'ATF test that is in known tests should not be tagged as new'
)
}
}, 25000)

const envVars = getCiVisEvpProxyConfig(receiver.port)
const specToRun = 'cypress/e2e/attempt-to-fix.js'

childProcess = exec(
version === 'latest' ? testCommand : `${testCommand} --spec ${specToRun}`,
{
cwd,
env: {
...envVars,
CYPRESS_BASE_URL: `http://localhost:${webAppPort}`,
SPEC_PATTERN: specToRun,
CYPRESS_SHOULD_ALWAYS_PASS: '1',
},
}
)

await Promise.all([
once(childProcess, 'exit'),
eventsPromise,
])
})

/**
* TODO:
* The spec says that quarantined tests that are not attempted to fix should be run and their result ignored.
Expand Down
53 changes: 53 additions & 0 deletions integration-tests/mocha/mocha.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4153,6 +4153,59 @@ describe(`mocha@${MOCHA_VERSION}`, function () {
runAttemptToFixTest(done, { extraEnvVars: { DD_TEST_MANAGEMENT_ENABLED: '0' } })
})

onlyLatestIt('does not tag known attempt to fix tests as new', async () => {
receiver.setKnownTests({
mocha: {
'ci-visibility/test-management/test-attempt-to-fix-1.js': [
'attempt to fix tests can attempt to fix a test',
],
},
})
receiver.setSettings({
test_management: { enabled: true, attempt_to_fix_retries: 2 },
early_flake_detection: {
enabled: true,
slow_test_retries: { '5s': 2 },
faulty_session_threshold: 100,
},
known_tests_enabled: true,
})

const eventsPromise = receiver
.gatherPayloadsMaxTimeout(({ url }) => url.endsWith('/api/v2/citestcycle'), (payloads) => {
const events = payloads.flatMap(({ payload }) => payload.events)
const tests = events.filter(event => event.type === 'test').map(event => event.content)
const atfTests = tests.filter(
t => t.meta[TEST_MANAGEMENT_IS_ATTEMPT_TO_FIX] === 'true'
)
assert.ok(atfTests.length > 0)
for (const test of atfTests) {
assert.ok(
!(TEST_IS_NEW in test.meta),
'ATF test that is in known tests should not be tagged as new'
)
}
})

childProcess = exec(
runTestsCommand,
{
cwd,
env: {
...getCiVisAgentlessConfig(receiver.port),
TESTS_TO_RUN: JSON.stringify([
'./test-management/test-attempt-to-fix-1.js',
]),
},
}
)

await Promise.all([
once(childProcess, 'exit'),
eventsPromise,
])
})

onlyLatestIt('does not fail retry if a test is quarantined', (done) => {
receiver.setSettings({ test_management: { enabled: true, attempt_to_fix_retries: 3 } })
receiver.setTestManagementTests({
Expand Down
53 changes: 53 additions & 0 deletions integration-tests/playwright/playwright.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1660,6 +1660,59 @@ versions.forEach((version) => {
await runAttemptToFixTest({ extraEnvVars: { DD_TEST_MANAGEMENT_ENABLED: '0' } })
})

it('does not tag known attempt to fix tests as new', async () => {
receiver.setKnownTests({
playwright: {
'attempt-to-fix-test.js': [
'attempt to fix should attempt to fix failed test',
'attempt to fix should attempt to fix passed test',
],
},
})
receiver.setSettings({
test_management: { enabled: true, attempt_to_fix_retries: 2 },
early_flake_detection: {
enabled: true,
slow_test_retries: { '5s': 2 },
faulty_session_threshold: 100,
},
known_tests_enabled: true,
})

const eventsPromise = receiver
.gatherPayloadsMaxTimeout(({ url }) => url === '/api/v2/citestcycle', (payloads) => {
const events = payloads.flatMap(({ payload }) => payload.events)
const tests = events.filter(event => event.type === 'test').map(event => event.content)
const atfTests = tests.filter(
t => t.meta[TEST_MANAGEMENT_IS_ATTEMPT_TO_FIX] === 'true'
)
assert.ok(atfTests.length > 0)
for (const test of atfTests) {
assert.ok(
!(TEST_IS_NEW in test.meta),
'ATF test that is in known tests should not be tagged as new'
)
}
})

childProcess = exec(
'./node_modules/.bin/playwright test -c playwright.config.js attempt-to-fix-test.js',
{
cwd,
env: {
...getCiVisAgentlessConfig(receiver.port),
PW_BASE_URL: `http://localhost:${webAppPort}`,
TEST_DIR: './ci-visibility/playwright-tests-test-management',
},
}
)

await Promise.all([
once(childProcess, 'exit'),
eventsPromise,
])
})

it('does not fail retry if a test is quarantined', async () => {
receiver.setSettings({
test_management: { enabled: true, attempt_to_fix_retries: ATTEMPT_TO_FIX_NUM_RETRIES },
Expand Down
52 changes: 52 additions & 0 deletions integration-tests/vitest/vitest.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1931,6 +1931,58 @@ versions.forEach((version) => {
runAttemptToFixTest(done, { extraEnvVars: { DD_TEST_MANAGEMENT_ENABLED: '0' } })
})

it('does not tag known attempt to fix tests as new', async () => {
receiver.setKnownTests({
vitest: {
'ci-visibility/vitest-tests/test-attempt-to-fix.mjs': [
'attempt to fix tests can attempt to fix a test',
],
},
})
receiver.setSettings({
test_management: { enabled: true, attempt_to_fix_retries: 2 },
early_flake_detection: {
enabled: true,
slow_test_retries: { '5s': 2 },
faulty_session_threshold: 100,
},
known_tests_enabled: true,
})

const eventsPromise = receiver
.gatherPayloadsMaxTimeout(({ url }) => url === '/api/v2/citestcycle', (payloads) => {
const events = payloads.flatMap(({ payload }) => payload.events)
const tests = events.filter(event => event.type === 'test').map(event => event.content)
const atfTests = tests.filter(
t => t.meta[TEST_MANAGEMENT_IS_ATTEMPT_TO_FIX] === 'true'
)
assert.ok(atfTests.length > 0)
for (const test of atfTests) {
assert.ok(
!(TEST_IS_NEW in test.meta),
'ATF test that is in known tests should not be tagged as new'
)
}
})

childProcess = exec(
'./node_modules/.bin/vitest run',
{
cwd,
env: {
...getCiVisAgentlessConfig(receiver.port),
TEST_DIR: 'ci-visibility/vitest-tests/test-attempt-to-fix*',
NODE_OPTIONS: '--import dd-trace/register.js -r dd-trace/ci/init --no-warnings',
},
}
)

await Promise.all([
once(childProcess, 'exit'),
eventsPromise,
])
})

it('does not fail retry if a test is quarantined', (done) => {
receiver.setSettings({ test_management: { enabled: true, attempt_to_fix_retries: 3 } })
receiver.setTestManagementTests({
Expand Down
5 changes: 4 additions & 1 deletion packages/datadog-instrumentations/src/cucumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ const numRetriesByPickleId = new Map()
const numAttemptToCtx = new Map()
const newTestsByTestFullname = new Map()
const modifiedTestsByPickleId = new Map()
// Pickle IDs for tests that are genuinely new (not in known tests list).
const newTestPickleIds = new Set()

let eventDataCollector = null
let pickleByFile = {}
Expand Down Expand Up @@ -359,7 +361,7 @@ function wrapRun (pl, isLatestVersion, version) {
}

if (isKnownTestsEnabled && status !== 'skip') {
isNew = numRetries !== undefined
isNew = newTestPickleIds.has(this.pickle.id)
}

if (isNew || isModified) {
Expand Down Expand Up @@ -714,6 +716,7 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
if (isKnownTestsEnabled && !isAttemptToFix) {
isNew = isNewTest(testSuitePath, pickle.name)
if (isNew) {
newTestPickleIds.add(pickle.id)
numRetriesByPickleId.set(pickle.id, 0)
}
}
Expand Down
Loading