diff --git a/x-pack/plugins/endpoint/common/generate_data.test.ts b/x-pack/plugins/endpoint/common/generate_data.test.ts index e1a24018493013..f99fa5c871d89f 100644 --- a/x-pack/plugins/endpoint/common/generate_data.test.ts +++ b/x-pack/plugins/endpoint/common/generate_data.test.ts @@ -101,20 +101,38 @@ describe('data generator', () => { }); it('with n-1 process events', () => { - for (let i = 1; i < events.length - 1; i++) { - expect(events[i].process.parent?.entity_id).toEqual(events[i - 1].process.entity_id); - expect(events[i].event.kind).toEqual('event'); - expect(events[i].event.category).toEqual('process'); + for (let i = events.length - 2; i > 0; ) { + const parentEntityIdOfChild = events[i].process.parent?.entity_id; + for ( + ; + --i >= -1 && (events[i].event.kind !== 'event' || events[i].event.category !== 'process'); + + ) { + // related event - skip it + } + expect(i).toBeGreaterThanOrEqual(0); + expect(parentEntityIdOfChild).toEqual(events[i].process.entity_id); } }); it('with a corresponding alert at the end', () => { + let previousProcessEventIndex = events.length - 2; + for ( + ; + previousProcessEventIndex >= -1 && + (events[previousProcessEventIndex].event.kind !== 'event' || + events[previousProcessEventIndex].event.category !== 'process'); + previousProcessEventIndex-- + ) { + // related event - skip it + } + expect(previousProcessEventIndex).toBeGreaterThanOrEqual(0); // The alert should be last and have the same entity_id as the previous process event expect(events[events.length - 1].process.entity_id).toEqual( - events[events.length - 2].process.entity_id + events[previousProcessEventIndex].process.entity_id ); expect(events[events.length - 1].process.parent?.entity_id).toEqual( - events[events.length - 2].process.parent?.entity_id + events[previousProcessEventIndex].process.parent?.entity_id ); expect(events[events.length - 1].event.kind).toEqual('alert'); expect(events[events.length - 1].event.category).toEqual('malware'); diff --git a/x-pack/plugins/endpoint/common/generate_data.ts b/x-pack/plugins/endpoint/common/generate_data.ts index 840574063d3f37..58393b88e37a35 100644 --- a/x-pack/plugins/endpoint/common/generate_data.ts +++ b/x-pack/plugins/endpoint/common/generate_data.ts @@ -339,13 +339,17 @@ export class EndpointDocGenerator { percentNodesWithRelated?: number, percentChildrenTerminated?: number ) { - const ancestry = this.createAlertEventAncestry(alertAncestors); + const ancestry = this.createAlertEventAncestry( + alertAncestors, + relatedEventsPerNode, + percentNodesWithRelated + ); for (let i = 0; i < ancestry.length; i++) { yield ancestry[i]; } - // ancestry will always have at least 2 elements, and the second to last element will be the process associated with the alert + // ancestry will always have at least 2 elements, and the last element will be the alert yield* this.descendantsTreeGenerator( - ancestry[ancestry.length - 2], + ancestry[ancestry.length - 1], childGenerations, maxChildrenPerNode, relatedEventsPerNode, @@ -358,18 +362,44 @@ export class EndpointDocGenerator { * Creates an alert event and associated process ancestry. The alert event will always be the last event in the return array. * @param alertAncestors - number of ancestor generations to create */ - public createAlertEventAncestry(alertAncestors = 3): Event[] { + public createAlertEventAncestry( + alertAncestors = 3, + relatedEventsPerNode = 5, + pctWithRelated = 30 + ): Event[] { const events = []; const startDate = new Date().getTime(); const root = this.generateEvent({ timestamp: startDate + 1000 }); events.push(root); let ancestor = root; + // generate related alerts for root + const processDuration: number = 6 * 3600; + if (this.randomN(100) < pctWithRelated) { + for (const relatedEvent of this.relatedEventsGenerator( + ancestor, + relatedEventsPerNode, + processDuration + )) { + events.push(relatedEvent); + } + } for (let i = 0; i < alertAncestors; i++) { ancestor = this.generateEvent({ timestamp: startDate + 1000 * (i + 1), parentEntityID: ancestor.process.entity_id, }); events.push(ancestor); + + // generate related alerts for ancestor + if (this.randomN(100) < pctWithRelated) { + for (const relatedEvent of this.relatedEventsGenerator( + ancestor, + relatedEventsPerNode, + processDuration + )) { + events.push(relatedEvent); + } + } } events.push( this.generateAlert(