Skip to content

Commit

Permalink
Application Status (#1866)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andres Martinez Gotor committed Jul 17, 2020
1 parent 6d7daa3 commit 814dad7
Show file tree
Hide file tree
Showing 11 changed files with 699 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { hapi } from "../../shared/hapi/release";
import { IK8sList, IKubeItem, IResource } from "../../shared/types";
import "./ApplicationStatus.css";

interface IApplicationStatusProps {
export interface IApplicationStatusProps {
deployments: Array<IKubeItem<IResource | IK8sList<IResource, {}>>>;
statefulsets: Array<IKubeItem<IResource | IK8sList<IResource, {}>>>;
daemonsets: Array<IKubeItem<IResource | IK8sList<IResource, {}>>>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.application-status-pie-chart {
display: flex;
justify-content: center;
text-align: center;
margin-bottom: -50px;
&-title {
font-weight: 600;
}
&-label {
position: relative;
bottom: 3.6rem;
}
&-number {
margin: 0;
font-size: 1.5em;
}
&-text {
margin: -5px 0 0 0;
}
h5 {
margin-top: 0.6rem;
}
}

.application-status-table {
text-align: left;
border-spacing: 1em 0em;
th {
text-transform: uppercase;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,350 @@
import { mount, shallow } from "enzyme";
import { has } from "lodash";
import * as React from "react";

import { IK8sList, IKubeItem, IResource } from "shared/types";
import ApplicationStatus from "./ApplicationStatus.v2";

const defaultProps = {
watchWorkloads: jest.fn(),
closeWatches: jest.fn(),
deployments: [],
statefulsets: [],
daemonsets: [],
};

describe("componentDidMount", () => {
it("calls watchWorkloads", () => {
const mock = jest.fn();
mount(<ApplicationStatus {...defaultProps} watchWorkloads={mock} />);
expect(mock).toHaveBeenCalled();
});
});

describe("componentWillUnmount", () => {
it("calls closeWatches", () => {
const mock = jest.fn();
const wrapper = mount(<ApplicationStatus {...defaultProps} closeWatches={mock} />);
wrapper.unmount();
expect(mock).toHaveBeenCalled();
});
});

it("renders a loading status", () => {
const deployments = [
{
isFetching: true,
},
];
const wrapper = shallow(<ApplicationStatus {...defaultProps} deployments={deployments} />);
expect(wrapper.text()).toContain("Loading");
expect(wrapper).toMatchSnapshot();
});

it("renders a deleting status", () => {
const deployments = [
{
isFetching: false,
},
];
const wrapper = shallow(
<ApplicationStatus {...defaultProps} deployments={deployments} info={{ deleted: {} }} />,
);
expect(wrapper.text()).toContain("Deleted");
expect(wrapper).toMatchSnapshot();
});

it("renders a failed status", () => {
const deployments = [
{
isFetching: false,
},
];
const wrapper = shallow(
<ApplicationStatus
{...defaultProps}
deployments={deployments}
info={{ status: { code: 4 } }}
/>,
);
expect(wrapper.text()).toContain("Failed");
expect(wrapper).toMatchSnapshot();
});

describe("isFetching", () => {
const tests: Array<{
title: string;
deployments: Array<IKubeItem<IResource | IK8sList<IResource, {}>>>;
statefulsets: Array<IKubeItem<IResource | IK8sList<IResource, {}>>>;
daemonsets: Array<IKubeItem<IResource | IK8sList<IResource, {}>>>;
deployed: boolean;
totalPods: number;
readyPods: number;
}> = [
{
title: "shows a warning if no workloads are present",
deployments: [],
statefulsets: [],
daemonsets: [],
deployed: false,
totalPods: 0,
readyPods: 0,
},
{
title: "shows a deploying status if there is a non deployed deployment",
deployments: [
{
isFetching: false,
item: {
metadata: { name: "foo" },
spec: {
replicas: 1,
},
status: {
availableReplicas: 0,
},
} as IResource,
},
],
statefulsets: [],
daemonsets: [],
deployed: false,
totalPods: 1,
readyPods: 0,
},
{
title: "shows a deploying status if there is a non deployed statefulset",
statefulsets: [
{
isFetching: false,
item: {
metadata: { name: "foo" },
spec: {
replicas: 1,
},
status: {
readyReplicas: 0,
},
} as IResource,
},
],
deployments: [],
daemonsets: [],
deployed: false,
totalPods: 1,
readyPods: 0,
},
{
title: "shows a deploying status if there is a non deployed daemonset",
daemonsets: [
{
isFetching: false,
item: {
metadata: { name: "foo" },
status: {
currentNumberScheduled: 1,
numberReady: 0,
},
} as IResource,
},
],
deployments: [],
statefulsets: [],
deployed: false,
totalPods: 1,
readyPods: 0,
},
{
title: "shows a deployed status if it has a daemonset, deployment and statefulset deployed",
daemonsets: [
{
isFetching: false,
item: {
metadata: { name: "foo" },
status: {
currentNumberScheduled: 1,
numberReady: 1,
},
} as IResource,
},
],
deployments: [
{
isFetching: false,
item: {
metadata: { name: "foo" },
spec: {
replicas: 1,
},
status: {
availableReplicas: 1,
},
} as IResource,
},
],
statefulsets: [
{
isFetching: false,
item: {
metadata: { name: "foo" },
spec: {
replicas: 1,
},
status: {
readyReplicas: 1,
},
} as IResource,
},
],
deployed: true,
totalPods: 3,
readyPods: 3,
},
{
title:
"shows a deploying status if it has a daemonset, deployment (deployed) and statefulset (not deployed)",
daemonsets: [
{
isFetching: false,
item: {
metadata: { name: "foo-ds" },
status: {
currentNumberScheduled: 1,
numberReady: 1,
},
} as IResource,
},
],
deployments: [
{
isFetching: false,
item: {
metadata: { name: "foo-dp" },
spec: {
replicas: 1,
},
status: {
availableReplicas: 1,
},
} as IResource,
},
],
statefulsets: [
{
isFetching: false,
item: {
metadata: { name: "foo-ss" },
spec: {
replicas: 1,
},
status: {
readyReplicas: 0,
},
} as IResource,
},
],
deployed: true,
totalPods: 3,
readyPods: 2,
},
{
title:
"shows a deploying status if it has a daemonset, deployment (deployed) and statefulset (not deployed) with lists",
daemonsets: [
{
isFetching: false,
item: {
items: [
{
metadata: { name: "foo-ds" },
status: {
currentNumberScheduled: 1,
numberReady: 1,
},
} as IResource,
],
} as IK8sList<IResource, {}>,
},
],
deployments: [
{
isFetching: false,
item: {
items: [
{
metadata: { name: "foo-dp" },
spec: {
replicas: 1,
},
status: {
availableReplicas: 1,
},
} as IResource,
],
} as IK8sList<IResource, {}>,
},
],
statefulsets: [
{
isFetching: false,
item: {
items: [
{
metadata: { name: "foo-ss" },
spec: {
replicas: 1,
},
status: {
readyReplicas: 0,
},
} as IResource,
],
} as IK8sList<IResource, {}>,
},
],
deployed: true,
totalPods: 3,
readyPods: 2,
},
];
tests.forEach(t => {
it(t.title, () => {
const wrapper = mount(<ApplicationStatus {...defaultProps} />);
wrapper.setProps({
deployments: t.deployments,
statefulsets: t.statefulsets,
daemonsets: t.daemonsets,
});
wrapper.update();
const getItem = (i?: IResource | IK8sList<IResource, {}>): IResource => {
return has(i, "items") ? (i as IK8sList<IResource, {}>).items[0] : (i as IResource);
};
if (!t.deployments.length && !t.statefulsets.length && !t.daemonsets.length) {
expect(wrapper.text()).toContain("No Workload Found");
return;
}
expect(wrapper.text()).toContain(t.deployed ? "Ready" : "Not Ready");
// expect(wrapper.state()).toMatchObject({ totalPods: t.totalPods, readyPods: t.readyPods });
// Check tooltip text
const tooltipText = wrapper.html();
t.deployments.forEach(d => {
const item = getItem(d.item);
expect(tooltipText).toContain(
`<td>${item.metadata.name}</td><td>${item.status.availableReplicas}/${item.spec.replicas}</td>`,
);
});
t.statefulsets.forEach(d => {
const item = getItem(d.item);
expect(tooltipText).toContain(
`<td>${item.metadata.name}</td><td>${item.status.readyReplicas}/${item.spec.replicas}</td>`,
);
});
t.daemonsets.forEach(d => {
const item = getItem(d.item);
expect(tooltipText).toContain(
`<td>${item.metadata.name}</td><td>${item.status.numberReady}/${item.status.currentNumberScheduled}</td>`,
);
});
});
});
});

0 comments on commit 814dad7

Please sign in to comment.