Skip to content

Commit

Permalink
Add events tab in pipelinerun and taskrun details page
Browse files Browse the repository at this point in the history
  • Loading branch information
karthik committed Oct 9, 2020
1 parent 3955528 commit b45ff07
Show file tree
Hide file tree
Showing 13 changed files with 839 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { PipelineRunDetails } from './detail-page-tabs/PipelineRunDetails';
import { PipelineRunLogsWithActiveTask } from './detail-page-tabs/PipelineRunLogs';
import { useMenuActionsWithUserAnnotation } from './triggered-by';
import { usePipelinesBreadcrumbsFor } from '../pipelines/hooks';
import PipelineRunEvents from './events/PipelineRunEvents';

const PipelineRunDetailsPage: React.FC<DetailsPageProps> = (props) => {
const { kindObj, match } = props;
Expand All @@ -30,6 +31,7 @@ const PipelineRunDetailsPage: React.FC<DetailsPageProps> = (props) => {
name: 'Logs',
component: PipelineRunLogsWithActiveTask,
},
navFactory.events(PipelineRunEvents),
]}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import { referenceForModel } from '@console/internal/module/k8s';
import { DetailsPage } from '@console/internal/components/factory';
import { PipelineRunModel } from '../../../models';
import * as utils from '../triggered-by';
import * as hookUtils from '../../pipelines/hooks';
import PipelineRunDetailsPage from '../PipelineRunDetailsPage';
import { getPipelineRunKebabActions } from '../../../utils/pipeline-actions';
import PipelineRunEvents from '../events/PipelineRunEvents';

const menuActions = jest.spyOn(utils, 'useMenuActionsWithUserAnnotation');
const breadCrumbs = jest.spyOn(hookUtils, 'usePipelinesBreadcrumbsFor');
type PipelineRunDetailsPageProps = React.ComponentProps<typeof PipelineRunDetailsPage>;

