diff --git a/packages/jaeger-ui/src/components/Monitoring/ServicesView/index.test.js b/packages/jaeger-ui/src/components/Monitoring/ServicesView/index.test.js index 1811b8dd42..42deffa0fb 100644 --- a/packages/jaeger-ui/src/components/Monitoring/ServicesView/index.test.js +++ b/packages/jaeger-ui/src/components/Monitoring/ServicesView/index.test.js @@ -22,6 +22,7 @@ import { } from '.'; import LoadingIndicator from '../../common/LoadingIndicator'; import MonitoringATMEmptyState from '../EmptyState'; +import ServiceGraph from './serviceGraph'; import { originInitialState, serviceMetrics, serviceOpsMetrics } from '../../../reducers/metrics.mock'; const state = { @@ -103,7 +104,7 @@ describe('', () => { expect(wrapper).toMatchSnapshot(); }); - it('ComponentWillUnmount remove listnere', () => { + it('ComponentWillUnmount remove listener', () => { const remover = jest.spyOn(global, 'removeEventListener').mockImplementation(() => {}); wrapper.unmount(); expect(remover).toHaveBeenCalled(); @@ -140,6 +141,76 @@ describe('', () => { wrapper.find('Search').simulate('change', { target: { value: '' } }); expect(wrapper.state().serviceOpsMetrics.length).toBe(1); }); + + it('Error in serviceLatencies ', () => { + wrapper.setProps({ + services: ['s1', 's2'], + selectedService: 's1', + metrics: { + ...originInitialState, + serviceMetrics, + serviceOpsMetrics, + loading: false, + isATMActivated: true, + serviceError: { + ...originInitialState.serviceError, + service_latencies_50: new Error('some API error'), + }, + }, + }); + expect( + wrapper + .find(ServiceGraph) + .first() + .prop('error') + ).toBeNull(); + + wrapper.setProps({ + services: ['s1', 's2'], + selectedService: 's1', + metrics: { + ...originInitialState, + serviceMetrics, + serviceOpsMetrics, + loading: false, + isATMActivated: true, + serviceError: { + ...originInitialState.serviceError, + service_latencies_50: new Error('some API error'), + service_latencies_75: new Error('some API error'), + }, + }, + }); + expect( + wrapper + .find(ServiceGraph) + .first() + .prop('error') + ).toBeNull(); + + wrapper.setProps({ + services: ['s1', 's2'], + selectedService: 's1', + metrics: { + ...originInitialState, + serviceMetrics, + serviceOpsMetrics, + loading: false, + isATMActivated: true, + serviceError: { + service_latencies_50: new Error('some API error'), + service_latencies_75: new Error('some API error'), + service_latencies_95: new Error('some API error'), + }, + }, + }); + expect( + wrapper + .find(ServiceGraph) + .first() + .prop('error') + ).not.toBeNull(); + }); }); describe('mapStateToProps()', () => { diff --git a/packages/jaeger-ui/src/components/Monitoring/ServicesView/operationDetailsTable/__snapshots__/index.test.js.snap b/packages/jaeger-ui/src/components/Monitoring/ServicesView/operationDetailsTable/__snapshots__/index.test.js.snap index 037863d655..6bb30d9f10 100644 --- a/packages/jaeger-ui/src/components/Monitoring/ServicesView/operationDetailsTable/__snapshots__/index.test.js.snap +++ b/packages/jaeger-ui/src/components/Monitoring/ServicesView/operationDetailsTable/__snapshots__/index.test.js.snap @@ -729,12 +729,7 @@ exports[` render some values in the table 1`] = ` onClick={[Function]} >
render some values in the table 1`] = ` onClick={[Function]} >
render some values in the table 1`] = ` onClick={[Function]} >
render some values in the table 1`] = ` onClick={[Function]} >
', () => { .text() ).toBe('/Accounts'); }); + + it('Graph avg label test', () => { + const data = [ + { + dataPoints: { + avg: { + service_operation_call_rate: 11, + service_operation_error_rate: 22, + service_operation_latencies: 99, + }, + service_operation_call_rate: [], + service_operation_error_rate: [], + service_operation_latencies: [], + }, + errRates: 1, + impact: 2, + key: 1, + latency: 3, + name: '/Accounts', + requests: 4, + }, + ]; + + wrapper.setProps({ ...props, data, loading: false }); + + // Latency + expect( + wrapper + .find('div.table-graph-avg') + .at(0) + .text() + ).toBe(''); + + // Request rate + expect( + wrapper + .find('div.table-graph-avg') + .at(1) + .text() + ).toBe(''); + + // Error rate + expect( + wrapper + .find('div.table-graph-avg') + .at(2) + .text() + ).toBe(''); + }); }); diff --git a/packages/jaeger-ui/src/components/Monitoring/ServicesView/operationDetailsTable/index.tsx b/packages/jaeger-ui/src/components/Monitoring/ServicesView/operationDetailsTable/index.tsx index 0b7e979a1b..3dd80a092d 100644 --- a/packages/jaeger-ui/src/components/Monitoring/ServicesView/operationDetailsTable/index.tsx +++ b/packages/jaeger-ui/src/components/Monitoring/ServicesView/operationDetailsTable/index.tsx @@ -65,16 +65,14 @@ export class OperationTableDetails extends React.PureComponent { key: 'latency', sorter: (a: ServiceOpsMetrics, b: ServiceOpsMetrics) => a.latency - b.latency, render: (value: ServiceOpsMetrics['latency'], row: ServiceOpsMetrics) => ( -
+
- {typeof value === 'number' && row.dataPoints.service_operation_latencies.length > 0 - ? `${value} ms` - : ''} + {row.dataPoints.service_operation_latencies.length > 0 ? `${value} ms` : ''}
), @@ -86,16 +84,14 @@ export class OperationTableDetails extends React.PureComponent { key: 'requests', sorter: (a: ServiceOpsMetrics, b: ServiceOpsMetrics) => a.requests - b.requests, render: (value: ServiceOpsMetrics['requests'], row: ServiceOpsMetrics) => ( -
+
- {typeof value === 'number' && row.dataPoints.service_operation_call_rate.length > 0 - ? `${value} req/s` - : ''} + {row.dataPoints.service_operation_call_rate.length > 0 ? `${value} req/s` : ''}
), @@ -107,7 +103,7 @@ export class OperationTableDetails extends React.PureComponent { key: 'errRates', sorter: (a: ServiceOpsMetrics, b: ServiceOpsMetrics) => a.errRates - b.errRates, render: (value: ServiceOpsMetrics['errRates'], row: ServiceOpsMetrics) => ( -
+
{ error={error.opsErrors} />
- {typeof value === 'number' && row.dataPoints.service_operation_error_rate.length > 0 - ? `${value}%` - : ''} + {row.dataPoints.service_operation_error_rate.length > 0 ? `${value}%` : ''}
), @@ -163,7 +157,7 @@ export class OperationTableDetails extends React.PureComponent { return { children: ( -
+
{ getData(): ServiceMetricsObject[] { const { metricsData } = this.props; + + // TS required to check, but we do it in render function + /* istanbul ignore next */ if (metricsData === null) { return []; } @@ -88,18 +91,14 @@ export class ServiceGraphImpl extends React.PureComponent { key={i++} data={line.metricPoints ? line.metricPoints : []} getNull={(d: Points) => d.y !== null} - onNearestX={ - idx === 0 - ? (_datapoint: Points, { index }: { index: number }) => { - this.setState({ - crosshairValues: this.getData().map((d: ServiceMetricsObject) => ({ - ...d.metricPoints[index], - label: d.quantile, - })), - }); - } - : null - } + onNearestX={(_datapoint: Points, { index }: { index: number }) => { + this.setState({ + crosshairValues: this.getData().map((d: ServiceMetricsObject) => ({ + ...d.metricPoints[index], + label: d.quantile, + })), + }); + }} opacity={0.1} color={[color || this.colors[idx]]} /> diff --git a/packages/jaeger-ui/src/reducers/metrics.test.js b/packages/jaeger-ui/src/reducers/metrics.test.js index 139bd8ee6b..177f4bfa81 100644 --- a/packages/jaeger-ui/src/reducers/metrics.test.js +++ b/packages/jaeger-ui/src/reducers/metrics.test.js @@ -39,6 +39,17 @@ describe('reducers/fetchAllServiceMetrics', () => { beforeEach(verifyInitialState); afterEach(verifyInitialState); + it('Pending state ', () => { + const state = metricReducer(initialState, { + type: `${fetchAllServiceMetrics}_PENDING`, + }); + + expect(state).toEqual({ + ...initialState, + loading: true, + }); + }); + it('payload is undefined', () => { const state = metricReducer(initialState, { type: `${fetchAllServiceMetrics}_FULFILLED`, @@ -235,6 +246,17 @@ describe('reducers/fetchAggregatedServiceMetrics', () => { beforeEach(verifyInitialState); afterEach(verifyInitialState); + it('Pending state ', () => { + const state = metricReducer(initialState, { + type: `${fetchAggregatedServiceMetrics}_PENDING`, + }); + + expect(state).toEqual({ + ...initialState, + operationMetricsLoading: true, + }); + }); + it('payload is undefined', () => { const state = metricReducer(initialState, { type: `${fetchAggregatedServiceMetrics}_FULFILLED`,