Skip to content

Commit

Permalink
force version non conflict diff when base version is missing
Browse files Browse the repository at this point in the history
  • Loading branch information
maximpn committed Nov 22, 2024
1 parent 05bf56f commit 26a3f57
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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 { ThreeVersionsOf } from '../../../../../../../../common/api/detection_engine';
import {
ThreeWayMergeOutcome,
MissingVersion,
ThreeWayDiffConflict,
} from '../../../../../../../../common/api/detection_engine';
import { forceTargetVersionDiffAlgorithm } from './force_target_version_diff_algorithm';

describe('forceTargetVersionDiffAlgorithm', () => {
describe('when base version exists', () => {
it('returns a NON conflict diff', () => {
const mockVersions: ThreeVersionsOf<number> = {
base_version: 1,
current_version: 1,
target_version: 2,
};

const result = forceTargetVersionDiffAlgorithm(mockVersions);

expect(result).toMatchObject({
conflict: ThreeWayDiffConflict.NONE,
});
});

it('return merge outcome TARGET', () => {
const mockVersions: ThreeVersionsOf<number> = {
base_version: 1,
current_version: 1,
target_version: 2,
};

const result = forceTargetVersionDiffAlgorithm(mockVersions);

expect(result).toMatchObject({
has_base_version: true,
merge_outcome: ThreeWayMergeOutcome.Target,
});
});
});

describe('when base version missing', () => {
it('returns a NON conflict diff', () => {
const mockVersions: ThreeVersionsOf<number> = {
base_version: MissingVersion,
current_version: 1,
target_version: 2,
};

const result = forceTargetVersionDiffAlgorithm(mockVersions);

expect(result).toMatchObject({
conflict: ThreeWayDiffConflict.NONE,
});
});

it('return merge outcome TARGET', () => {
const mockVersions: ThreeVersionsOf<number> = {
base_version: MissingVersion,
current_version: 1,
target_version: 2,
};

const result = forceTargetVersionDiffAlgorithm(mockVersions);

expect(result).toMatchObject({
has_base_version: false,
merge_outcome: ThreeWayMergeOutcome.Target,
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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 {
ThreeVersionsOf,
ThreeWayDiff,
} from '../../../../../../../../common/api/detection_engine/prebuilt_rules';
import {
MissingVersion,
ThreeWayDiffConflict,
ThreeWayDiffOutcome,
ThreeWayMergeOutcome,
} from '../../../../../../../../common/api/detection_engine/prebuilt_rules';

/**
* Diff algorithm forcing target version. Useful for special fields like `version`.
*/
export const forceTargetVersionDiffAlgorithm = <TValue>(
versions: ThreeVersionsOf<TValue>
): ThreeWayDiff<TValue> => {
const {
base_version: baseVersion,
current_version: currentVersion,
target_version: targetVersion,
} = versions;
const hasBaseVersion = baseVersion !== MissingVersion;

return {
has_base_version: hasBaseVersion,
base_version: hasBaseVersion ? baseVersion : undefined,
current_version: currentVersion,
target_version: targetVersion,
merged_version: targetVersion,
merge_outcome: ThreeWayMergeOutcome.Target,

diff_outcome: hasBaseVersion
? ThreeWayDiffOutcome.StockValueCanUpdate
: ThreeWayDiffOutcome.MissingBaseCanUpdate,
has_update: false,
conflict: ThreeWayDiffConflict.NONE,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export { kqlQueryDiffAlgorithm } from './kql_query_diff_algorithm';
export { eqlQueryDiffAlgorithm } from './eql_query_diff_algorithm';
export { esqlQueryDiffAlgorithm } from './esql_query_diff_algorithm';
export { ruleTypeDiffAlgorithm } from './rule_type_diff_algorithm';
export { forceTargetVersionDiffAlgorithm } from './force_target_version_diff_algorithm';
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
eqlQueryDiffAlgorithm,
esqlQueryDiffAlgorithm,
ruleTypeDiffAlgorithm,
forceTargetVersionDiffAlgorithm,
} from './algorithms';

const BASE_TYPE_ERROR = `Base version can't be of different rule type`;
Expand Down Expand Up @@ -179,7 +180,11 @@ const calculateCommonFieldsDiff = (

const commonFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor<DiffableCommonFields> = {
rule_id: simpleDiffAlgorithm,
version: numberDiffAlgorithm,
/**
* `version` shouldn't have a conflict. It always get target value automatically.
* Diff has informational purpose.
*/
version: forceTargetVersionDiffAlgorithm,
name: singleLineStringDiffAlgorithm,
tags: scalarArrayDiffAlgorithm,
description: multiLineStringDiffAlgorithm,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,15 @@ export default ({ getService }: FtrProviderContext): void => {
const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff;
expect(fieldDiffObject.data_source).toBeUndefined();

expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1);
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);
expect(reviewResponse.stats).toMatchObject({
num_rules_with_conflicts: 0,
num_rules_with_non_solvable_conflicts: 0,
});
expect(reviewResponse.rules[0].diff).toMatchObject({
num_fields_with_updates: 0,
num_fields_with_conflicts: 0,
num_fields_with_non_solvable_conflicts: 0,
});
});
});

Expand Down

0 comments on commit 26a3f57

Please sign in to comment.