mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-19 16:36:45 +00:00
chore: add unit tests for hosts list in infra monitoring (#8230)
This commit is contained in:
parent
75f62372ae
commit
66affb0ece
@ -0,0 +1,43 @@
|
|||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
import HostsEmptyOrIncorrectMetrics from '../HostsEmptyOrIncorrectMetrics';
|
||||||
|
|
||||||
|
describe('HostsEmptyOrIncorrectMetrics', () => {
|
||||||
|
it('shows no data message when noData is true', () => {
|
||||||
|
render(<HostsEmptyOrIncorrectMetrics noData incorrectData={false} />);
|
||||||
|
expect(
|
||||||
|
screen.getByText('No host metrics data received yet.'),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
expect(
|
||||||
|
screen.getByText(/Infrastructure monitoring requires the/),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows incorrect data message when incorrectData is true', () => {
|
||||||
|
render(<HostsEmptyOrIncorrectMetrics noData={false} incorrectData />);
|
||||||
|
expect(
|
||||||
|
screen.getByText(
|
||||||
|
'To see host metrics, upgrade to the latest version of SigNoz k8s-infra chart. Please contact support if you need help.',
|
||||||
|
),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show no data message when noData is false', () => {
|
||||||
|
render(<HostsEmptyOrIncorrectMetrics noData={false} incorrectData={false} />);
|
||||||
|
expect(
|
||||||
|
screen.queryByText('No host metrics data received yet.'),
|
||||||
|
).not.toBeInTheDocument();
|
||||||
|
expect(
|
||||||
|
screen.queryByText(/Infrastructure monitoring requires the/),
|
||||||
|
).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show incorrect data message when incorrectData is false', () => {
|
||||||
|
render(<HostsEmptyOrIncorrectMetrics noData={false} incorrectData={false} />);
|
||||||
|
expect(
|
||||||
|
screen.queryByText(
|
||||||
|
'To see host metrics, upgrade to the latest version of SigNoz k8s-infra chart. Please contact support if you need help.',
|
||||||
|
),
|
||||||
|
).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,166 @@
|
|||||||
|
/* eslint-disable react/button-has-type */
|
||||||
|
import { render } from '@testing-library/react';
|
||||||
|
import ROUTES from 'constants/routes';
|
||||||
|
import * as useGetHostListHooks from 'hooks/infraMonitoring/useGetHostList';
|
||||||
|
import * as appContextHooks from 'providers/App/App';
|
||||||
|
import * as timezoneHooks from 'providers/Timezone';
|
||||||
|
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
import store from 'store';
|
||||||
|
import { LicenseEvent } from 'types/api/licensesV3/getActive';
|
||||||
|
|
||||||
|
import HostsList from '../HostsList';
|
||||||
|
|
||||||
|
jest.mock('lib/getMinMax', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: jest.fn().mockImplementation(() => ({
|
||||||
|
minTime: 1713734400000,
|
||||||
|
maxTime: 1713738000000,
|
||||||
|
isValidTimeFormat: jest.fn().mockReturnValue(true),
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
jest.mock('components/CustomTimePicker/CustomTimePicker', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: ({ onSelect, selectedTime, selectedValue }: any): JSX.Element => (
|
||||||
|
<div data-testid="custom-time-picker">
|
||||||
|
<button onClick={(): void => onSelect('custom')}>
|
||||||
|
{selectedTime} - {selectedValue}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
|
jest.mock('uplot', () => {
|
||||||
|
const paths = {
|
||||||
|
spline: jest.fn(),
|
||||||
|
bars: jest.fn(),
|
||||||
|
};
|
||||||
|
const uplotMock = jest.fn(() => ({
|
||||||
|
paths,
|
||||||
|
}));
|
||||||
|
return {
|
||||||
|
paths,
|
||||||
|
default: uplotMock,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
jest.mock('react-redux', () => ({
|
||||||
|
...jest.requireActual('react-redux'),
|
||||||
|
useSelector: (): any => ({
|
||||||
|
globalTime: {
|
||||||
|
selectedTime: {
|
||||||
|
startTime: 1713734400000,
|
||||||
|
endTime: 1713738000000,
|
||||||
|
},
|
||||||
|
maxTime: 1713738000000,
|
||||||
|
minTime: 1713734400000,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
jest.mock('react-router-dom', () => ({
|
||||||
|
...jest.requireActual('react-router-dom'),
|
||||||
|
useLocation: jest.fn().mockReturnValue({
|
||||||
|
pathname: ROUTES.INFRASTRUCTURE_MONITORING_HOSTS,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
jest.mock('react-router-dom-v5-compat', () => {
|
||||||
|
const actual = jest.requireActual('react-router-dom-v5-compat');
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
useSearchParams: jest
|
||||||
|
.fn()
|
||||||
|
.mockReturnValue([
|
||||||
|
{ get: jest.fn(), entries: jest.fn().mockReturnValue([]) },
|
||||||
|
jest.fn(),
|
||||||
|
]),
|
||||||
|
useNavigationType: (): any => 'PUSH',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
jest.mock('hooks/useSafeNavigate', () => ({
|
||||||
|
useSafeNavigate: (): any => ({
|
||||||
|
safeNavigate: jest.fn(),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.spyOn(timezoneHooks, 'useTimezone').mockReturnValue({
|
||||||
|
timezone: {
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
browserTimezone: {
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
} as any);
|
||||||
|
jest.spyOn(useGetHostListHooks, 'useGetHostList').mockReturnValue({
|
||||||
|
data: {
|
||||||
|
payload: {
|
||||||
|
data: {
|
||||||
|
records: [
|
||||||
|
{
|
||||||
|
hostName: 'test-host',
|
||||||
|
active: true,
|
||||||
|
cpu: 0.75,
|
||||||
|
memory: 0.65,
|
||||||
|
wait: 0.03,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isSendingK8SAgentMetrics: false,
|
||||||
|
sentAnyHostMetricsData: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
isLoading: false,
|
||||||
|
isError: false,
|
||||||
|
} as any);
|
||||||
|
jest.spyOn(appContextHooks, 'useAppContext').mockReturnValue({
|
||||||
|
user: {
|
||||||
|
role: 'admin',
|
||||||
|
},
|
||||||
|
activeLicenseV3: {
|
||||||
|
event_queue: {
|
||||||
|
created_at: '0',
|
||||||
|
event: LicenseEvent.NO_EVENT,
|
||||||
|
scheduled_at: '0',
|
||||||
|
status: '',
|
||||||
|
updated_at: '0',
|
||||||
|
},
|
||||||
|
license: {
|
||||||
|
license_key: 'test-license-key',
|
||||||
|
license_type: 'trial',
|
||||||
|
org_id: 'test-org-id',
|
||||||
|
plan_id: 'test-plan-id',
|
||||||
|
plan_name: 'test-plan-name',
|
||||||
|
plan_type: 'trial',
|
||||||
|
plan_version: 'test-plan-version',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
describe('HostsList', () => {
|
||||||
|
it('renders hosts list table', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<QueryClientProvider client={queryClient}>
|
||||||
|
<MemoryRouter>
|
||||||
|
<Provider store={store}>
|
||||||
|
<HostsList />
|
||||||
|
</Provider>
|
||||||
|
</MemoryRouter>
|
||||||
|
</QueryClientProvider>,
|
||||||
|
);
|
||||||
|
expect(container.querySelector('.hosts-list-table')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders filters', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<QueryClientProvider client={queryClient}>
|
||||||
|
<MemoryRouter>
|
||||||
|
<Provider store={store}>
|
||||||
|
<HostsList />
|
||||||
|
</Provider>
|
||||||
|
</MemoryRouter>
|
||||||
|
</QueryClientProvider>,
|
||||||
|
);
|
||||||
|
expect(container.querySelector('.filters')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
import HostsListControls from '../HostsListControls';
|
||||||
|
|
||||||
|
jest.mock('container/QueryBuilder/filters/QueryBuilderSearch', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: (): JSX.Element => (
|
||||||
|
<div data-testid="query-builder-search">Search</div>
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('container/TopNav/DateTimeSelectionV2', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: (): JSX.Element => (
|
||||||
|
<div data-testid="date-time-selection">Date Time</div>
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('HostsListControls', () => {
|
||||||
|
const mockHandleFiltersChange = jest.fn();
|
||||||
|
const mockFilters = {
|
||||||
|
items: [],
|
||||||
|
op: 'AND',
|
||||||
|
};
|
||||||
|
|
||||||
|
it('renders search and date time filters', () => {
|
||||||
|
render(
|
||||||
|
<HostsListControls
|
||||||
|
handleFiltersChange={mockHandleFiltersChange}
|
||||||
|
filters={mockFilters}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByTestId('query-builder-search')).toBeInTheDocument();
|
||||||
|
expect(screen.getByTestId('date-time-selection')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,139 @@
|
|||||||
|
/* eslint-disable react/jsx-props-no-spreading */
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
import HostsListTable from '../HostsListTable';
|
||||||
|
|
||||||
|
jest.mock('uplot', () => {
|
||||||
|
const paths = {
|
||||||
|
spline: jest.fn(),
|
||||||
|
bars: jest.fn(),
|
||||||
|
};
|
||||||
|
const uplotMock = jest.fn(() => ({
|
||||||
|
paths,
|
||||||
|
}));
|
||||||
|
return {
|
||||||
|
paths,
|
||||||
|
default: uplotMock,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const EMPTY_STATE_CONTAINER_CLASS = '.hosts-empty-state-container';
|
||||||
|
|
||||||
|
describe('HostsListTable', () => {
|
||||||
|
const mockHost = {
|
||||||
|
hostName: 'test-host-1',
|
||||||
|
active: true,
|
||||||
|
cpu: 0.75,
|
||||||
|
memory: 0.65,
|
||||||
|
wait: 0.03,
|
||||||
|
load15: 1.5,
|
||||||
|
os: 'linux',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockTableData = {
|
||||||
|
payload: {
|
||||||
|
data: {
|
||||||
|
hosts: [mockHost],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const mockOnHostClick = jest.fn();
|
||||||
|
const mockSetCurrentPage = jest.fn();
|
||||||
|
const mockSetOrderBy = jest.fn();
|
||||||
|
const mockSetPageSize = jest.fn();
|
||||||
|
const mockProps = {
|
||||||
|
isLoading: false,
|
||||||
|
isError: false,
|
||||||
|
isFetching: false,
|
||||||
|
tableData: mockTableData,
|
||||||
|
hostMetricsData: [mockHost],
|
||||||
|
filters: {
|
||||||
|
items: [],
|
||||||
|
op: 'AND',
|
||||||
|
},
|
||||||
|
onHostClick: mockOnHostClick,
|
||||||
|
currentPage: 1,
|
||||||
|
setCurrentPage: mockSetCurrentPage,
|
||||||
|
pageSize: 10,
|
||||||
|
setOrderBy: mockSetOrderBy,
|
||||||
|
setPageSize: mockSetPageSize,
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
it('renders loading state if isLoading is true', () => {
|
||||||
|
const { container } = render(<HostsListTable {...mockProps} isLoading />);
|
||||||
|
expect(container.querySelector('.hosts-list-loading-state')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders loading state if isFetching is true', () => {
|
||||||
|
const { container } = render(<HostsListTable {...mockProps} isFetching />);
|
||||||
|
expect(container.querySelector('.hosts-list-loading-state')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders error state if isError is true', () => {
|
||||||
|
render(<HostsListTable {...mockProps} isError />);
|
||||||
|
expect(screen.getByText('Something went wrong')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders empty state if no hosts are found', () => {
|
||||||
|
const { container } = render(<HostsListTable {...mockProps} />);
|
||||||
|
expect(container.querySelector(EMPTY_STATE_CONTAINER_CLASS)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders empty state if sentAnyHostMetricsData is false', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<HostsListTable
|
||||||
|
{...mockProps}
|
||||||
|
tableData={{
|
||||||
|
...mockTableData,
|
||||||
|
payload: {
|
||||||
|
...mockTableData.payload,
|
||||||
|
data: {
|
||||||
|
...mockTableData.payload.data,
|
||||||
|
sentAnyHostMetricsData: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(container.querySelector(EMPTY_STATE_CONTAINER_CLASS)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders empty state if isSendingIncorrectK8SAgentMetrics is true', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<HostsListTable
|
||||||
|
{...mockProps}
|
||||||
|
tableData={{
|
||||||
|
...mockTableData,
|
||||||
|
payload: {
|
||||||
|
...mockTableData.payload,
|
||||||
|
data: {
|
||||||
|
...mockTableData.payload.data,
|
||||||
|
isSendingIncorrectK8SAgentMetrics: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(container.querySelector(EMPTY_STATE_CONTAINER_CLASS)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders table data', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<HostsListTable
|
||||||
|
{...mockProps}
|
||||||
|
tableData={{
|
||||||
|
...mockTableData,
|
||||||
|
payload: {
|
||||||
|
...mockTableData.payload,
|
||||||
|
data: {
|
||||||
|
...mockTableData.payload.data,
|
||||||
|
isSendingIncorrectK8SAgentMetrics: false,
|
||||||
|
sentAnyHostMetricsData: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(container.querySelector('.hosts-list-table')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,104 @@
|
|||||||
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
|
import { formatDataForTable, GetHostsQuickFiltersConfig } from '../utils';
|
||||||
|
|
||||||
|
const PROGRESS_BAR_CLASS = '.progress-bar';
|
||||||
|
|
||||||
|
jest.mock('uplot', () => {
|
||||||
|
const paths = {
|
||||||
|
spline: jest.fn(),
|
||||||
|
bars: jest.fn(),
|
||||||
|
};
|
||||||
|
const uplotMock = jest.fn(() => ({
|
||||||
|
paths,
|
||||||
|
}));
|
||||||
|
return {
|
||||||
|
paths,
|
||||||
|
default: uplotMock,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('InfraMonitoringHosts utils', () => {
|
||||||
|
describe('formatDataForTable', () => {
|
||||||
|
it('should format host data correctly', () => {
|
||||||
|
const mockData = [
|
||||||
|
{
|
||||||
|
hostName: 'test-host',
|
||||||
|
active: true,
|
||||||
|
cpu: 0.95,
|
||||||
|
memory: 0.85,
|
||||||
|
wait: 0.05,
|
||||||
|
load15: 2.5,
|
||||||
|
os: 'linux',
|
||||||
|
},
|
||||||
|
] as any;
|
||||||
|
|
||||||
|
const result = formatDataForTable(mockData);
|
||||||
|
|
||||||
|
expect(result[0].hostName).toBe('test-host');
|
||||||
|
expect(result[0].wait).toBe('5%');
|
||||||
|
expect(result[0].load15).toBe(2.5);
|
||||||
|
|
||||||
|
// Test active tag rendering
|
||||||
|
const activeTag = render(result[0].active as JSX.Element);
|
||||||
|
expect(activeTag.container.textContent).toBe('ACTIVE');
|
||||||
|
expect(activeTag.container.querySelector('.active')).toBeTruthy();
|
||||||
|
|
||||||
|
// Test CPU progress bar
|
||||||
|
const cpuProgress = render(result[0].cpu as JSX.Element);
|
||||||
|
const cpuProgressBar = cpuProgress.container.querySelector(
|
||||||
|
PROGRESS_BAR_CLASS,
|
||||||
|
);
|
||||||
|
expect(cpuProgressBar).toBeTruthy();
|
||||||
|
|
||||||
|
// Test memory progress bar
|
||||||
|
const memoryProgress = render(result[0].memory as JSX.Element);
|
||||||
|
const memoryProgressBar = memoryProgress.container.querySelector(
|
||||||
|
PROGRESS_BAR_CLASS,
|
||||||
|
);
|
||||||
|
expect(memoryProgressBar).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle inactive hosts', () => {
|
||||||
|
const mockData = [
|
||||||
|
{
|
||||||
|
hostName: 'test-host',
|
||||||
|
active: false,
|
||||||
|
cpu: 0.3,
|
||||||
|
memory: 0.4,
|
||||||
|
wait: 0.02,
|
||||||
|
load15: 1.2,
|
||||||
|
os: 'linux',
|
||||||
|
cpuTimeSeries: [],
|
||||||
|
memoryTimeSeries: [],
|
||||||
|
waitTimeSeries: [],
|
||||||
|
load15TimeSeries: [],
|
||||||
|
},
|
||||||
|
] as any;
|
||||||
|
|
||||||
|
const result = formatDataForTable(mockData);
|
||||||
|
|
||||||
|
const inactiveTag = render(result[0].active as JSX.Element);
|
||||||
|
expect(inactiveTag.container.textContent).toBe('INACTIVE');
|
||||||
|
expect(inactiveTag.container.querySelector('.inactive')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GetHostsQuickFiltersConfig', () => {
|
||||||
|
it('should return correct config when dotMetricsEnabled is true', () => {
|
||||||
|
const result = GetHostsQuickFiltersConfig(true);
|
||||||
|
|
||||||
|
expect(result[0].attributeKey.key).toBe('host.name');
|
||||||
|
expect(result[1].attributeKey.key).toBe('os.type');
|
||||||
|
expect(result[0].aggregateAttribute).toBe('system.cpu.load_average.15m');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct config when dotMetricsEnabled is false', () => {
|
||||||
|
const result = GetHostsQuickFiltersConfig(false);
|
||||||
|
|
||||||
|
expect(result[0].attributeKey.key).toBe('host_name');
|
||||||
|
expect(result[1].attributeKey.key).toBe('os_type');
|
||||||
|
expect(result[0].aggregateAttribute).toBe('system_cpu_load_average_15m');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user