From 7670d26c30ab325ebe4b17e31990c38e5423fb10 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 16 Jul 2024 22:47:21 +0200 Subject: [PATCH] [8.15] [Detection Engine] Fix flake in ML Rule Cypress tests (#188164) (#188483) # Backport This will backport the following commits from `main` to `8.15`: - [[Detection Engine] Fix flake in ML Rule Cypress tests (#188164)](https://github.com/elastic/kibana/pull/188164) ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) Co-authored-by: Ryland Herrick --- .../machine_learning_rule_suppression.cy.ts | 4 ++-- .../rule_edit/machine_learning_rule.cy.ts | 4 ++-- .../cypress/support/machine_learning.ts | 20 ++++++++++++++++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/machine_learning_rule_suppression.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/machine_learning_rule_suppression.cy.ts index befa75fce93ff..3052c6dbc95c2 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/machine_learning_rule_suppression.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/machine_learning_rule_suppression.cy.ts @@ -19,9 +19,9 @@ import { SUPPRESS_MISSING_FIELD, } from '../../../../screens/rule_details'; import { - executeSetupModuleRequest, forceStartDatafeeds, forceStopAndCloseJob, + setupMlModulesWithRetry, } from '../../../../support/machine_learning'; import { continueFromDefineStep, @@ -94,7 +94,7 @@ describe( describe('when ML jobs have run', () => { before(() => { cy.task('esArchiverLoad', { archiveName: '../auditbeat/hosts', type: 'ftr' }); - executeSetupModuleRequest({ moduleName: 'security_linux_v3' }); + setupMlModulesWithRetry({ moduleName: 'security_linux_v3' }); forceStartDatafeeds({ jobIds: [jobId] }); cy.task('esArchiverLoad', { archiveName: 'anomalies', type: 'ftr' }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_edit/machine_learning_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_edit/machine_learning_rule.cy.ts index 5e6cd673070ba..abaa3c567b690 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_edit/machine_learning_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_edit/machine_learning_rule.cy.ts @@ -19,9 +19,9 @@ import { SUPPRESS_MISSING_FIELD, } from '../../../../screens/rule_details'; import { - executeSetupModuleRequest, forceStartDatafeeds, forceStopAndCloseJob, + setupMlModulesWithRetry, } from '../../../../support/machine_learning'; import { editFirstRule } from '../../../../tasks/alerts_detection_rules'; import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; @@ -71,7 +71,7 @@ describe( login(); deleteAlertsAndRules(); cy.task('esArchiverLoad', { archiveName: '../auditbeat/hosts', type: 'ftr' }); - executeSetupModuleRequest({ moduleName: 'security_linux_v3' }); + setupMlModulesWithRetry({ moduleName: 'security_linux_v3' }); forceStartDatafeeds({ jobIds: [jobId] }); cy.task('esArchiverLoad', { archiveName: 'anomalies', type: 'ftr' }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/support/machine_learning.ts b/x-pack/test/security_solution_cypress/cypress/support/machine_learning.ts index 5fb869cebc29f..b10b4d827445a 100644 --- a/x-pack/test/security_solution_cypress/cypress/support/machine_learning.ts +++ b/x-pack/test/security_solution_cypress/cypress/support/machine_learning.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { recurse } from 'cypress-recurse'; import { ML_GROUP_ID } from '@kbn/security-solution-plugin/common/constants'; import { rootRequest } from '../tasks/api_calls/common'; @@ -16,7 +17,7 @@ import { rootRequest } from '../tasks/api_calls/common'; * @returns the response from the setup module request */ export const executeSetupModuleRequest = ({ moduleName }: { moduleName: string }) => - rootRequest({ + rootRequest<{ jobs: Array<{ success: boolean; error?: { status: number } }> }>({ headers: { 'elastic-api-version': 1, }, @@ -33,6 +34,23 @@ export const executeSetupModuleRequest = ({ moduleName }: { moduleName: string } }, }); +/** + * + * Calls {@link executeSetupModuleRequest} until all jobs in the module are + * successfully set up. + * @param moduleName the name of the ML module to set up + * @returns the response from the setup module request + */ +export const setupMlModulesWithRetry = ({ moduleName }: { moduleName: string }) => + recurse( + () => executeSetupModuleRequest({ moduleName }), + (response) => + response.body.jobs.every( + (job) => job.success || (job.error?.status && job.error.status < 500) + ), + { delay: 1000 } + ); + /** * * Calls the internal ML Jobs API to force start the datafeeds for the given job IDs. Necessary to get them in the "started" state for the purposes of the detection engine