mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Add error handling/retry logic for search source alert tests (#196443)
## Summary Resolves https://github.com/elastic/kibana/issues/193842. Adds error handling & retry logic for search source alerts that are causing failures on MKI. ### Checklist - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed
This commit is contained in:
parent
75760bbb13
commit
5acba9678a
2 changed files with 125 additions and 89 deletions
|
@ -45,53 +45,59 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
let connectorId: string;
|
||||
|
||||
const createSourceIndex = () =>
|
||||
es.index({
|
||||
index: SOURCE_DATA_VIEW,
|
||||
body: {
|
||||
settings: { number_of_shards: 1 },
|
||||
mappings: {
|
||||
properties: {
|
||||
'@timestamp': { type: 'date' },
|
||||
message: { type: 'keyword' },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
retry.try(() =>
|
||||
createIndex(SOURCE_DATA_VIEW, {
|
||||
'@timestamp': { type: 'date' },
|
||||
message: { type: 'keyword' },
|
||||
})
|
||||
);
|
||||
|
||||
const generateNewDocs = async (docsNumber: number) => {
|
||||
const createOutputDataIndex = () =>
|
||||
retry.try(() =>
|
||||
createIndex(OUTPUT_DATA_VIEW, {
|
||||
rule_id: { type: 'text' },
|
||||
rule_name: { type: 'text' },
|
||||
alert_id: { type: 'text' },
|
||||
context_link: { type: 'text' },
|
||||
})
|
||||
);
|
||||
|
||||
async function createIndex(index: string, properties: unknown) {
|
||||
try {
|
||||
await es.index({
|
||||
index,
|
||||
body: {
|
||||
settings: { number_of_shards: 1 },
|
||||
mappings: { properties },
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
log.error(`Failed to create index "${index}" with error "${e.message}"`);
|
||||
}
|
||||
}
|
||||
|
||||
async function generateNewDocs(docsNumber: number, index = SOURCE_DATA_VIEW) {
|
||||
const mockMessages = Array.from({ length: docsNumber }, (_, i) => `msg-${i}`);
|
||||
const dateNow = new Date();
|
||||
const dateToSet = new Date(dateNow);
|
||||
dateToSet.setMinutes(dateNow.getMinutes() - 10);
|
||||
for (const message of mockMessages) {
|
||||
await es.transport.request({
|
||||
path: `/${SOURCE_DATA_VIEW}/_doc`,
|
||||
method: 'POST',
|
||||
body: {
|
||||
'@timestamp': dateToSet.toISOString(),
|
||||
message,
|
||||
},
|
||||
});
|
||||
try {
|
||||
await Promise.all(
|
||||
mockMessages.map((message) =>
|
||||
es.transport.request({
|
||||
path: `/${index}/_doc`,
|
||||
method: 'POST',
|
||||
body: {
|
||||
'@timestamp': dateToSet.toISOString(),
|
||||
message,
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
} catch (e) {
|
||||
log.error(`Failed to generate new docs in "${index}" with error "${e.message}"`);
|
||||
}
|
||||
};
|
||||
|
||||
const createOutputDataIndex = () =>
|
||||
es.index({
|
||||
index: OUTPUT_DATA_VIEW,
|
||||
body: {
|
||||
settings: {
|
||||
number_of_shards: 1,
|
||||
},
|
||||
mappings: {
|
||||
properties: {
|
||||
rule_id: { type: 'text' },
|
||||
rule_name: { type: 'text' },
|
||||
alert_id: { type: 'text' },
|
||||
context_link: { type: 'text' },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const deleteAlerts = (alertIds: string[]) =>
|
||||
asyncForEach(alertIds, async (alertId: string) => {
|
||||
|
|
|
@ -48,53 +48,59 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
let connectorId: string;
|
||||
|
||||
const createSourceIndex = () =>
|
||||
es.index({
|
||||
index: SOURCE_DATA_VIEW,
|
||||
body: {
|
||||
settings: { number_of_shards: 1 },
|
||||
mappings: {
|
||||
properties: {
|
||||
'@timestamp': { type: 'date' },
|
||||
message: { type: 'keyword' },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
retry.try(() =>
|
||||
createIndex(SOURCE_DATA_VIEW, {
|
||||
'@timestamp': { type: 'date' },
|
||||
message: { type: 'keyword' },
|
||||
})
|
||||
);
|
||||
|
||||
const generateNewDocs = async (docsNumber: number) => {
|
||||
const createOutputDataIndex = () =>
|
||||
retry.try(() =>
|
||||
createIndex(OUTPUT_DATA_VIEW, {
|
||||
rule_id: { type: 'text' },
|
||||
rule_name: { type: 'text' },
|
||||
alert_id: { type: 'text' },
|
||||
context_link: { type: 'text' },
|
||||
})
|
||||
);
|
||||
|
||||
async function createIndex(index: string, properties: unknown) {
|
||||
try {
|
||||
await es.index({
|
||||
index,
|
||||
body: {
|
||||
settings: { number_of_shards: 1 },
|
||||
mappings: { properties },
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
log.error(`Failed to create index "${index}" with error "${e.message}"`);
|
||||
}
|
||||
}
|
||||
|
||||
async function generateNewDocs(docsNumber: number, index = SOURCE_DATA_VIEW) {
|
||||
const mockMessages = Array.from({ length: docsNumber }, (_, i) => `msg-${i}`);
|
||||
const dateNow = new Date();
|
||||
const dateToSet = new Date(dateNow);
|
||||
dateToSet.setMinutes(dateNow.getMinutes() - 10);
|
||||
for (const message of mockMessages) {
|
||||
await es.transport.request({
|
||||
path: `/${SOURCE_DATA_VIEW}/_doc`,
|
||||
method: 'POST',
|
||||
body: {
|
||||
'@timestamp': dateToSet.toISOString(),
|
||||
message,
|
||||
},
|
||||
});
|
||||
try {
|
||||
await Promise.all(
|
||||
mockMessages.map((message) =>
|
||||
es.transport.request({
|
||||
path: `/${index}/_doc`,
|
||||
method: 'POST',
|
||||
body: {
|
||||
'@timestamp': dateToSet.toISOString(),
|
||||
message,
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
} catch (e) {
|
||||
log.error(`Failed to generate new docs in "${index}" with error "${e.message}"`);
|
||||
}
|
||||
};
|
||||
|
||||
const createOutputDataIndex = () =>
|
||||
es.index({
|
||||
index: OUTPUT_DATA_VIEW,
|
||||
body: {
|
||||
settings: {
|
||||
number_of_shards: 1,
|
||||
},
|
||||
mappings: {
|
||||
properties: {
|
||||
rule_id: { type: 'text' },
|
||||
rule_name: { type: 'text' },
|
||||
alert_id: { type: 'text' },
|
||||
context_link: { type: 'text' },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const deleteAlerts = (alertIds: string[]) =>
|
||||
asyncForEach(alertIds, async (alertId: string) => {
|
||||
|
@ -216,7 +222,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
const openDiscoverAlertFlyout = async () => {
|
||||
await testSubjects.click('discoverAlertsButton');
|
||||
await testSubjects.click('discoverCreateAlertButton');
|
||||
// Different create rule buttons in serverless
|
||||
if (await testSubjects.exists('discoverCreateAlertButton')) {
|
||||
await testSubjects.click('discoverCreateAlertButton');
|
||||
} else {
|
||||
await testSubjects.click('discoverAppMenuCustomThresholdRule');
|
||||
}
|
||||
};
|
||||
|
||||
const openManagementAlertFlyout = async () => {
|
||||
|
@ -366,8 +377,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
};
|
||||
|
||||
describe('Search source Alert', function () {
|
||||
// see details: https://github.com/elastic/kibana/issues/193842
|
||||
this.tags(['failsOnMKI', 'skipSvlOblt']);
|
||||
// Failing: https://github.com/elastic/kibana/issues/203045
|
||||
this.tags(['skipSvlOblt']);
|
||||
|
||||
before(async () => {
|
||||
await security.testUser.setRoles(['discover_alert']);
|
||||
await PageObjects.svlCommonPage.loginAsAdmin();
|
||||
|
@ -502,7 +514,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
await testSubjects.click('thresholdPopover');
|
||||
await testSubjects.setValue('alertThresholdInput0', '1');
|
||||
await testSubjects.click('saveEditedRuleButton');
|
||||
|
||||
// Different save buttons in serverless
|
||||
if (await testSubjects.exists('saveEditedRuleButton')) {
|
||||
await testSubjects.click('saveEditedRuleButton');
|
||||
} else {
|
||||
await testSubjects.click('rulePageFooterSaveButton');
|
||||
}
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
await openAlertResults(RULE_NAME);
|
||||
|
@ -652,8 +670,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
await retry.waitFor('rule name value is correct', async () => {
|
||||
await testSubjects.setValue('ruleNameInput', newAlert);
|
||||
const ruleName = await testSubjects.getAttribute('ruleNameInput', 'value');
|
||||
let ruleName;
|
||||
// Rule name input is different in serverless
|
||||
if (await testSubjects.exists('ruleNameInput')) {
|
||||
await testSubjects.setValue('ruleNameInput', newAlert);
|
||||
ruleName = await testSubjects.getAttribute('ruleNameInput', 'value');
|
||||
} else {
|
||||
await testSubjects.setValue('ruleDetailsNameInput', newAlert);
|
||||
ruleName = await testSubjects.getAttribute('ruleDetailsNameInput', 'value');
|
||||
}
|
||||
return ruleName === newAlert;
|
||||
});
|
||||
|
||||
|
@ -677,7 +702,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await comboBox.set('ruleFormConsumerSelect', 'Stack Rules');
|
||||
}
|
||||
|
||||
await testSubjects.click('saveRuleButton');
|
||||
// Save rule button is different in serverless
|
||||
if (await testSubjects.exists('saveRuleButton')) {
|
||||
await testSubjects.click('saveRuleButton');
|
||||
} else {
|
||||
await testSubjects.click('rulePageFooterSaveButton');
|
||||
}
|
||||
|
||||
await retry.waitFor('confirmation modal', async () => {
|
||||
return await testSubjects.exists('confirmModalConfirmButton');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue