diff --git a/frontend/src/container/MetricsApplication/__mocks__/getTopOperation.ts b/frontend/src/container/MetricsApplication/__mocks__/getTopOperation.ts new file mode 100644 index 0000000000..27833f5415 --- /dev/null +++ b/frontend/src/container/MetricsApplication/__mocks__/getTopOperation.ts @@ -0,0 +1,19 @@ +import { TopOperationList } from '../TopOperationsTable'; + +interface TopOperation { + numCalls: number; + errorCount: number; +} + +export const getTopOperationList = ({ + errorCount, + numCalls, +}: TopOperation): TopOperationList => + ({ + p50: 0, + errorCount, + name: 'test', + numCalls, + p95: 0, + p99: 0, + } as TopOperationList); diff --git a/frontend/src/container/MetricsApplication/utils.test.ts b/frontend/src/container/MetricsApplication/utils.test.ts new file mode 100644 index 0000000000..7ad338d850 --- /dev/null +++ b/frontend/src/container/MetricsApplication/utils.test.ts @@ -0,0 +1,70 @@ +import { getTopOperationList } from './__mocks__/getTopOperation'; +import { TopOperationList } from './TopOperationsTable'; +import { + convertedTracesToDownloadData, + getErrorRate, + getNearestHighestBucketValue, +} from './utils'; + +describe('Error Rate', () => { + test('should return correct error rate', () => { + const list: TopOperationList = getTopOperationList({ + errorCount: 10, + numCalls: 100, + }); + + expect(getErrorRate(list)).toBe(10); + }); + + test('should handle no errors gracefully', () => { + const list = getTopOperationList({ errorCount: 0, numCalls: 100 }); + expect(getErrorRate(list)).toBe(0); + }); + + test('should handle zero calls', () => { + const list = getTopOperationList({ errorCount: 0, numCalls: 0 }); + expect(getErrorRate(list)).toBe(0); + }); +}); + +describe('getNearestHighestBucketValue', () => { + test('should return nearest higher bucket value', () => { + expect(getNearestHighestBucketValue(50, [10, 20, 30, 40, 60, 70])).toBe('60'); + }); + + test('should return +Inf for value higher than any bucket', () => { + expect(getNearestHighestBucketValue(80, [10, 20, 30, 40, 60, 70])).toBe( + '+Inf', + ); + }); + + test('should return the first bucket for value lower than all buckets', () => { + expect(getNearestHighestBucketValue(5, [10, 20, 30, 40, 60, 70])).toBe('10'); + }); +}); + +describe('convertedTracesToDownloadData', () => { + test('should convert trace data correctly', () => { + const data = [ + { + name: 'op1', + p50: 50000000, + p95: 95000000, + p99: 99000000, + numCalls: 100, + errorCount: 10, + }, + ]; + + expect(convertedTracesToDownloadData(data)).toEqual([ + { + Name: 'op1', + 'P50 (in ms)': '50.00', + 'P95 (in ms)': '95.00', + 'P99 (in ms)': '99.00', + 'Number of calls': '100', + 'Error Rate (%)': '10.00', + }, + ]); + }); +}); diff --git a/frontend/src/container/MetricsApplication/utils.ts b/frontend/src/container/MetricsApplication/utils.ts index a6aec561d7..0fdf307ace 100644 --- a/frontend/src/container/MetricsApplication/utils.ts +++ b/frontend/src/container/MetricsApplication/utils.ts @@ -5,8 +5,12 @@ import history from 'lib/history'; import { TopOperationList } from './TopOperationsTable'; import { NavigateToTraceProps } from './types'; -export const getErrorRate = (list: TopOperationList): number => - (list.errorCount / list.numCalls) * 100; +export const getErrorRate = (list: TopOperationList): number => { + if (list.errorCount === 0 && list.numCalls === 0) { + return 0; + } + return (list.errorCount / list.numCalls) * 100; +}; export const navigateToTrace = ({ servicename,