Skip to content

Commit

Permalink
Add reducer, action, tests, and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
peluja1012 committed Jan 8, 2020
1 parent cefb014 commit 3bda8d5
Show file tree
Hide file tree
Showing 14 changed files with 387 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { CameraAction } from './store/camera';
import { DataAction } from './store/data';

export type ResolverAction = CameraAction;
export type ResolverAction = CameraAction | DataAction;
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/

// TODO: type root and children
export function* depthFirstPreorder({ root, children }) {
export function* depthFirstPreorder<T>(root: T, children: (parent: T) => T[]): Iterable<T> {
const nodesToVisit = [root];
while (nodesToVisit.length !== 0) {
const currentNode = nodesToVisit.shift();
nodesToVisit.unshift(...(children(currentNode) || []));
yield currentNode;
if (currentNode !== undefined) {
nodesToVisit.unshift(...(children(currentNode) || []));
yield currentNode;
}
}
}

export function* levelOrder({ root, children }) {
export function* levelOrder<T>(root: T, children: (parent: T) => T[]): Iterable<T> {
let level = [root];
while (level.length !== 0) {
let nextLevel = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { eventType } from './process_event';
import { ProcessEvent } from '../types';

describe('process event', () => {
describe('eventType', () => {
let event: ProcessEvent;
beforeEach(() => {
event = {
data_buffer: {
event_type_full: 'process_event',
},
};
});
it("returns the right value when the subType is 'creation_event'", () => {
event.data_buffer.event_subtype_full = 'creation_event';
expect(eventType(event)).toEqual('processCreated');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { ProcessEvent } from '../types';

export function isGraphableProcess(event: ProcessEvent) {
return eventType(event) === 'processCreated' || eventType(event) === 'processRan';
}

export function eventType(event: ProcessEvent) {
const {
data_buffer: { event_type_full: type, event_subtype_full: subType },
} = event;

if (type === 'process_event') {
if (subType === 'creation_event' || subType === 'fork_event' || subType === 'exec_event') {
return 'processCreated';
} else if (subType === 'already_running') {
return 'processRan';
} else if (subType === 'termination_event') {
return 'processTerminated';
} else {
return 'unknownProcessEvent';
}
} else if (type === 'alert_event') {
return 'processCausedAlert';
}
return 'unknownEvent';
}

export function uniquePidForProcess(event: ProcessEvent) {
return event.data_buffer.node_id;
}

export function uniqueParentPidForProcess(event: ProcessEvent) {
return event.data_buffer.source_id;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

interface ServerReturnedResolverData {
readonly type: 'serverReturnedResolverData';
readonly payload: Record<string, any>;
}

export type DataAction = ServerReturnedResolverData;
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { Store, createStore, AnyAction } from 'redux';
import { DataAction } from './action';
import { dataReducer } from './reducer';
import { DataState, Vector2 } from '../../types';
import {
graphableProcesses,
widthOfProcessSubtrees,
distanceBetweenNodes,
processNodePositionsAndEdgeLineSegments,
} from './selectors';

describe('resolver graph layout', () => {
let store: Store<DataState, AnyAction>;

beforeEach(() => {
store = createStore(dataReducer, undefined);
});
describe('resolver data is received', () => {
/*
* A
* ____|____
* | |
* B C
* ___|___ ___|___
* | | | |
* D E F G
* |
* H
*
*/
const processA = {
data_buffer: {
event_type_full: 'process_event',
event_subtype_full: 'creation_event',
node_id: 0,
},
};
const processB = {
data_buffer: {
event_type_full: 'process_event',
event_subtype_full: 'already_running',
node_id: 1,
source_id: 0,
},
};
const processC = {
data_buffer: {
event_type_full: 'process_event',
event_subtype_full: 'creation_event',
node_id: 2,
source_id: 0,
},
};
const processD = {
data_buffer: {
event_type_full: 'process_event',
event_subtype_full: 'creation_event',
node_id: 3,
source_id: 1,
},
};
const processE = {
data_buffer: {
event_type_full: 'process_event',
event_subtype_full: 'creation_event',
node_id: 4,
source_id: 1,
},
};
const processF = {
data_buffer: {
event_type_full: 'process_event',
event_subtype_full: 'creation_event',
node_id: 5,
source_id: 2,
},
};
const processG = {
data_buffer: {
event_type_full: 'process_event',
event_subtype_full: 'creation_event',
node_id: 6,
source_id: 2,
},
};
const processH = {
data_buffer: {
event_type_full: 'process_event',
event_subtype_full: 'creation_event',
node_id: 7,
source_id: 6,
},
};
const processI = {
data_buffer: {
event_type_full: 'process_event',
event_subtype_full: 'termination_event',
node_id: 8,
source_id: 0,
},
};
beforeEach(() => {
const payload = {
data: {
result: {
search_results: [
processA,
processB,
processC,
processD,
processE,
processF,
processG,
processH,
processI,
],
},
},
};
const action: DataAction = { type: 'serverReturnedResolverData', payload };
store.dispatch(action);
});
it("the graphableProcesses list should only include events with 'processCreated' an 'processRan' eventType", () => {
const actual = graphableProcesses(store.getState());
expect(actual).toEqual([
processA,
processB,
processC,
processD,
processE,
processF,
processG,
processH,
]);
});
it('the width of process subtress is calculated correctly', () => {
const expected = new Map([
[processA, 3 * distanceBetweenNodes],
[processB, 1 * distanceBetweenNodes],
[processC, 1 * distanceBetweenNodes],
[processD, 0 * distanceBetweenNodes],
[processE, 0 * distanceBetweenNodes],
[processF, 0 * distanceBetweenNodes],
[processG, 0 * distanceBetweenNodes],
[processH, 0 * distanceBetweenNodes],
]);
const actual = widthOfProcessSubtrees(store.getState());
expect(actual).toEqual(expected);
});
it('it renders the nodes at the right positions', () => {
const expected = new Map([
[processA, [0, 100]],
[processB, [-100, 0]],
[processC, [100, 0]],
[processD, [-150, -100]],
[processE, [-50, -100]],
[processF, [50, -100]],
[processG, [150, -100]],
[processH, [150, -200]],
]);
const actual = processNodePositionsAndEdgeLineSegments(store.getState()).processNodePositions;
expect(actual).toEqual(expected);
});
it('it renders edges at the right positions', () => {
expect(false).toEqual(true);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export { dataReducer } from './reducer';
export { DataAction } from './action';
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { Reducer } from 'redux';
import { DataState, ResolverAction } from '../../types';
import { sampleData } from './sample';

function initialState(): DataState {
return {
results: sampleData.data.result.search_results,
};
}

export const dataReducer: Reducer<DataState, ResolverAction> = (state = initialState(), action) => {
if (action.type === 'serverReturnedResolverData') {
const {
data: {
result: { search_results },
},
} = action.payload;
return {
...state,
results: search_results,
};
} else {
return state;
}
};
Loading

0 comments on commit 3bda8d5

Please sign in to comment.