Skip to content

Commit

Permalink
addresses comments
Browse files Browse the repository at this point in the history
  • Loading branch information
dplumlee committed Jul 30, 2024
1 parent 638dc71 commit 687d07f
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import { isEqual } from 'lodash';
import { MissingVersion } from './three_way_diff';
import type { RuleDataSource } from '../diffable_rule/diffable_field_types';
import { DataSourceType } from '../diffable_rule/diffable_field_types';

/**
* Result of comparing three versions of a value against each other.
Expand Down Expand Up @@ -75,6 +77,33 @@ export const determineOrderAgnosticDiffOutcome = <TValue>(
});
};

/**
* Determines diff outcome for `data_source` field
*
* NOTE: uses order agnostic comparison for nested array fields (e.g. `index`)
*/
export const determineDiffOutcomeForDataSource = (
baseVersion: RuleDataSource | MissingVersion,
currentVersion: RuleDataSource,
targetVersion: RuleDataSource
): ThreeWayDiffOutcome => {
const isBaseVersionMissing = baseVersion === MissingVersion;

if (
(isBaseVersionMissing || isIndexPatternDataSourceType(baseVersion)) &&
isIndexPatternDataSourceType(currentVersion) &&
isIndexPatternDataSourceType(targetVersion)
) {
return determineOrderAgnosticDiffOutcome(
isBaseVersionMissing ? MissingVersion : baseVersion.index_patterns,
currentVersion.index_patterns,
targetVersion.index_patterns
);
}

return determineDiffOutcome(baseVersion, currentVersion, targetVersion);
};

interface DetermineDiffOutcomeProps {
baseEqlCurrent: boolean;
baseEqlTarget: boolean;
Expand Down Expand Up @@ -121,3 +150,8 @@ export const determineIfValueCanUpdate = (diffCase: ThreeWayDiffOutcome): boolea
diffCase === ThreeWayDiffOutcome.MissingBaseCanUpdate
);
};

const isIndexPatternDataSourceType = (
version: RuleDataSource
): version is Extract<RuleDataSource, { type: DataSourceType.index_patterns }> =>
version.type === DataSourceType.index_patterns;
Original file line number Diff line number Diff line change
Expand Up @@ -166,32 +166,53 @@ describe('dataSourceDiffAlgorithm', () => {
});
});

