mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Fleet] skip loading agents when in progress (#136624)
* skip loading agents when in progress * added unit test * added comment
This commit is contained in:
parent
302bd423f3
commit
68cb7fb680
2 changed files with 125 additions and 83 deletions
|
@ -12,7 +12,7 @@ import { act, fireEvent, waitFor } from '@testing-library/react';
|
|||
|
||||
import { createFleetTestRendererMock } from '../../../../../mock';
|
||||
|
||||
import { sendGetAgents } from '../../../hooks';
|
||||
import { sendGetAgents, sendGetAgentStatus } from '../../../hooks';
|
||||
|
||||
import { AgentListPage } from '.';
|
||||
|
||||
|
@ -28,17 +28,7 @@ jest.mock('../../../hooks', () => ({
|
|||
return props.children;
|
||||
},
|
||||
useFleetStatus: jest.fn().mockReturnValue({}),
|
||||
sendGetAgentStatus: jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
results: {
|
||||
online: 6,
|
||||
error: 0,
|
||||
offline: 0,
|
||||
updating: 0,
|
||||
},
|
||||
totalInactive: 0,
|
||||
},
|
||||
}),
|
||||
sendGetAgentStatus: jest.fn(),
|
||||
useAuthz: jest.fn().mockReturnValue({ fleet: { all: true } }),
|
||||
useStartServices: jest.fn().mockReturnValue({
|
||||
notifications: {
|
||||
|
@ -74,6 +64,7 @@ jest.mock('./components/search_and_filter_bar', () => {
|
|||
});
|
||||
|
||||
const mockedSendGetAgents = sendGetAgents as jest.Mock;
|
||||
const mockedSendGetAgentStatus = sendGetAgentStatus as jest.Mock;
|
||||
|
||||
function renderAgentList() {
|
||||
const renderer = createFleetTestRendererMock();
|
||||
|
@ -111,96 +102,140 @@ describe('agent_list_page', () => {
|
|||
},
|
||||
});
|
||||
jest.useFakeTimers();
|
||||
|
||||
({ utils } = renderAgentList());
|
||||
|
||||
await waitFor(() => {
|
||||
expect(utils.getByText('Showing 6 agents')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
act(() => {
|
||||
const selectAll = utils.container.querySelector('[data-test-subj="checkboxSelectAll"]');
|
||||
fireEvent.click(selectAll!);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
utils.getByText('5 agents selected');
|
||||
});
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(utils.getByText('Select everything on all pages'));
|
||||
});
|
||||
utils.getByText('All agents selected');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should not set selection mode when agent selection changed automatically', async () => {
|
||||
it('should not send another agents status request if first one takes longer', () => {
|
||||
mockedSendGetAgentStatus.mockImplementation(async () => {
|
||||
const sleep = () => {
|
||||
return new Promise((res) => {
|
||||
setTimeout(() => res({}), 35000);
|
||||
});
|
||||
};
|
||||
await sleep();
|
||||
return {
|
||||
data: {
|
||||
results: {
|
||||
online: 6,
|
||||
error: 0,
|
||||
offline: 0,
|
||||
updating: 0,
|
||||
},
|
||||
totalInactive: 0,
|
||||
},
|
||||
};
|
||||
});
|
||||
({ utils } = renderAgentList());
|
||||
|
||||
act(() => {
|
||||
jest.runOnlyPendingTimers();
|
||||
jest.advanceTimersByTime(65000);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(utils.getByText('agent6')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
utils.getByText('All agents selected');
|
||||
|
||||
expect(
|
||||
utils
|
||||
.getByText('agent6')
|
||||
.closest('tr')!
|
||||
.getAttribute('class')!
|
||||
.includes('euiTableRow-isSelected')
|
||||
).toBeTruthy();
|
||||
expect(mockedSendGetAgentStatus).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should set selection mode when agent selection changed manually', async () => {
|
||||
act(() => {
|
||||
fireEvent.click(utils.getAllByRole('checkbox')[3]);
|
||||
describe('selection change', () => {
|
||||
beforeEach(async () => {
|
||||
mockedSendGetAgentStatus.mockResolvedValue({
|
||||
data: {
|
||||
results: {
|
||||
online: 6,
|
||||
error: 0,
|
||||
offline: 0,
|
||||
updating: 0,
|
||||
},
|
||||
totalInactive: 0,
|
||||
},
|
||||
});
|
||||
({ utils } = renderAgentList());
|
||||
|
||||
await waitFor(() => {
|
||||
expect(utils.getByText('Showing 6 agents')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
act(() => {
|
||||
const selectAll = utils.container.querySelector('[data-test-subj="checkboxSelectAll"]');
|
||||
fireEvent.click(selectAll!);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
utils.getByText('5 agents selected');
|
||||
});
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(utils.getByText('Select everything on all pages'));
|
||||
});
|
||||
utils.getByText('All agents selected');
|
||||
});
|
||||
|
||||
utils.getByText('4 agents selected');
|
||||
});
|
||||
it('should not set selection mode when agent selection changed automatically', async () => {
|
||||
act(() => {
|
||||
jest.runOnlyPendingTimers();
|
||||
});
|
||||
|
||||
it('should pass sort parameters on table sort', () => {
|
||||
act(() => {
|
||||
fireEvent.click(utils.getByTitle('Last activity'));
|
||||
await waitFor(() => {
|
||||
expect(utils.getByText('agent6')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
utils.getByText('All agents selected');
|
||||
|
||||
expect(
|
||||
utils
|
||||
.getByText('agent6')
|
||||
.closest('tr')!
|
||||
.getAttribute('class')!
|
||||
.includes('euiTableRow-isSelected')
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
expect(mockedSendGetAgents).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sortField: 'last_checkin',
|
||||
sortOrder: 'asc',
|
||||
})
|
||||
);
|
||||
});
|
||||
it('should set selection mode when agent selection changed manually', async () => {
|
||||
act(() => {
|
||||
fireEvent.click(utils.getAllByRole('checkbox')[3]);
|
||||
});
|
||||
|
||||
it('should pass keyword field on table sort on version', () => {
|
||||
act(() => {
|
||||
fireEvent.click(utils.getByTitle('Version'));
|
||||
utils.getByText('4 agents selected');
|
||||
});
|
||||
|
||||
expect(mockedSendGetAgents).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sortField: 'local_metadata.elastic.agent.version.keyword',
|
||||
sortOrder: 'asc',
|
||||
})
|
||||
);
|
||||
});
|
||||
it('should pass sort parameters on table sort', () => {
|
||||
act(() => {
|
||||
fireEvent.click(utils.getByTitle('Last activity'));
|
||||
});
|
||||
|
||||
it('should pass keyword field on table sort on hostname', () => {
|
||||
act(() => {
|
||||
fireEvent.click(utils.getByTitle('Host'));
|
||||
expect(mockedSendGetAgents).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sortField: 'last_checkin',
|
||||
sortOrder: 'asc',
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
expect(mockedSendGetAgents).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sortField: 'local_metadata.host.hostname.keyword',
|
||||
sortOrder: 'asc',
|
||||
})
|
||||
);
|
||||
it('should pass keyword field on table sort on version', () => {
|
||||
act(() => {
|
||||
fireEvent.click(utils.getByTitle('Version'));
|
||||
});
|
||||
|
||||
expect(mockedSendGetAgents).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sortField: 'local_metadata.elastic.agent.version.keyword',
|
||||
sortOrder: 'asc',
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should pass keyword field on table sort on hostname', () => {
|
||||
act(() => {
|
||||
fireEvent.click(utils.getByTitle('Host'));
|
||||
});
|
||||
|
||||
expect(mockedSendGetAgents).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sortField: 'local_metadata.host.hostname.keyword',
|
||||
sortOrder: 'asc',
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -220,14 +220,20 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
|
|||
},
|
||||
};
|
||||
|
||||
const isLoadingVar = useRef<boolean>(false);
|
||||
|
||||
// Request to fetch agents and agent status
|
||||
const currentRequestRef = useRef<number>(0);
|
||||
const fetchData = useCallback(
|
||||
({ refreshTags = false }: { refreshTags?: boolean } = {}) => {
|
||||
async function fetchDataAsync() {
|
||||
// skipping refresh if previous request is in progress
|
||||
if (isLoadingVar.current) {
|
||||
return;
|
||||
}
|
||||
currentRequestRef.current++;
|
||||
const currentRequest = currentRequestRef.current;
|
||||
|
||||
isLoadingVar.current = true;
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const [agentsRequest, agentsStatusRequest] = await Promise.all([
|
||||
|
@ -244,7 +250,8 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
|
|||
kuery: kuery && kuery !== '' ? kuery : undefined,
|
||||
}),
|
||||
]);
|
||||
// Return if a newer request as been triggered
|
||||
isLoadingVar.current = false;
|
||||
// Return if a newer request has been triggered
|
||||
if (currentRequestRef.current !== currentRequest) {
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue