//
// SPDX-License-Identifier: AGPL-3.0
-import { formatUploadSpeed, formatCost } from "./formatters";
+import { formatFileSize, formatUploadSpeed, formatCost, formatCWLResourceSize } from "./formatters";
+
+describe('formatFileSize', () => {
+ it('should pick the largest unit', () => {
+ const base = 1024;
+ const testCases = [
+ {input: 0, output: '0 B'},
+ {input: 1, output: '1 B'},
+ {input: 1023, output: '1023 B'},
+ {input: base, output: '1.0 KiB'},
+ {input: 1.1 * base, output: '1.1 KiB'},
+ {input: 1.5 * base, output: '1.5 KiB'},
+ {input: base ** 2, output: '1.0 MiB'},
+ {input: 1.5 * (base ** 2), output: '1.5 MiB'},
+ {input: base ** 3, output: '1.0 GiB'},
+ {input: base ** 4, output: '1.0 TiB'},
+ ];
+
+ for (const { input, output } of testCases) {
+ expect(formatFileSize(input)).toBe(output);
+ }
+ });
+
+ it('should handle accidental empty string or undefined input', () => {
+ expect(formatFileSize('')).toBe('-');
+ expect(formatFileSize(undefined)).toBe('-');
+ });
+
+ it('should handle accidental non-empty string input', () => {
+ expect(formatFileSize('foo')).toBe('0 B');
+ });
+});
+
+describe('formatCWLResourceSize', () => {
+ it('should format bytes as MiB', () => {
+ const base = 1024 ** 2;
+
+ const testCases = [
+ {input: 0, output: '0 MiB'},
+ {input: 1, output: '0 MiB'},
+ {input: base - 1, output: '1 MiB'},
+ {input: 2 * base, output: '2 MiB'},
+ {input: 1024 * base, output: '1024 MiB'},
+ {input: 10000 * base, output: '10000 MiB'},
+ ];
+
+ for (const { input, output } of testCases) {
+ expect(formatCWLResourceSize(input)).toBe(output);
+ }
+ });
+});
describe('formatUploadSpeed', () => {
it('should show speed less than 1MB/s', () => {
import { connect } from 'react-redux';
import { ClusterConfigJSON } from 'common/config';
import { NotFoundView } from 'views/not-found-panel/not-found-panel';
-import { formatCost, formatFileSize } from 'common/formatters';
+import { formatCWLResourceSize, formatCost, formatFileSize } from 'common/formatters';
type CssRules = 'root' | 'instanceType';
{Object.keys(instances).length > 0 ?
Object.keys(instances).map((instanceKey) => {
const instanceType = instances[instanceKey];
+ const diskRequest = instanceType.IncludedScratch;
+ const ramRequest = instanceType.RAM - config.Containers.ReserveExtraRAM;
return <Grid data-cy={instanceKey} className={classes.instanceType} item sm={6} xs={12} key={instanceKey}>
<Card>
Preemptible: {instanceType.Preemptible.toString()}
</Typography>
<Typography>
- Max disk request: {formatFileSize(instanceType.IncludedScratch)}
+ Max disk request: {formatCWLResourceSize(diskRequest)} ({formatFileSize(diskRequest)})
</Typography>
<Typography>
- Max ram request: {formatFileSize(instanceType.RAM - config.Containers.ReserveExtraRAM)}
+ Max RAM request: {formatCWLResourceSize(ramRequest)} ({formatFileSize(ramRequest)})
</Typography>
{instanceType.CUDA && instanceType.CUDA.DeviceCount > 0 ?
<>