it('returns current_version as merged output if current version is different but it matches the update - scenario ABB', () => {
const mockVersions: ThreeVersionsOf<RuleDataSource> = {
base_version: {
type: DataSourceType.index_patterns,
index_patterns: ['one', 'two', 'three'],
},
current_version: {
type: DataSourceType.index_patterns,
index_patterns: ['one', 'three', 'four'],
},
target_version: {
type: DataSourceType.index_patterns,
index_patterns: ['one', 'three', 'four'],
},
};

const result = dataSourceDiffAlgorithm(mockVersions);

expect(result).toEqual(
expect.objectContaining({
merged_version: mockVersions.current_version,
diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate,
merge_outcome: ThreeWayMergeOutcome.Current,
conflict: ThreeWayDiffConflict.NONE,
})
);
describe('returns current_version as merged output if current version is different but it matches the update - scenario ABB', () => {
it('if all versions are index patterns', () => {
const mockVersions: ThreeVersionsOf<RuleDataSource> = {
base_version: {
type: DataSourceType.index_patterns,
index_patterns: ['one', 'two', 'three'],
},
current_version: {
type: DataSourceType.index_patterns,
index_patterns: ['one', 'three', 'four'],
},
target_version: {
type: DataSourceType.index_patterns,
index_patterns: ['one', 'three', 'four'],
},
};

const result = dataSourceDiffAlgorithm(mockVersions);

expect(result).toEqual(
expect.objectContaining({
merged_version: mockVersions.current_version,
diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate,
merge_outcome: ThreeWayMergeOutcome.Current,
conflict: ThreeWayDiffConflict.NONE,
})
);
});

it('if all versions are data views', () => {
const mockVersions: ThreeVersionsOf<RuleDataSource> = {
base_version: { type: DataSourceType.data_view, data_view_id: '123' },
current_version: { type: DataSourceType.data_view, data_view_id: '456' },
target_version: { type: DataSourceType.data_view, data_view_id: '456' },
};

const result = dataSourceDiffAlgorithm(mockVersions);

expect(result).toEqual(
expect.objectContaining({
merged_version: mockVersions.current_version,
diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate,
merge_outcome: ThreeWayMergeOutcome.Current,
conflict: ThreeWayDiffConflict.NONE,
})
);
});
});

describe('returns current_version as merged output if all three versions are different - scenario ABC', () => {
Expand Down Expand Up @@ -260,14 +281,19 @@ describe('dataSourceDiffAlgorithm', () => {
},
};

const expectedMergedVersion: RuleDataSource = {
type: DataSourceType.index_patterns,
index_patterns: ['one', 'three', 'four', 'two', 'five'],
};

const result = dataSourceDiffAlgorithm(mockVersions);

expect(result).toEqual(
expect.objectContaining({
merged_version: mockVersions.current_version,
merged_version: expectedMergedVersion,
diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate,
merge_outcome: ThreeWayMergeOutcome.Current,
conflict: ThreeWayDiffConflict.NON_SOLVABLE,
merge_outcome: ThreeWayMergeOutcome.Merged,
conflict: ThreeWayDiffConflict.SOLVABLE,
})
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,23 @@
* 2.0.
*/

import { uniq } from 'lodash';
import { union } from 'lodash';
import { assertUnreachable } from '../../../../../../../../common/utility_types';
import type {
RuleDataSource,
ThreeVersionsOf,
ThreeWayDiff,
} from '../../../../../../../../common/api/detection_engine/prebuilt_rules';
import {
determineDiffOutcome,
determineIfValueCanUpdate,
ThreeWayDiffOutcome,
ThreeWayMergeOutcome,
MissingVersion,
DataSourceType,
determineOrderAgnosticDiffOutcome,
ThreeWayDiffConflict,
determineDiffOutcomeForDataSource,
} from '../../../../../../../../common/api/detection_engine/prebuilt_rules';
import { mergeDedupedArrays } from './helpers';
import { getDedupedDataSourceVersion, mergeDedupedArrays } from './helpers';

export const dataSourceDiffAlgorithm = (
versions: ThreeVersionsOf<RuleDataSource>
Expand All @@ -33,36 +32,7 @@ export const dataSourceDiffAlgorithm = (
target_version: targetVersion,
} = versions;

let diffOutcome: ThreeWayDiffOutcome;

if (baseVersion === MissingVersion) {
if (
currentVersion.type === DataSourceType.index_patterns &&
targetVersion.type === DataSourceType.index_patterns
) {
diffOutcome = determineOrderAgnosticDiffOutcome(
MissingVersion,
currentVersion.index_patterns,
targetVersion.index_patterns
);
} else {
diffOutcome = determineDiffOutcome(baseVersion, currentVersion, targetVersion);
}
} else {
if (
baseVersion.type === DataSourceType.index_patterns &&
currentVersion.type === DataSourceType.index_patterns &&
targetVersion.type === DataSourceType.index_patterns
) {
diffOutcome = determineOrderAgnosticDiffOutcome(
baseVersion.index_patterns,
currentVersion.index_patterns,
targetVersion.index_patterns
);
} else {
diffOutcome = determineDiffOutcome(baseVersion, currentVersion, targetVersion);
}
}
const diffOutcome = determineDiffOutcomeForDataSource(baseVersion, currentVersion, targetVersion);

const valueCanUpdate = determineIfValueCanUpdate(diffOutcome);

Expand Down Expand Up @@ -134,18 +104,31 @@ const mergeVersions = ({

case ThreeWayDiffOutcome.CustomizedValueCanUpdate: {
if (
dedupedBaseVersion &&
dedupedBaseVersion.type === DataSourceType.index_patterns &&
dedupedCurrentVersion.type === DataSourceType.index_patterns &&
dedupedTargetVersion.type === DataSourceType.index_patterns
) {
if (dedupedBaseVersion && dedupedBaseVersion.type === DataSourceType.index_patterns) {
// If all versions are index pattern types, merge all arrays
return {
conflict: ThreeWayDiffConflict.SOLVABLE,
mergeOutcome: ThreeWayMergeOutcome.Merged,
mergedVersion: {
type: DataSourceType.index_patterns,
index_patterns: mergeDedupedArrays(
dedupedBaseVersion.index_patterns,
dedupedCurrentVersion.index_patterns,
dedupedTargetVersion.index_patterns
),
},
};
}
// If just the current and target versions are index pattern types, return the union of the arrays as the merged version
return {
conflict: ThreeWayDiffConflict.SOLVABLE,
mergeOutcome: ThreeWayMergeOutcome.Merged,
mergedVersion: {
type: DataSourceType.index_patterns,
index_patterns: mergeDedupedArrays(
dedupedBaseVersion.index_patterns,
index_patterns: union(
dedupedCurrentVersion.index_patterns,
dedupedTargetVersion.index_patterns
),
Expand Down Expand Up @@ -173,13 +156,3 @@ const mergeVersions = ({
return assertUnreachable(diffOutcome);
}
};

const getDedupedDataSourceVersion = (version: RuleDataSource): RuleDataSource => {
if (version.type === DataSourceType.index_patterns) {
return {
...version,
index_patterns: uniq(version.index_patterns),
};
}
return version;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
* 2.0.
*/

import { difference, union } from 'lodash';
import { difference, union, uniq } from 'lodash';
import type { RuleDataSource } from '../../../../../../../../common/api/detection_engine';
import { DataSourceType } from '../../../../../../../../common/api/detection_engine';

export const mergeDedupedArrays = <T>(
dedupedBaseVersion: T[],
Expand All @@ -23,3 +25,13 @@ export const mergeDedupedArrays = <T>(

return difference(union(dedupedBaseVersion, bothAdded), bothRemoved);
};

export const getDedupedDataSourceVersion = (version: RuleDataSource): RuleDataSource => {
if (version.type === DataSourceType.index_patterns) {
return {
...version,
index_patterns: uniq(version.index_patterns),
};
}
return version;
};

0 comments on commit 687d07f

Please sign in to comment.