mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[8.x] [Security Solution] Integration tests for `query` diff algorithms (#192655) (#193108)
# Backport This will backport the following commits from `main` to `8.x`: - [[Security Solution] Integration tests for `query` diff algorithms (#192655)](https://github.com/elastic/kibana/pull/192655) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Davis Plumlee","email":"56367316+dplumlee@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-09-16T23:58:55Z","message":"[Security Solution] Integration tests for `query` diff algorithms (#192655)\n\n## Summary\r\n\r\nCompletes https://github.com/elastic/kibana/issues/187658\r\n\r\n\r\nSwitches `kql_query`, `eql_query`, and `esql_query` fields to use the\r\nimplemented diff algorithms assigned to them in\r\nhttps://github.com/elastic/kibana/pull/190179\r\n\r\n\r\nAdds integration tests in accordance to\r\nhttps://github.com/elastic/kibana/pull/192529 for the `upgrade/_review`\r\nAPI endpoint for the `query` field diff algorithms.\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n- [x] [Flaky Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\r\nused on any tests changed\r\n\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"ceb1b1a4bf253ac94f9ba0ba649e9a4908a76c51","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["test","release_note:skip","v9.0.0","Team:Detections and Resp","Team: SecuritySolution","Team:Detection Rule Management","Feature:Prebuilt Detection Rules","v8.16.0"],"title":"[Security Solution] Integration tests for `query` diff algorithms","number":192655,"url":"https://github.com/elastic/kibana/pull/192655","mergeCommit":{"message":"[Security Solution] Integration tests for `query` diff algorithms (#192655)\n\n## Summary\r\n\r\nCompletes https://github.com/elastic/kibana/issues/187658\r\n\r\n\r\nSwitches `kql_query`, `eql_query`, and `esql_query` fields to use the\r\nimplemented diff algorithms assigned to them in\r\nhttps://github.com/elastic/kibana/pull/190179\r\n\r\n\r\nAdds integration tests in accordance to\r\nhttps://github.com/elastic/kibana/pull/192529 for the `upgrade/_review`\r\nAPI endpoint for the `query` field diff algorithms.\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n- [x] [Flaky Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\r\nused on any tests changed\r\n\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"ceb1b1a4bf253ac94f9ba0ba649e9a4908a76c51"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/192655","number":192655,"mergeCommit":{"message":"[Security Solution] Integration tests for `query` diff algorithms (#192655)\n\n## Summary\r\n\r\nCompletes https://github.com/elastic/kibana/issues/187658\r\n\r\n\r\nSwitches `kql_query`, `eql_query`, and `esql_query` fields to use the\r\nimplemented diff algorithms assigned to them in\r\nhttps://github.com/elastic/kibana/pull/190179\r\n\r\n\r\nAdds integration tests in accordance to\r\nhttps://github.com/elastic/kibana/pull/192529 for the `upgrade/_review`\r\nAPI endpoint for the `query` field diff algorithms.\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n- [x] [Flaky Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\r\nused on any tests changed\r\n\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"ceb1b1a4bf253ac94f9ba0ba649e9a4908a76c51"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Davis Plumlee <56367316+dplumlee@users.noreply.github.com>
This commit is contained in:
parent
87786b5783
commit
9d09dbfcd4
5 changed files with 2041 additions and 8 deletions
|
@ -44,6 +44,9 @@ import {
|
|||
scalarArrayDiffAlgorithm,
|
||||
simpleDiffAlgorithm,
|
||||
singleLineStringDiffAlgorithm,
|
||||
kqlQueryDiffAlgorithm,
|
||||
eqlQueryDiffAlgorithm,
|
||||
esqlQueryDiffAlgorithm,
|
||||
} from './algorithms';
|
||||
|
||||
const BASE_TYPE_ERROR = `Base version can't be of different rule type`;
|
||||
|
@ -210,7 +213,7 @@ const calculateCustomQueryFieldsDiff = (
|
|||
|
||||
const customQueryFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor<DiffableCustomQueryFields> = {
|
||||
type: simpleDiffAlgorithm,
|
||||
kql_query: simpleDiffAlgorithm,
|
||||
kql_query: kqlQueryDiffAlgorithm,
|
||||
data_source: dataSourceDiffAlgorithm,
|
||||
alert_suppression: simpleDiffAlgorithm,
|
||||
};
|
||||
|
@ -223,7 +226,7 @@ const calculateSavedQueryFieldsDiff = (
|
|||
|
||||
const savedQueryFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor<DiffableSavedQueryFields> = {
|
||||
type: simpleDiffAlgorithm,
|
||||
kql_query: simpleDiffAlgorithm,
|
||||
kql_query: kqlQueryDiffAlgorithm,
|
||||
data_source: dataSourceDiffAlgorithm,
|
||||
alert_suppression: simpleDiffAlgorithm,
|
||||
};
|
||||
|
@ -236,7 +239,7 @@ const calculateEqlFieldsDiff = (
|
|||
|
||||
const eqlFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor<DiffableEqlFields> = {
|
||||
type: simpleDiffAlgorithm,
|
||||
eql_query: simpleDiffAlgorithm,
|
||||
eql_query: eqlQueryDiffAlgorithm,
|
||||
data_source: dataSourceDiffAlgorithm,
|
||||
event_category_override: singleLineStringDiffAlgorithm,
|
||||
timestamp_field: singleLineStringDiffAlgorithm,
|
||||
|
@ -252,7 +255,7 @@ const calculateEsqlFieldsDiff = (
|
|||
|
||||
const esqlFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor<DiffableEsqlFields> = {
|
||||
type: simpleDiffAlgorithm,
|
||||
esql_query: simpleDiffAlgorithm,
|
||||
esql_query: esqlQueryDiffAlgorithm,
|
||||
alert_suppression: simpleDiffAlgorithm,
|
||||
};
|
||||
|
||||
|
@ -264,9 +267,9 @@ const calculateThreatMatchFieldsDiff = (
|
|||
|
||||
const threatMatchFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor<DiffableThreatMatchFields> = {
|
||||
type: simpleDiffAlgorithm,
|
||||
kql_query: simpleDiffAlgorithm,
|
||||
kql_query: kqlQueryDiffAlgorithm,
|
||||
data_source: dataSourceDiffAlgorithm,
|
||||
threat_query: simpleDiffAlgorithm,
|
||||
threat_query: kqlQueryDiffAlgorithm,
|
||||
threat_index: scalarArrayDiffAlgorithm,
|
||||
threat_mapping: simpleDiffAlgorithm,
|
||||
threat_indicator_path: singleLineStringDiffAlgorithm,
|
||||
|
@ -282,7 +285,7 @@ const calculateThresholdFieldsDiff = (
|
|||
|
||||
const thresholdFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor<DiffableThresholdFields> = {
|
||||
type: simpleDiffAlgorithm,
|
||||
kql_query: simpleDiffAlgorithm,
|
||||
kql_query: kqlQueryDiffAlgorithm,
|
||||
data_source: dataSourceDiffAlgorithm,
|
||||
threshold: simpleDiffAlgorithm,
|
||||
alert_suppression: simpleDiffAlgorithm,
|
||||
|
@ -310,7 +313,7 @@ const calculateNewTermsFieldsDiff = (
|
|||
|
||||
const newTermsFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor<DiffableNewTermsFields> = {
|
||||
type: simpleDiffAlgorithm,
|
||||
kql_query: simpleDiffAlgorithm,
|
||||
kql_query: kqlQueryDiffAlgorithm,
|
||||
data_source: dataSourceDiffAlgorithm,
|
||||
new_terms_fields: scalarArrayDiffAlgorithm,
|
||||
history_window_start: singleLineStringDiffAlgorithm,
|
||||
|
|
|
@ -22,6 +22,9 @@ export default ({ loadTestFile }: FtrProviderContext): void => {
|
|||
loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.scalar_array_fields'));
|
||||
loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.multi_line_string_fields'));
|
||||
loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.data_source_fields'));
|
||||
loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.kql_query_fields'));
|
||||
loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.eql_query_fields'));
|
||||
loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.esql_query_fields'));
|
||||
loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats'));
|
||||
});
|
||||
};
|
||||
|
|
|
@ -0,0 +1,465 @@
|
|||
/*
|
||||
* 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 {
|
||||
AllFieldsDiff,
|
||||
RuleUpdateProps,
|
||||
ThreeWayDiffConflict,
|
||||
ThreeWayDiffOutcome,
|
||||
ThreeWayMergeOutcome,
|
||||
} from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { getPrebuiltRuleMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks';
|
||||
import { FtrProviderContext } from '../../../../../../ftr_provider_context';
|
||||
import {
|
||||
deleteAllTimelines,
|
||||
deleteAllPrebuiltRuleAssets,
|
||||
createRuleAssetSavedObject,
|
||||
installPrebuiltRules,
|
||||
createPrebuiltRuleAssetSavedObjects,
|
||||
reviewPrebuiltRulesToUpgrade,
|
||||
createHistoricalPrebuiltRuleAssetSavedObjects,
|
||||
updateRule,
|
||||
} 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 from package with mock rule assets', () => {
|
||||
beforeEach(async () => {
|
||||
await deleteAllRules(supertest, log);
|
||||
await deleteAllTimelines(es, log);
|
||||
await deleteAllPrebuiltRuleAssets(es, log);
|
||||
});
|
||||
|
||||
describe(`eql_query fields`, () => {
|
||||
const getRuleAssetSavedObjects = () => [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 1,
|
||||
type: 'eql',
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
}),
|
||||
];
|
||||
|
||||
describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => {
|
||||
it('should not show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, do NOT update the related eql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'eql',
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but eql_query field is NOT returned
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.eql_query).toBeUndefined();
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => {
|
||||
it('should show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Customize an eql_query field on the installed rule
|
||||
await updateRule(supertest, {
|
||||
...getPrebuiltRuleMock(),
|
||||
rule_id: 'rule-1',
|
||||
type: 'eql',
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
} as RuleUpdateProps);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, do NOT update the related eql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'eql',
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that eql_query diff field is returned but field does not have an update
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.eql_query).toEqual({
|
||||
base_version: {
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
current_version: {
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
target_version: {
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
merged_version: {
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Current,
|
||||
conflict: ThreeWayDiffConflict.NONE,
|
||||
has_update: false,
|
||||
has_base_version: true,
|
||||
});
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule field has an update but does not have a custom value - scenario AAB', () => {
|
||||
it('should show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'eql',
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.eql_query).toEqual({
|
||||
base_version: {
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
current_version: {
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
target_version: {
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
merged_version: {
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Target,
|
||||
conflict: ThreeWayDiffConflict.NONE,
|
||||
has_update: true,
|
||||
has_base_version: true,
|
||||
});
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule field has an update and a custom value that are the same - scenario ABB', () => {
|
||||
it('should show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Customize an eql_query field on the installed rule
|
||||
await updateRule(supertest, {
|
||||
...getPrebuiltRuleMock(),
|
||||
rule_id: 'rule-1',
|
||||
type: 'eql',
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
} as RuleUpdateProps);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'eql',
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains eql_query field
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.eql_query).toEqual({
|
||||
base_version: {
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
current_version: {
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
target_version: {
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
merged_version: {
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Current,
|
||||
conflict: ThreeWayDiffConflict.NONE,
|
||||
has_update: false,
|
||||
has_base_version: true,
|
||||
});
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule field has an update and a custom value that are different - scenario ABC', () => {
|
||||
it('should show a non-solvable conflict in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Customize an eql_query field on the installed rule
|
||||
await updateRule(supertest, {
|
||||
...getPrebuiltRuleMock(),
|
||||
rule_id: 'rule-1',
|
||||
type: 'eql',
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [{ field: 'query' }],
|
||||
} as RuleUpdateProps);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'eql',
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update
|
||||
// and eql_query field update has conflict
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.eql_query).toEqual({
|
||||
base_version: {
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
current_version: {
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [{ field: 'query' }],
|
||||
},
|
||||
target_version: {
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
merged_version: {
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [{ field: 'query' }],
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Current,
|
||||
conflict: ThreeWayDiffConflict.NON_SOLVABLE,
|
||||
has_update: true,
|
||||
has_base_version: true,
|
||||
});
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule base version does not exist', () => {
|
||||
describe('when rule field has an update and a custom value that are the same - scenario -AA', () => {
|
||||
it('should not show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Clear previous rule assets
|
||||
await deleteAllPrebuiltRuleAssets(es, log);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, but keep eql_query field unchanged
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'eql',
|
||||
query: 'query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
}),
|
||||
];
|
||||
await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update
|
||||
// but does NOT contain eql_query field
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.eql_query).toBeUndefined();
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // `version` is considered conflict
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule field has an update and a custom value that are different - scenario -AB', () => {
|
||||
it('should show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Clear previous rule assets
|
||||
await deleteAllPrebuiltRuleAssets(es, log);
|
||||
|
||||
// Customize an eql_query field on the installed rule
|
||||
await updateRule(supertest, {
|
||||
...getPrebuiltRuleMock(),
|
||||
rule_id: 'rule-1',
|
||||
type: 'eql',
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
} as RuleUpdateProps);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'eql',
|
||||
query: 'new query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
}),
|
||||
];
|
||||
await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update
|
||||
// and eql_query field update does not have a conflict
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.eql_query).toEqual({
|
||||
current_version: {
|
||||
query: 'query where false',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
target_version: {
|
||||
query: 'new query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
merged_version: {
|
||||
query: 'new query where true',
|
||||
language: 'eql',
|
||||
filters: [],
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Target,
|
||||
conflict: ThreeWayDiffConflict.SOLVABLE,
|
||||
has_update: true,
|
||||
has_base_version: false,
|
||||
});
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // version + query
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(2); // version + query
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
|
@ -0,0 +1,434 @@
|
|||
/*
|
||||
* 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 {
|
||||
AllFieldsDiff,
|
||||
RuleUpdateProps,
|
||||
ThreeWayDiffConflict,
|
||||
ThreeWayDiffOutcome,
|
||||
ThreeWayMergeOutcome,
|
||||
} from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { getPrebuiltRuleMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks';
|
||||
import { FtrProviderContext } from '../../../../../../ftr_provider_context';
|
||||
import {
|
||||
deleteAllTimelines,
|
||||
deleteAllPrebuiltRuleAssets,
|
||||
createRuleAssetSavedObject,
|
||||
installPrebuiltRules,
|
||||
createPrebuiltRuleAssetSavedObjects,
|
||||
reviewPrebuiltRulesToUpgrade,
|
||||
createHistoricalPrebuiltRuleAssetSavedObjects,
|
||||
updateRule,
|
||||
} 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 from package with mock rule assets', () => {
|
||||
beforeEach(async () => {
|
||||
await deleteAllRules(supertest, log);
|
||||
await deleteAllTimelines(es, log);
|
||||
await deleteAllPrebuiltRuleAssets(es, log);
|
||||
});
|
||||
|
||||
describe(`esql_query fields`, () => {
|
||||
const getRuleAssetSavedObjects = () => [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 1,
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
}),
|
||||
];
|
||||
|
||||
describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => {
|
||||
it('should not show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, do NOT update the related esql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but esql_query field is NOT returned
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.esql_query).toBeUndefined();
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => {
|
||||
it('should show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Customize an esql_query field on the installed rule
|
||||
await updateRule(supertest, {
|
||||
...getPrebuiltRuleMock(),
|
||||
rule_id: 'rule-1',
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
} as RuleUpdateProps);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, do NOT update the related esql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that esql_query diff field is returned but field does not have an update
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.esql_query).toEqual({
|
||||
base_version: {
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
},
|
||||
current_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
target_version: {
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
},
|
||||
merged_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Current,
|
||||
conflict: ThreeWayDiffConflict.NONE,
|
||||
has_update: false,
|
||||
has_base_version: true,
|
||||
});
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule field has an update but does not have a custom value - scenario AAB', () => {
|
||||
it('should show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.esql_query).toEqual({
|
||||
base_version: {
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
},
|
||||
current_version: {
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
},
|
||||
target_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
merged_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Target,
|
||||
conflict: ThreeWayDiffConflict.NONE,
|
||||
has_update: true,
|
||||
has_base_version: true,
|
||||
});
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule field has an update and a custom value that are the same - scenario ABB', () => {
|
||||
it('should show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Customize an esql_query field on the installed rule
|
||||
await updateRule(supertest, {
|
||||
...getPrebuiltRuleMock(),
|
||||
rule_id: 'rule-1',
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
} as RuleUpdateProps);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains esql_query field
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.esql_query).toEqual({
|
||||
base_version: {
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
},
|
||||
current_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
target_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
merged_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Current,
|
||||
conflict: ThreeWayDiffConflict.NONE,
|
||||
has_update: false,
|
||||
has_base_version: true,
|
||||
});
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule field has an update and a custom value that are different - scenario ABC', () => {
|
||||
it('should show a non-solvable conflict in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Customize an esql_query field on the installed rule
|
||||
await updateRule(supertest, {
|
||||
...getPrebuiltRuleMock(),
|
||||
rule_id: 'rule-1',
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
} as RuleUpdateProps);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'esql',
|
||||
query: 'FROM new query WHERE true',
|
||||
language: 'esql',
|
||||
}),
|
||||
];
|
||||
await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update
|
||||
// and esql_query field update has conflict
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.esql_query).toEqual({
|
||||
base_version: {
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
},
|
||||
current_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
target_version: {
|
||||
query: 'FROM new query WHERE true',
|
||||
language: 'esql',
|
||||
},
|
||||
merged_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Current,
|
||||
conflict: ThreeWayDiffConflict.NON_SOLVABLE,
|
||||
has_update: true,
|
||||
has_base_version: true,
|
||||
});
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule base version does not exist', () => {
|
||||
describe('when rule field has an update and a custom value that are the same - scenario -AA', () => {
|
||||
it('should not show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Clear previous rule assets
|
||||
await deleteAllPrebuiltRuleAssets(es, log);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, but keep esql_query field unchanged
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE true',
|
||||
language: 'esql',
|
||||
}),
|
||||
];
|
||||
await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update
|
||||
// but does NOT contain esql_query field
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.esql_query).toBeUndefined();
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // version is considered conflict
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rule field has an update and a custom value that are different - scenario -AB', () => {
|
||||
it('should show in the upgrade/_review API response', async () => {
|
||||
// Install base prebuilt detection rule
|
||||
await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects());
|
||||
await installPrebuiltRules(es, supertest);
|
||||
|
||||
// Clear previous rule assets
|
||||
await deleteAllPrebuiltRuleAssets(es, log);
|
||||
|
||||
// Customize an esql_query field on the installed rule
|
||||
await updateRule(supertest, {
|
||||
...getPrebuiltRuleMock(),
|
||||
rule_id: 'rule-1',
|
||||
type: 'esql',
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
} as RuleUpdateProps);
|
||||
|
||||
// Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets
|
||||
const updatedRuleAssetSavedObjects = [
|
||||
createRuleAssetSavedObject({
|
||||
rule_id: 'rule-1',
|
||||
version: 2,
|
||||
type: 'esql',
|
||||
query: 'FROM new query WHERE true',
|
||||
language: 'esql',
|
||||
}),
|
||||
];
|
||||
await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects);
|
||||
|
||||
// Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update
|
||||
// and esql_query field update does not have a conflict
|
||||
const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest);
|
||||
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
|
||||
expect(fieldDiffObject.esql_query).toEqual({
|
||||
current_version: {
|
||||
query: 'FROM query WHERE false',
|
||||
language: 'esql',
|
||||
},
|
||||
target_version: {
|
||||
query: 'FROM new query WHERE true',
|
||||
language: 'esql',
|
||||
},
|
||||
merged_version: {
|
||||
query: 'FROM new query WHERE true',
|
||||
language: 'esql',
|
||||
},
|
||||
diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate,
|
||||
merge_outcome: ThreeWayMergeOutcome.Target,
|
||||
conflict: ThreeWayDiffConflict.SOLVABLE,
|
||||
has_update: true,
|
||||
has_base_version: false,
|
||||
});
|
||||
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2);
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(2); // version + query
|
||||
expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0);
|
||||
|
||||
expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1);
|
||||
expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue