Skip to content

Commit

Permalink
Merge pull request elastic#18 from Elastic-AWP-Platform/session-view-…
Browse files Browse the repository at this point in the history
…detail-panel-tests

Session view detail panel tests
  • Loading branch information
Jack authored Dec 1, 2021
2 parents d345568 + 978c931 commit 94bf3ef
Show file tree
Hide file tree
Showing 13 changed files with 693 additions and 140 deletions.

Large diffs are not rendered by default.

127 changes: 127 additions & 0 deletions x-pack/plugins/session_view/common/types/process_tree/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* 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.
*/

export enum EventKind {
event = 'event',
signal = 'signal',
}

export enum EventAction {
fork = 'fork',
exec = 'exec',
exit = 'exit',
output = 'output',
}

export interface EventActionPartition {
fork: ProcessEvent[];
exec: ProcessEvent[];
exit: ProcessEvent[];
output: ProcessEvent[];
}

export interface User {
id: string;
name: string;
}

export interface ProcessFields {
args: string[];
args_count: number;
command_line: string;
entity_id: string;
executable: string;
interactive: boolean;
name: string;
working_directory: string;
pid: number;
pgid: number;
user: User;
end?: string;
exit_code?: number;
}

export interface ProcessSelf extends ProcessFields {
parent: ProcessFields;
session: ProcessFields;
entry: ProcessFields;
last_user_entered?: ProcessFields;
}

export interface ProcessEventHost {
architecture: string;
hostname: string;
id: string;
ip: string;
mac: string;
name: string;
os: {
family: string;
full: string;
kernel: string;
name: string;
platform: string;
type: string;
version: string;
};
}

export interface ProcessEventAlertRule {
category: string;
consumer: string;
description: string;
enabled: boolean;
name: string;
query: string;
risk_score: number;
severity: string;
uuid: string;
}

export interface ProcessEventAlert {
uuid: string;
reason: string;
workflow_status: string;
status: string;
original_time: Date;
original_event: {
action: string;
};
rule: ProcessEventAlertRule;
}

export interface ProcessEvent {
'@timestamp': Date;
event: {
kind: EventKind;
category: string;
action: EventAction;
};
// optional host for now (raw agent output doesn't have server identity)
host?: ProcessEventHost;
process: ProcessSelf;
kibana?: {
alert: ProcessEventAlert;
};
}

export interface Process {
id: string; // the process entity_id
events: ProcessEvent[];
children: Process[];
parent: Process | undefined;
autoExpand: boolean;
searchMatched: string | null; // either false, or set to searchQuery
hasOutput(): boolean;
hasAlerts(): boolean;
getAlerts(): ProcessEvent[];
hasExec(): boolean;
getOutput(): string;
getDetails(): ProcessEvent;
isUserEntered(): boolean;
getMaxAlertLevel(): number | null;
}
1 change: 1 addition & 0 deletions x-pack/plugins/session_view/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ module.exports = {
collectCoverageFrom: [
'<rootDir>/x-pack/plugins/session_view/{common,public,server}/**/*.{ts,tsx}',
],
setupFiles: ['jest-canvas-mock'],
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
*/
import React, { useRef, useLayoutEffect, useCallback } from 'react';
import { ProcessTreeNode } from '../ProcessTreeNode';
import { useProcessTree, ProcessEvent, Process } from '../../hooks/use_process_tree';
import { useProcessTree } from '../../hooks/use_process_tree';
import { ProcessEvent, Process } from '../../../common/types/process_tree';
import { useScroll } from '../../hooks/use_scroll';
import { useStyles } from './styles';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { useStyles } from './styles';
import { ProcessEvent } from '../../hooks/use_process_tree';
import { ProcessEvent } from '../../../common/types/process_tree';
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import { CoreStart } from '../../../../../../src/core/public';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import React, { useMemo, useRef, useLayoutEffect, useState, useEffect, MouseEvent } from 'react';
import { EuiButton, EuiIcon } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { Process } from '../../hooks/use_process_tree';
import { Process } from '../../../common/types/process_tree';
import { useStyles, ButtonType } from './styles';
import { ProcessTreeAlerts } from '../ProcessTreeAlerts';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useQuery } from 'react-query';
import { EuiSearchBarOnChangeArgs } from '@elastic/eui';
import { CoreStart } from 'kibana/public';
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import { ProcessEvent } from '../../hooks/use_process_tree';
import { ProcessEvent } from '../../../common/types/process_tree';
import { PROCESS_EVENTS_ROUTE } from '../../../common/constants';

