From 5e9a886d4eea8bf22414d8f8a61985ced0e98342 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 3 Feb 2025 12:34:44 +0100 Subject: [PATCH] add rule upgrade review integration tests --- .../trial_license_complete_tier/index.ts | 1 - .../upgrade_review_prebuilt_rules.stats.ts | 131 ------ .../diffable_rule_fields/index.ts | 3 +- .../customization_enabled/index.ts | 1 + .../preview_prebuilt_rules_upgrade.ts | 400 ++++++++++++++++++ .../upgrade_prebuilt_rules/index.ts | 3 +- 6 files changed, 403 insertions(+), 136 deletions(-) delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.stats.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts index e52b0dfc59cbe..0b57697c483b5 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts @@ -15,6 +15,5 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./install_prebuilt_rules')); loadTestFile(require.resolve('./install_prebuilt_rules_with_historical_versions')); loadTestFile(require.resolve('./fleet_integration')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats')); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.stats.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.stats.ts deleted file mode 100644 index 74010578da9f3..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.stats.ts +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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 expect from 'expect'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - // createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - // patchRule, - createHistoricalPrebuiltRuleAssetSavedObjects, - patchRule, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`the endpoint stats -`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1, name: 'A' }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 1, name: 'A' }), - createRuleAssetSavedObject({ rule_id: 'rule-3', version: 1, name: 'A' }), - ]; - - it('should show how many rules have upgrades', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - const updatedRuleAssetSavedObjects = ['rule-1', 'rule-2', 'rule-3'].map((ruleId) => - createRuleAssetSavedObject({ - rule_id: ruleId, - name: 'A', - version: 2, - }) - ); - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(3); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should show how many rules have updates with conflicts', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rules to generate a solvable conflict - for (const ruleId of ['rule-1', 'rule-2', 'rule-3']) { - await patchRule(supertest, log, { - rule_id: ruleId, - tags: ['one', 'two', 'four'], - }); - } - - const updatedRuleAssetSavedObjects = ['rule-1', 'rule-2', 'rule-3'].map((ruleId) => - createRuleAssetSavedObject({ - rule_id: ruleId, - name: 'A', - version: 2, - tags: ['one', 'two', 'FOUR'], - }) - ); - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(3); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(3); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should show how many rules have updates with non-solvable conflicts', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rules to generate a solvable conflict - for (const ruleId of ['rule-1', 'rule-2', 'rule-3']) { - await patchRule(supertest, log, { - rule_id: ruleId, - tags: ['one', 'two', 'four'], - }); - } - - // Customize a single-line field on two installed rules to generate a non-solvable conflict - for (const ruleId of ['rule-2', 'rule-3']) { - await patchRule(supertest, log, { - rule_id: ruleId, - name: 'B', - }); - } - - const updatedRuleAssetSavedObjects = ['rule-1', 'rule-2', 'rule-3'].map((ruleId) => - createRuleAssetSavedObject({ - rule_id: ruleId, - name: 'C', - version: 2, - tags: ['one', 'two', 'FOUR'], - }) - ); - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(3); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(3); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(2); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts index 7b90b4821856c..243f130ee937e 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts @@ -6,7 +6,7 @@ */ import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { deleteAllTimelines, deleteAllPrebuiltRuleAssets } from '../../../../../utils'; +import { deleteAllPrebuiltRuleAssets } from '../../../../../utils'; import { deleteAllRules } from '../../../../../../../../common/utils/security_solution'; import { nameField } from './name'; import { descriptionField } from './description'; @@ -53,7 +53,6 @@ export default (context: FtrProviderContext): void => { describe('@ess @serverless @skipInServerlessMKI diffable rule fields', () => { beforeEach(async () => { await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); await deleteAllPrebuiltRuleAssets(es, log); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts index 0b70a1536f8fc..f8431c2608953 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts @@ -12,6 +12,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./is_customized_calculation')); loadTestFile(require.resolve('./import_rules')); loadTestFile(require.resolve('./rules_export')); + loadTestFile(require.resolve('./preview_prebuilt_rules_upgrade')); loadTestFile(require.resolve('./upgrade_prebuilt_rules')); loadTestFile(require.resolve('./diffable_rule_fields')); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts new file mode 100644 index 0000000000000..a7566eb8229af --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts @@ -0,0 +1,400 @@ +/* + * 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 expect from 'expect'; +import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { deleteAllPrebuiltRuleAssets, reviewPrebuiltRulesToUpgrade } from '../../../../utils'; +import { setUpRuleUpgrade } from '../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('@ess @serverless @skipInServerlessMKI preview prebuilt rules upgrade', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + describe('stats', () => { + it('returns num of rules with upgrades', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'query-rule', + type: 'query', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 2, + }); + }); + + it('returns zero conflicts when there are no conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'query-rule', + type: 'query', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + }); + + it('returns num of rules with conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagA'], + version: 1, + }, + patch: { + rule_id: 'saved-query-rule', + tags: ['tagB'], + }, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_conflicts: 2, + }); + }); + + it('returns num of rules with non-solvable conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagA'], + version: 1, + }, + patch: { + rule_id: 'saved-query-rule', + tags: ['tagB'], + }, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_non_solvable_conflicts: 1, + }); + }); + + it('returns num of rules with conflicts when historical versions are missing', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'query-rule', + type: 'query', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + name: 'Updated name', + version: 2, + }, + }, + ], + removeInstalledAssets: true, + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_conflicts: 2, + }); + }); + }); + + describe('fields diff stats', () => { + it('returns num of fields with updates', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 3, // name + tags + version = 3 fields + }); + }); + + it('returns num of fields with conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + tags: ['tabB'], + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_conflicts: 2, + }); + }); + + it('returns num of fields with non-solvable conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + tags: ['tabB'], + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_non_solvable_conflicts: 1, + }); + }); + }); + + describe('fields diff', () => { + it('returns fields diff', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules[0].diff.fields).toMatchObject({ + name: expect.any(Object), + tags: expect.any(Object), + }); + }); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts index b74ba80405e72..0e9cbef2e1468 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts @@ -6,7 +6,7 @@ */ import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { deleteAllTimelines, deleteAllPrebuiltRuleAssets } from '../../../../../utils'; +import { deleteAllPrebuiltRuleAssets } from '../../../../../utils'; import { deleteAllRules } from '../../../../../../../../common/utils/security_solution'; import { bulkUpgradeAllPrebuiltRules } from './bulk_upgrade_all_prebuilt_rules'; import { bulkUpgradeSelectedPrebuiltRules } from './bulk_upgrade_selected_prebuilt_rules'; @@ -20,7 +20,6 @@ export default (context: FtrProviderContext): void => { describe('@ess @serverless @skipInServerlessMKI upgrade prebuilt rules', () => { beforeEach(async () => { await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); await deleteAllPrebuiltRuleAssets(es, log); });