describe('PipelineRunDetailsPage:', () => {
let pipelineRunDetailsPageProps: PipelineRunDetailsPageProps;
beforeEach(() => {
pipelineRunDetailsPageProps = {
kind: PipelineRunModel.kind,
kindObj: PipelineRunModel,
match: {
isExact: true,
path: `/k8s/ns/:ns/${referenceForModel(PipelineRunModel)}/events`,
url: `k8s/ns/rhd-test/${referenceForModel(PipelineRunModel)}/events`,
params: {
ns: 'rhd-test',
},
},
};
menuActions.mockReturnValue([getPipelineRunKebabActions(true)]);
breadCrumbs.mockReturnValue([{ label: 'PipelineRuns' }, { label: 'PipelineRuns Details' }]);
});

it('Should render a DetailsPage component', () => {
const wrapper = shallow(<PipelineRunDetailsPage {...pipelineRunDetailsPageProps} />);
expect(wrapper.find(DetailsPage).exists()).toBe(true);
});

it('Should contain four tabs in the details page', () => {
const wrapper = shallow(<PipelineRunDetailsPage {...pipelineRunDetailsPageProps} />);
const { pages } = wrapper.props();
expect(pages).toHaveLength(4);
});

it('Should contain events page', () => {
const wrapper = shallow(<PipelineRunDetailsPage {...pipelineRunDetailsPageProps} />);
const { pages } = wrapper.props();
const eventPage = pages.find((page) => page.name === 'Events');
expect(eventPage).toBeDefined();
expect(eventPage.component).toBe(PipelineRunEvents);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as React from 'react';
import { match as RMatch } from 'react-router';
import { ResourcesEventStream } from '@console/internal/components/events';
import { PipelineRun } from '../../../utils/pipeline-augment';
import { usePipelineRunFilters } from './event-utils';

type PipelineRunEventsProps = {
obj: PipelineRun;
match: RMatch<{
ns?: string;
}>;
};

const PipelineRunEvents: React.FC<PipelineRunEventsProps> = ({ obj: pipelineRun, ...props }) => {
const { match } = props;
const namespace = match.params.ns;

return (
<ResourcesEventStream
filters={usePipelineRunFilters(namespace, pipelineRun)}
namespace={namespace}
/>
);
};
export default PipelineRunEvents;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import { referenceForModel } from '@console/internal/module/k8s';
import { ResourcesEventStream } from '@console/internal/components/events';
import { PipelineRunModel } from '../../../../models';
import { DataState, PipelineExampleNames, pipelineTestData } from '../../../../test/pipeline-data';
import PipelineRunEvents from '../PipelineRunEvents';
import * as utils from '../event-utils';

const pipeline = pipelineTestData[PipelineExampleNames.WORKSPACE_PIPELINE];
const pipelineRun = pipeline.pipelineRuns[DataState.SUCCESS];
const { taskRuns, pods } = pipeline;

const sypUsePipelineRunRelatedResources = jest.spyOn(utils, 'usePipelineRunRelatedResources');
type PipelineRunEventsProps = React.ComponentProps<typeof PipelineRunEvents>;

describe('PipelineRunEvents:', () => {
let pipelineRunEventsProps: PipelineRunEventsProps;
beforeEach(() => {
pipelineRunEventsProps = {
obj: pipelineRun,
match: {
isExact: true,
path: `/k8s/ns/:ns/${referenceForModel(PipelineRunModel)}/events`,
url: `k8s/ns/rhd-test/${referenceForModel(PipelineRunModel)}/events`,
params: {
ns: 'rhd-test',
},
},
};
sypUsePipelineRunRelatedResources.mockReturnValue({
taskruns: { data: taskRuns, loaded: true },
pods: { data: pods, loaded: true },
});
});

it('Should render a ResourcesEventStream', () => {
const pipelineRunEventsWrapper = shallow(<PipelineRunEvents {...pipelineRunEventsProps} />);
expect(pipelineRunEventsWrapper.find(ResourcesEventStream).exists()).toBe(true);
});

it('Should pass three filters in the props to the ResourcesEventStream', () => {
const pipelineRunEventsWrapper = shallow(<PipelineRunEvents {...pipelineRunEventsProps} />);
expect(pipelineRunEventsWrapper.props().filters).toHaveLength(3);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { useK8sWatchResources } from '@console/internal/components/utils/k8s-watch-hook';
import { testHook } from '@console/shared/src/test-utils/hooks-utils';
import { EventInvolvedObject } from '@console/internal/module/k8s';
import { DataState, PipelineExampleNames, pipelineTestData } from '../../../../test/pipeline-data';
import { PipelineRun } from '../../../../utils/pipeline-augment';
import * as eventUtils from '../event-utils';

jest.mock('@console/internal/components/utils/k8s-watch-hook', () => ({
useK8sWatchResources: jest.fn(),
}));

const pipeline = pipelineTestData[PipelineExampleNames.WORKSPACE_PIPELINE];
const pipelineRun: PipelineRun = pipeline.pipelineRuns[DataState.SUCCESS];
const {
metadata: { namespace },
} = pipelineRun;
const { taskRuns, pods } = pipeline;

describe('usePipelineRunFilters:', () => {
beforeEach(() => {
(useK8sWatchResources as jest.Mock).mockReturnValue({
taskruns: { data: taskRuns, loaded: true },
pods: { data: pods, loaded: true },
});
});
it('should return the pipeline run filters', () => {
(useK8sWatchResources as jest.Mock).mockReturnValue({
taskruns: { data: [], loaded: true },
pods: { data: [], loaded: true },
});
testHook(() => {
const filters = eventUtils.usePipelineRunFilters(namespace, pipelineRun);
expect(filters).toHaveLength(3);
});
});

it('should return true if the involved objects matches with assoicated pipelinerun resources', () => {
const PipelineRunInvolvedObj: EventInvolvedObject = {
uid: pipelineRun.metadata.uid,
kind: pipelineRun.kind,
};
const taskRunInvolvedObj: EventInvolvedObject = {
uid: taskRuns[0].metadata.uid,
kind: taskRuns[0].kind,
};
const podInvolvedObj: EventInvolvedObject = {
uid: pods[0].metadata.uid,
kind: pods[0].kind,
};
testHook(() => {
const filters = eventUtils.usePipelineRunFilters(namespace, pipelineRun);
expect(filters.some((filter) => filter(PipelineRunInvolvedObj))).toBeTruthy();
expect(filters.some((filter) => filter(taskRunInvolvedObj))).toBeTruthy();
expect(filters.some((filter) => filter(podInvolvedObj))).toBeTruthy();
});
});

it('should return false if the involved objects matches with assoicated pipelinerun resources', () => {
const unrelatedPlrInvolvedObj: EventInvolvedObject = {
uid: 'cbe7e8db-c641-11e8-8889-0242ac110004',
kind: pipelineRun.kind,
};

testHook(() => {
const filters = eventUtils.usePipelineRunFilters(namespace, pipelineRun);
expect(filters.some((filter) => filter(unrelatedPlrInvolvedObj))).toBeFalsy();
});
});
});

describe('useTaskRunFilters:', () => {
beforeEach(() => {
(useK8sWatchResources as jest.Mock).mockReturnValue({
taskruns: { data: taskRuns, loaded: true },
pods: { data: pods, loaded: true },
});
});
it('should return the task run and associated pod filters', () => {
testHook(() => {
const filters = eventUtils.useTaskRunFilters(namespace, taskRuns[0]);
expect(filters).toHaveLength(2);
});
});

it('should return true if the taskrun matches with event involved object', () => {
const involvedObj: EventInvolvedObject = {
uid: taskRuns[0].metadata.uid,
kind: taskRuns[0].kind,
};

testHook(() => {
const filters = eventUtils.useTaskRunFilters(namespace, taskRuns[0]);
expect(filters.some((filter) => filter(involvedObj))).toBeTruthy();
});
});

it('should return true if the pod matches with event involved object', () => {
const involvedObj: EventInvolvedObject = {
uid: pods[0].metadata.uid,
kind: pods[0].kind,
};

testHook(() => {
const filters = eventUtils.useTaskRunFilters(namespace, taskRuns[0]);
expect(filters.some((filter) => filter(involvedObj))).toBeTruthy();
});
});

it('should return false if involved object uid is not matched', () => {
const unrelatedInvolvedObj: EventInvolvedObject = {
uid: 'cbe7e8db-c641-11e8-8889-0242ac110004',
kind: pods[0].kind,
};

testHook(() => {
const filters = eventUtils.useTaskRunFilters(namespace, taskRuns[0]);
expect(filters.some((filter) => filter(unrelatedInvolvedObj))).toBeFalsy();
});
});

it('should return false if unsupported kind is supplied in event involved object', () => {
const involvedObj: EventInvolvedObject = {
uid: pods[0].metadata.uid,
kind: 'Depolyment',
};

testHook(() => {
const filters = eventUtils.useTaskRunFilters(namespace, taskRuns[0]);
expect(filters.some((filter) => filter(involvedObj))).toBeFalsy();
});
});

it('should return false if watched resources are empty', () => {
(useK8sWatchResources as jest.Mock).mockReturnValue({
taskruns: { data: [], loaded: true },
pods: { data: [], loaded: true },
});
const involvedObj: EventInvolvedObject = {
uid: pods[0].metadata.uid,
kind: pods[0].kind,
};

testHook(() => {
const filters = eventUtils.useTaskRunFilters(namespace, taskRuns[0]);
expect(filters.some((filter) => filter(involvedObj))).toBeFalsy();
});
});
});

0 comments on commit b45ff07

Please sign in to comment.