Skip to content

Commit 27d1627

Browse files
dvaldiviabexsoft
andauthored
Show Warnings when running speed test or diagnostics (#1487)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
1 parent 780cf72 commit 27d1627

File tree

11 files changed

+408
-414
lines changed

11 files changed

+408
-414
lines changed

portal-ui/src/common/__tests__/utils.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ import {
2222
} from "../utils";
2323

2424
test("A variety of formatting results", () => {
25-
expect(niceBytes("1024")).toBe("1.0 KB");
26-
expect(niceBytes("1048576")).toBe("1.0 MB");
27-
expect(niceBytes("1073741824")).toBe("1.0 GB");
25+
expect(niceBytes("1024")).toBe("1.0 KiB");
26+
expect(niceBytes("1048576")).toBe("1.0 MiB");
27+
expect(niceBytes("1073741824")).toBe("1.0 GiB");
2828
});
2929

3030
test("From value and unit to a number of bytes", () => {
31-
expect(getBytes("1", "KB")).toBe("1024");
32-
expect(getBytes("1", "MB")).toBe("1048576");
33-
expect(getBytes("1", "GB")).toBe("1073741824");
31+
expect(getBytes("1", "KiB")).toBe("1024");
32+
expect(getBytes("1", "MiB")).toBe("1048576");
33+
expect(getBytes("1", "GiB")).toBe("1073741824");
3434
});
3535

3636
test("From value and unit to a number of bytes for kubernetes", () => {

portal-ui/src/common/utils.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,17 @@ import { IPool } from "../screens/Console/Tenants/ListTenants/types";
2626
const minStReq = 1073741824; // Minimal Space required for MinIO
2727
const minMemReq = 2147483648; // Minimal Memory required for MinIO in bytes
2828

29-
export const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
29+
export const units = [
30+
"B",
31+
"KiB",
32+
"MiB",
33+
"GiB",
34+
"TiB",
35+
"PiB",
36+
"EiB",
37+
"ZiB",
38+
"YiB",
39+
];
3040
export const k8sUnits = ["Ki", "Mi", "Gi", "Ti", "Pi", "Ei"];
3141
export const k8sCalcUnits = ["B", ...k8sUnits];
3242
export const timeUnits = ["ms", "s", "m", "h", "d", "w", "M", "Q", "y"];

portal-ui/src/screens/Console/Common/ProgressBarWrapper/ProgressBarWrapper.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface IProgressBarWrapper {
2727
ready: boolean;
2828
indeterminate?: boolean;
2929
withLabel?: boolean;
30+
size?: string;
3031
}
3132

3233
const BorderLinearProgress = styled(LinearProgress)(() => ({
@@ -39,6 +40,13 @@ const BorderLinearProgress = styled(LinearProgress)(() => ({
3940
borderRadius: 5,
4041
},
4142
}));
43+
const SmallBorderLinearProgress = styled(BorderLinearProgress)(() => ({
44+
height: 6,
45+
borderRadius: 3,
46+
[`& .${linearProgressClasses.bar}`]: {
47+
borderRadius: 3,
48+
},
49+
}));
4250

4351
function LinearProgressWithLabel(props: LinearProgressProps) {
4452
return (
@@ -58,6 +66,7 @@ const ProgressBarWrapper = ({
5866
ready,
5967
indeterminate,
6068
withLabel,
69+
size = "regular",
6170
}: IProgressBarWrapper) => {
6271
const propsComponent: LinearProgressProps = {
6372
variant: indeterminate && !ready ? "indeterminate" : "determinate",
@@ -67,6 +76,9 @@ const ProgressBarWrapper = ({
6776
if (withLabel) {
6877
return <LinearProgressWithLabel {...propsComponent} />;
6978
}
79+
if (size === "small") {
80+
return <SmallBorderLinearProgress {...propsComponent} />;
81+
}
7082

7183
return <BorderLinearProgress {...propsComponent} />;
7284
};

portal-ui/src/screens/Console/HealthInfo/HealthInfo.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ import { setServerDiagStat, setSnackBarMessage } from "../../../actions";
4747
import CircularProgress from "@mui/material/CircularProgress";
4848
import TestWrapper from "../Common/TestWrapper/TestWrapper";
4949
import PageLayout from "../Common/Layout/PageLayout";
50+
import HelpBox from "../../../common/HelpBox";
51+
import WarnIcon from "../../../icons/WarnIcon";
5052

5153
const styles = (theme: Theme) =>
5254
createStyles({
@@ -303,6 +305,18 @@ const HealthInfo = ({
303305
</Grid>
304306
</TestWrapper>
305307
</Grid>
308+
{!diagStarted && (
309+
<Fragment>
310+
<br />
311+
<HelpBox
312+
title={
313+
"During the health diagnostics run all production traffic will be suspended."
314+
}
315+
iconComponent={<WarnIcon />}
316+
help={<Fragment />}
317+
/>
318+
</Fragment>
319+
)}
306320
</PageLayout>
307321
</Fragment>
308322
);

portal-ui/src/screens/Console/Speedtest/STResults.tsx

Lines changed: 40 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -35,39 +35,10 @@ import BoxIconButton from "../Common/BoxIconButton/BoxIconButton";
3535
import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
3636
import { Area, AreaChart, CartesianGrid, ResponsiveContainer } from "recharts";
3737
import { cleanMetrics } from "./utils";
38-
39-
interface ISTResults {
40-
classes: any;
41-
results: SpeedTestResponse[];
42-
start: boolean;
43-
autotune: boolean;
44-
}
38+
import SpeedTestUnit from "./SpeedTestUnit";
4539

4640
const styles = (theme: Theme) =>
4741
createStyles({
48-
objectGeneralTitle: {
49-
fontWeight: "bold",
50-
color: "#000",
51-
display: "flex",
52-
alignItems: "center",
53-
"& svg": {
54-
width: 14,
55-
},
56-
},
57-
generalUnit: {
58-
color: "#000",
59-
marginTop: 6,
60-
fontSize: 12,
61-
fontWeight: "bold",
62-
},
63-
testUnitRes: {
64-
fontSize: 120,
65-
color: "#081C42",
66-
fontWeight: "bold",
67-
},
68-
metricValContainer: {
69-
lineHeight: 1,
70-
},
7142
actionButtons: {
7243
textAlign: "right",
7344
},
@@ -153,17 +124,27 @@ const styles = (theme: Theme) =>
153124
},
154125
download: {
155126
"& .min-icon": {
127+
width: 35,
128+
height: 35,
156129
color: "rgb(113,200,150)",
157130
},
158131
},
159132
upload: {
160133
"& .min-icon": {
134+
width: 35,
135+
height: 35,
161136
color: "rgb(66,127,172)",
162137
},
163138
},
164139
});
165140

166-
const STResults = ({ classes, results, start, autotune }: ISTResults) => {
141+
interface ISTResults {
142+
classes: any;
143+
results: SpeedTestResponse[];
144+
start: boolean;
145+
}
146+
147+
const STResults = ({ classes, results, start }: ISTResults) => {
167148
const [jsonView, setJsonView] = useState<boolean>(false);
168149

169150
const finalRes = results[results.length - 1] || [];
@@ -177,38 +158,6 @@ const STResults = ({ classes, results, start, autotune }: ISTResults) => {
177158
const putThroughput = get(finalRes, "PUTStats.throughputPerSec", 0);
178159
const putObjects = get(finalRes, "PUTStats.objectsPerSec", 0);
179160

180-
const ObjectGeneral = ({
181-
title,
182-
throughput,
183-
objects,
184-
}: {
185-
title: any;
186-
throughput: string;
187-
objects: number;
188-
}) => {
189-
const avg = calculateBytes(throughput);
190-
191-
let total = "--";
192-
let unit = "";
193-
194-
if (avg.total !== 0) {
195-
total = avg.total.toString();
196-
unit = `${avg.unit}/S`;
197-
}
198-
199-
return (
200-
<Grid container>
201-
<Grid item xs={12} className={classes.objectGeneralTitle}>
202-
{title}
203-
</Grid>
204-
<Grid item xs={12} md={6} className={classes.metricValContainer}>
205-
<span className={classes.testUnitRes}>{total}</span>
206-
<span className={classes.generalUnit}>{unit}</span>
207-
</Grid>
208-
</Grid>
209-
);
210-
};
211-
212161
let statJoin: IndvServerMetric[] = [];
213162

214163
getServers.forEach((item) => {
@@ -280,31 +229,35 @@ const STResults = ({ classes, results, start, autotune }: ISTResults) => {
280229
return (
281230
<Fragment>
282231
<Grid container className={classes.objectGeneral}>
283-
<Grid item xs={12} md={6} lg={4}>
284-
<ObjectGeneral
285-
title={
286-
<div className={classes.download}>
287-
<DownloadStatIcon />
288-
&nbsp; GET
289-
</div>
290-
}
291-
throughput={getThroughput}
292-
objects={getObjects}
293-
/>
294-
</Grid>
295-
<Grid item xs={12} md={6} lg={4}>
296-
<ObjectGeneral
297-
title={
298-
<div className={classes.upload}>
299-
<UploadStatIcon />
300-
&nbsp; PUT
301-
</div>
302-
}
303-
throughput={putThroughput}
304-
objects={putObjects}
305-
/>
232+
<Grid item xs={12} md={6} lg={6}>
233+
<Grid container className={classes.objectGeneral}>
234+
<Grid item xs={12} md={6} lg={6}>
235+
<SpeedTestUnit
236+
icon={
237+
<div className={classes.download}>
238+
<DownloadStatIcon />
239+
</div>
240+
}
241+
title={"GET"}
242+
throughput={getThroughput}
243+
objects={getObjects}
244+
/>
245+
</Grid>
246+
<Grid item xs={12} md={6} lg={6}>
247+
<SpeedTestUnit
248+
icon={
249+
<div className={classes.upload}>
250+
<UploadStatIcon />
251+
</div>
252+
}
253+
title={"PUT"}
254+
throughput={putThroughput}
255+
objects={putObjects}
256+
/>
257+
</Grid>
258+
</Grid>
306259
</Grid>
307-
<Grid item xs={12} md={12} lg={4}>
260+
<Grid item xs={12} md={6} lg={6}>
308261
<ResponsiveContainer width="99%">
309262
<AreaChart data={clnMetrics}>
310263
<defs>
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2022 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import { calculateBytes } from "../../../common/utils";
18+
import React from "react";
19+
import withStyles from "@mui/styles/withStyles";
20+
import { Theme } from "@mui/material/styles";
21+
import createStyles from "@mui/styles/createStyles";
22+
import clsx from "clsx";
23+
24+
const styles = (theme: Theme) =>
25+
createStyles({
26+
objectGeneralTitle: {
27+
lineHeight: 1,
28+
fontSize: 50,
29+
color: "#696969",
30+
},
31+
generalUnit: {
32+
color: "#000",
33+
fontSize: 12,
34+
fontWeight: "bold",
35+
},
36+
testUnitRes: {
37+
fontSize: 60,
38+
color: "#081C42",
39+
fontWeight: "bold",
40+
textAlign: "right",
41+
},
42+
metricValContainer: {
43+
lineHeight: 1,
44+
verticalAlign: "bottom",
45+
},
46+
objectsUnitRes: {
47+
fontSize: 22,
48+
marginTop: 6,
49+
color: "#696969",
50+
fontWeight: "bold",
51+
textAlign: "right",
52+
},
53+
objectsUnit: {
54+
color: "#696969",
55+
fontSize: 16,
56+
fontWeight: "bold",
57+
},
58+
iconTd: {
59+
verticalAlign: "bottom",
60+
},
61+
});
62+
63+
const SpeedTestUnit = ({
64+
classes,
65+
title,
66+
icon,
67+
throughput,
68+
objects,
69+
}: {
70+
classes: any;
71+
title: any;
72+
icon: any;
73+
throughput: string;
74+
objects: number;
75+
}) => {
76+
const avg = calculateBytes(throughput);
77+
78+
let total = "0";
79+
let unit = "";
80+
81+
if (avg.total !== 0) {
82+
total = avg.total.toString();
83+
unit = `${avg.unit}/s`;
84+
}
85+
86+
return (
87+
<table>
88+
<tr>
89+
<td className={classes.objectGeneralTitle}>{title}</td>
90+
<td className={classes.iconTd}>{icon}</td>
91+
</tr>
92+
<tr>
93+
<td className={clsx(classes.metricValContainer, classes.testUnitRes)}>
94+
{total}
95+
</td>
96+
<td className={clsx(classes.metricValContainer, classes.generalUnit)}>
97+
{unit}
98+
</td>
99+
</tr>
100+
<tr>
101+
<td
102+
className={clsx(classes.metricValContainer, classes.objectsUnitRes)}
103+
>
104+
{objects}
105+
</td>
106+
<td className={clsx(classes.metricValContainer, classes.objectsUnit)}>
107+
{objects !== 0 && "Objs/S"}
108+
</td>
109+
</tr>
110+
</table>
111+
);
112+
};
113+
export default withStyles(styles)(SpeedTestUnit);

0 commit comments

Comments
 (0)