forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Security Solution] Expand prebuilt rules install/update workflow tes…
…t coverage (elastic#155241) ## Summary Extends test coverage for the current Prebuilt Rules installation and update workflows, in the Rules Management area. Follows the test plan: https://docs.google.com/document/d/1d_1DYnHlnCaPznWTjeCxhoaRUwxc2O_V0LToAPG0xLE/edit#heading=h.y4vywfmfu3ef Other changes besides the new tests: - Integration tests related to prebuilt rules were moved to a new `prebuilt_rules` dir from their old `group1` dir. - Existing Cypress tests related to prebuilt rules were renamed to `prebuilt_rules_management.cy.ts` to differentiate those tests to the new tests related to notifications, installation and updates. - Prevented the installation of the +700 prebuilt rules in test suites where it is not necessary. Replaced that with installing a low number of mock prebuilt rules, which enables to test the same functionality. - Unskipping tests in [rules_selection.cy.ts](https://github.com/elastic/kibana/blob/3d146298a43e1ba24d83e0ede2758b87e826d0b6/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_selection.cy.ts#L34). See [explanation](elastic#154694 (comment)). ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <[email protected]>
- Loading branch information
1 parent
6a9e8d4
commit d6d4c64
Showing
35 changed files
with
955 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
175 changes: 175 additions & 0 deletions
175
...curity_solution/cypress/e2e/detection_rules/prebuilt_rules_install_update_workflows.cy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import type { BulkInstallPackageInfo } from '@kbn/fleet-plugin/common'; | ||
import type { Rule } from '../../../public/detection_engine/rule_management/logic/types'; | ||
import { createRuleAssetSavedObject } from '../../helpers/rules'; | ||
import { | ||
GO_BACK_TO_RULES_TABLE_BUTTON, | ||
INSTALL_ALL_RULES_BUTTON, | ||
INSTALL_SELECTED_RULES_BUTTON, | ||
RULES_MANAGEMENT_TABLE, | ||
RULES_ROW, | ||
RULES_UPDATES_TABLE, | ||
SELECT_ALL_RULES_ON_PAGE_CHECKBOX, | ||
TOASTER, | ||
} from '../../screens/alerts_detection_rules'; | ||
import { waitForRulesTableToBeLoaded } from '../../tasks/alerts_detection_rules'; | ||
import { | ||
getRuleAssets, | ||
createAndInstallMockedPrebuiltRules, | ||
} from '../../tasks/api_calls/prebuilt_rules'; | ||
import { resetRulesTableState, deleteAlertsAndRules, reload } from '../../tasks/common'; | ||
import { esArchiverResetKibana } from '../../tasks/es_archiver'; | ||
import { login, visitWithoutDateRange } from '../../tasks/login'; | ||
import { SECURITY_DETECTIONS_RULES_URL } from '../../urls/navigation'; | ||
import { | ||
addElasticRulesButtonClick, | ||
assertRuleUpgradeAvailableAndUpgradeAll, | ||
ruleUpdatesTabClick, | ||
} from '../../tasks/prebuilt_rules'; | ||
|
||
describe('Detection rules, Prebuilt Rules Installation and Update workflow', () => { | ||
beforeEach(() => { | ||
login(); | ||
resetRulesTableState(); | ||
deleteAlertsAndRules(); | ||
esArchiverResetKibana(); | ||
|
||
visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); | ||
}); | ||
|
||
describe('Installation of prebuilt rules package via Fleet', () => { | ||
beforeEach(() => { | ||
cy.intercept('POST', '/api/fleet/epm/packages/_bulk*').as('installPackage'); | ||
waitForRulesTableToBeLoaded(); | ||
}); | ||
|
||
it('should install package from Fleet in the background', () => { | ||
/* Assert that the package in installed from Fleet by checking that | ||
/* the installSource is "registry", as opposed to "bundle" */ | ||
cy.wait('@installPackage', { | ||
timeout: 60000, | ||
}).then(({ response }) => { | ||
cy.wrap(response?.statusCode).should('eql', 200); | ||
|
||
const packages = response?.body.items.map(({ name, result }: BulkInstallPackageInfo) => ({ | ||
name, | ||
installSource: result.installSource, | ||
})); | ||
|
||
expect(packages.length).to.have.greaterThan(0); | ||
expect(packages).to.deep.include.members([ | ||
{ name: 'security_detection_engine', installSource: 'registry' }, | ||
]); | ||
}); | ||
}); | ||
|
||
it('should install rules from the Fleet package when user clicks on CTA', () => { | ||
/* Retrieve how many rules were installed from the Fleet package */ | ||
cy.wait('@installPackage', { | ||
timeout: 60000, | ||
}).then(() => { | ||
getRuleAssets().then((response) => { | ||
const ruleIds = response.body.hits.hits.map( | ||
(hit: { _source: { ['security-rule']: Rule } }) => hit._source['security-rule'].rule_id | ||
); | ||
|
||
const numberOfRulesToInstall = new Set(ruleIds).size; | ||
addElasticRulesButtonClick(); | ||
|
||
cy.get(INSTALL_ALL_RULES_BUTTON).click(); | ||
cy.get(TOASTER) | ||
.should('be.visible') | ||
.should('have.text', `${numberOfRulesToInstall} rules installed successfully.`); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('Installation of prebuilt rules', () => { | ||
const RULE_1 = createRuleAssetSavedObject({ | ||
name: 'Test rule 1', | ||
rule_id: 'rule_1', | ||
}); | ||
const RULE_2 = createRuleAssetSavedObject({ | ||
name: 'Test rule 2', | ||
rule_id: 'rule_2', | ||
}); | ||
beforeEach(() => { | ||
createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2], installToKibana: false }); | ||
waitForRulesTableToBeLoaded(); | ||
}); | ||
|
||
it('should install selected rules when user clicks on Install selected rules', () => { | ||
addElasticRulesButtonClick(); | ||
cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click(); | ||
cy.get(INSTALL_SELECTED_RULES_BUTTON).click(); | ||
cy.get(TOASTER).should('be.visible').should('have.text', `2 rules installed successfully.`); | ||
cy.get(GO_BACK_TO_RULES_TABLE_BUTTON).click(); | ||
cy.get(RULES_MANAGEMENT_TABLE).find(RULES_ROW).should('have.length', 2); | ||
cy.get(RULES_MANAGEMENT_TABLE).contains(RULE_1['security-rule'].name); | ||
cy.get(RULES_MANAGEMENT_TABLE).contains(RULE_2['security-rule'].name); | ||
}); | ||
|
||
it('should fail gracefully with toast error message when request to install rules fails', () => { | ||
/* Stub request to force rules installation to fail */ | ||
cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/installation/_perform', { | ||
statusCode: 500, | ||
}).as('installPrebuiltRules'); | ||
addElasticRulesButtonClick(); | ||
cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click(); | ||
cy.get(INSTALL_SELECTED_RULES_BUTTON).click(); | ||
cy.wait('@installPrebuiltRules'); | ||
cy.get(TOASTER).should('be.visible').should('have.text', 'Rule installation failed'); | ||
}); | ||
}); | ||
|
||
describe('Update of prebuilt rules', () => { | ||
const RULE_ID = 'rule_id'; | ||
const OUTDATED_RULE = createRuleAssetSavedObject({ | ||
name: 'Outdated rule', | ||
rule_id: RULE_ID, | ||
version: 1, | ||
}); | ||
const UPDATED_RULE = createRuleAssetSavedObject({ | ||
name: 'Updated rule', | ||
rule_id: RULE_ID, | ||
version: 2, | ||
}); | ||
beforeEach(() => { | ||
/* Create a new rule and install it */ | ||
createAndInstallMockedPrebuiltRules({ rules: [OUTDATED_RULE] }); | ||
/* Create a second version of the rule, making it available for update */ | ||
createAndInstallMockedPrebuiltRules({ rules: [UPDATED_RULE], installToKibana: false }); | ||
waitForRulesTableToBeLoaded(); | ||
reload(); | ||
}); | ||
|
||
it('should update rule succesfully', () => { | ||
cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/upgrade/_perform').as( | ||
'updatePrebuiltRules' | ||
); | ||
ruleUpdatesTabClick(); | ||
assertRuleUpgradeAvailableAndUpgradeAll(OUTDATED_RULE); | ||
cy.get(TOASTER).should('be.visible').should('have.text', `1 rule updated successfully.`); | ||
}); | ||
|
||
it('should fail gracefully with toast error message when request to update rules fails', () => { | ||
/* Stub request to force rules update to fail */ | ||
cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/upgrade/_perform', { | ||
statusCode: 500, | ||
}).as('updatePrebuiltRules'); | ||
ruleUpdatesTabClick(); | ||
assertRuleUpgradeAvailableAndUpgradeAll(OUTDATED_RULE); | ||
cy.get(TOASTER).should('be.visible').should('have.text', 'Rule update failed'); | ||
|
||
/* Assert that the rule has not been updated in the UI */ | ||
cy.get(RULES_UPDATES_TABLE).should('contain', OUTDATED_RULE['security-rule'].name); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
.../plugins/security_solution/cypress/e2e/detection_rules/prebuilt_rules_notifications.cy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { createRuleAssetSavedObject } from '../../helpers/rules'; | ||
import { ADD_ELASTIC_RULES_BTN, RULES_UPDATES_TAB } from '../../screens/alerts_detection_rules'; | ||
import { deleteFirstRule, waitForRulesTableToBeLoaded } from '../../tasks/alerts_detection_rules'; | ||
import { | ||
installAllPrebuiltRulesRequest, | ||
createAndInstallMockedPrebuiltRules, | ||
} from '../../tasks/api_calls/prebuilt_rules'; | ||
import { resetRulesTableState, deleteAlertsAndRules, reload } from '../../tasks/common'; | ||
import { login, visitWithoutDateRange } from '../../tasks/login'; | ||
import { SECURITY_DETECTIONS_RULES_URL } from '../../urls/navigation'; | ||
|
||
describe('Detection rules, Prebuilt Rules Installation and Update workflow', () => { | ||
beforeEach(() => { | ||
login(); | ||
/* Make sure persisted rules table state is cleared */ | ||
resetRulesTableState(); | ||
deleteAlertsAndRules(); | ||
|
||
const RULE_1 = createRuleAssetSavedObject({ | ||
name: 'Test rule 1', | ||
rule_id: 'rule_1', | ||
}); | ||
createAndInstallMockedPrebuiltRules({ rules: [RULE_1], installToKibana: false }); | ||
}); | ||
|
||
describe('Rules installation notification when no rules have been installed', () => { | ||
beforeEach(() => { | ||
visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); | ||
}); | ||
|
||
it('should notify user about prebuilt rules available for installation', () => { | ||
cy.get(ADD_ELASTIC_RULES_BTN).should('be.visible'); | ||
}); | ||
}); | ||
|
||
describe('No notifications', () => { | ||
it('should display no install or update notifications when latest rules are installed', () => { | ||
/* Install current available rules */ | ||
installAllPrebuiltRulesRequest(); | ||
visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); | ||
waitForRulesTableToBeLoaded(); | ||
|
||
/* Assert that there are no installation or update notifications */ | ||
/* Add Elastic Rules button and Rule Upgrade tabs should not contain a number badge */ | ||
cy.get(ADD_ELASTIC_RULES_BTN).should('have.text', 'Add Elastic rules'); | ||
cy.get(RULES_UPDATES_TAB).should('have.text', 'Rule Updates'); | ||
}); | ||
}); | ||
|
||
describe('Rule installation notification when at least one rule already installed', () => { | ||
beforeEach(() => { | ||
installAllPrebuiltRulesRequest(); | ||
/* Create new rule assets with a different rule_id as the one that was */ | ||
/* installed before in order to trigger the installation notification */ | ||
const RULE_2 = createRuleAssetSavedObject({ | ||
name: 'Test rule 2', | ||
rule_id: 'rule_2', | ||
}); | ||
const RULE_3 = createRuleAssetSavedObject({ | ||
name: 'Test rule 3', | ||
rule_id: 'rule_3', | ||
}); | ||
|
||
createAndInstallMockedPrebuiltRules({ rules: [RULE_2, RULE_3], installToKibana: false }); | ||
visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); | ||
waitForRulesTableToBeLoaded(); | ||
}); | ||
|
||
it('should notify user about prebuilt rules package available for installation', () => { | ||
const numberOfAvailableRules = 2; | ||
cy.get(ADD_ELASTIC_RULES_BTN).should('be.visible'); | ||
cy.get(ADD_ELASTIC_RULES_BTN).should( | ||
'have.text', | ||
`Add Elastic rules${numberOfAvailableRules}` | ||
); | ||
}); | ||
|
||
it('should notify user a rule is again available for installation if it is deleted', () => { | ||
/* Install available rules, assert that the notification is gone */ | ||
/* then delete one rule and assert that the notification is back */ | ||
installAllPrebuiltRulesRequest(); | ||
reload(); | ||
deleteFirstRule(); | ||
cy.get(ADD_ELASTIC_RULES_BTN).should('be.visible'); | ||
cy.get(ADD_ELASTIC_RULES_BTN).should('have.text', `Add Elastic rules${1}`); | ||
}); | ||
}); | ||
|
||
describe('Rule update notification', () => { | ||
beforeEach(() => { | ||
installAllPrebuiltRulesRequest(); | ||
/* Create new rule asset with the same rule_id as the one that was installed */ | ||
/* but with a higher version, in order to trigger the update notification */ | ||
const UPDATED_RULE = createRuleAssetSavedObject({ | ||
name: 'Test rule 1.1 (updated)', | ||
rule_id: 'rule_1', | ||
version: 2, | ||
}); | ||
createAndInstallMockedPrebuiltRules({ rules: [UPDATED_RULE], installToKibana: false }); | ||
visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); | ||
waitForRulesTableToBeLoaded(); | ||
reload(); | ||
}); | ||
|
||
it('should notify user about prebuilt rules package available for update', () => { | ||
cy.get(RULES_UPDATES_TAB).should('be.visible'); | ||
cy.get(RULES_UPDATES_TAB).should('have.text', `Rule Updates${1}`); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.