interface ProcessEventResults {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import { FormattedMessage } from '@kbn/i18n/react';
import { SectionLoading } from '../../shared_imports';
import { ProcessTree } from '../ProcessTree';
import { Process } from '../../hooks/use_process_tree';
import { Process } from '../../../common/types/process_tree';
import { SessionViewDetailPanel } from '../SessionViewDetailPanel';
import { useStyles } from './styles';
import {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* 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 React from 'react';
import {
sessionViewBasicProcessMock,
sessionViewAlertProcessMock,
} from '../../../common/mocks/constants/session_view_process.mock';
import { AppContextTestRender, createAppRootMockRenderer } from '../../test';
import { SessionViewDetailPanel } from './index';

describe('SessionView component', () => {
let render: () => ReturnType<AppContextTestRender['render']>;
let renderResult: ReturnType<typeof render>;
let mockedContext: AppContextTestRender;

beforeEach(() => {
mockedContext = createAppRootMockRenderer();
});

describe('When SessionViewDetailPanel is mounted', () => {
it('should show session detail and server detail when no process is selected', async () => {
renderResult = mockedContext.render(
<SessionViewDetailPanel
isDetailMounted={true}
height={400}
selectedProcess={null}
setIsDetailOpen={() => jest.fn()}
/>
);
// see if loader is present
expect(renderResult.queryByTestId('sessionViewDetailPanelCommandDetail')).toBeNull();
expect(renderResult.queryByTestId('sessionViewDetailPanelSessionDetail')).toBeTruthy();
expect(renderResult.queryByTestId('sessionViewDetailPanelServerDetail')).toBeTruthy();
expect(renderResult.queryByTestId('sessionViewDetailPanelAlertDetail')).toBeNull();
});

it('should show command detail when selectedProcess is present', async () => {
renderResult = mockedContext.render(
<SessionViewDetailPanel
isDetailMounted={true}
height={400}
selectedProcess={sessionViewBasicProcessMock}
setIsDetailOpen={() => jest.fn()}
/>
);
expect(renderResult.queryByTestId('sessionViewDetailPanelCommandDetail')).toBeTruthy();
expect(renderResult.queryByTestId('sessionViewDetailPanelSessionDetail')).toBeTruthy();
expect(renderResult.queryByTestId('sessionViewDetailPanelServerDetail')).toBeTruthy();
expect(renderResult.queryByTestId('sessionViewDetailPanelAlertDetail')).toBeNull();
});

it('should show command and alerts detail if selectedProcess contains a signal event', async () => {
renderResult = mockedContext.render(
<SessionViewDetailPanel
isDetailMounted={true}
height={400}
selectedProcess={sessionViewAlertProcessMock}
setIsDetailOpen={() => jest.fn()}
/>
);
expect(renderResult.queryByTestId('sessionViewDetailPanelCommandDetail')).toBeTruthy();
expect(renderResult.queryByTestId('sessionViewDetailPanelSessionDetail')).toBeTruthy();
expect(renderResult.queryByTestId('sessionViewDetailPanelServerDetail')).toBeTruthy();
expect(renderResult.queryByTestId('sessionViewDetailPanelAlertDetail')).toBeTruthy();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import MonacoEditor from 'react-monaco-editor';
import { partition } from 'lodash';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiSpacer, EuiSplitPanel, EuiTitle, EuiTabs, EuiTab } from '@elastic/eui';
import { EventKind, Process } from '../../hooks/use_process_tree';
import { EventKind, Process } from '../../../common/types/process_tree';
import { useStyles } from './styles';

interface SessionViewDetailPanelDeps {
Expand Down Expand Up @@ -83,7 +83,7 @@ export const SessionViewDetailPanel = ({
const renderSelectedProcessCommandDetail = () => {
if (selectedProcess) {
return (
<div>
<div data-test-subj="sessionViewDetailPanelCommandDetail">
<EuiTitle size="s">
<span>
<FormattedMessage
Expand Down Expand Up @@ -114,7 +114,7 @@ export const SessionViewDetailPanel = ({
const renderSelectedProcessAlertDetail = () => {
if (selectedProcess && selectedProcess.hasAlerts()) {
return (
<div>
<div data-test-subj="sessionViewDetailPanelAlertDetail">
<EuiTitle size="s">
<span>
<FormattedMessage id="xpack.sessionView.alertDetail" defaultMessage="Alert detail" />
Expand Down Expand Up @@ -147,19 +147,26 @@ export const SessionViewDetailPanel = ({
onAnimationEnd={handleAnimationEnd}
>
{renderSelectedProcessCommandDetail()}
<EuiTitle size="s">
<span>
<FormattedMessage id="xpack.sessionView.sessionDetail" defaultMessage="Session detail" />
</span>
</EuiTitle>
{/* Add session detail */}
<div data-test-subj="sessionViewDetailPanelSessionDetail">
<EuiTitle size="s">
<span>
<FormattedMessage
id="xpack.sessionView.sessionDetail"
defaultMessage="Session detail"
/>
</span>
</EuiTitle>
{/* Add session detail */}
</div>
<EuiSpacer size="xxl" />
<EuiTitle size="s">
<span>
<FormattedMessage id="xpack.sessionView.serverDetail" defaultMessage="Server detail" />
</span>
</EuiTitle>
{/* Add server detail */}
<div data-test-subj="sessionViewDetailPanelServerDetail">
<EuiTitle size="s">
<span>
<FormattedMessage id="xpack.sessionView.serverDetail" defaultMessage="Server detail" />
</span>
</EuiTitle>
{/* Add server detail */}
</div>
<EuiSpacer size="xxl" />
{renderSelectedProcessAlertDetail()}
</EuiSplitPanel.Inner>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { CoreStart } from '../../../../../../src/core/public';
import { RECENT_SESSION_ROUTE, BASE_PATH } from '../../../common/constants';

import { SessionView } from '../SessionView';
import { ProcessEvent } from '../../hooks/use_process_tree';
import { ProcessEvent } from '../../../common/types/process_tree';

interface RecentSessionResults {
hits: any[];
Expand Down
Loading

0 comments on commit 94bf3ef

Please sign in to comment.