mirror of
https://github.com/ansible/awx.git
synced 2026-05-17 06:17:36 -02:30
Only derive row count from max counter when job is running.
This commit is contained in:
committed by
Shane McDonald
parent
dc327ceaeb
commit
1211faf8df
@@ -434,28 +434,42 @@ function JobOutput({ job, eventRelatedSearchableKeys, eventSearchableKeys }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const eventPromise = getJobModel(job.type).readEvents(job.id, {
|
||||||
|
...params,
|
||||||
|
...parseQueryString(QS_CONFIG, location.search),
|
||||||
|
});
|
||||||
|
|
||||||
|
let countRequest;
|
||||||
|
if (isJobRunning(job?.status)) {
|
||||||
|
// If the job is running, it means we're using limit-offset pagination. Requests
|
||||||
|
// with limit-offset pagination won't return a total event count for performance
|
||||||
|
// reasons. In this situation, we derive the remote row count by using the highest
|
||||||
|
// counter available in the database.
|
||||||
|
countRequest = async () => {
|
||||||
|
const {
|
||||||
|
data: { results: lastEvents = [] },
|
||||||
|
} = await getJobModel(job.type).readEvents(job.id, {
|
||||||
|
order_by: '-counter',
|
||||||
|
limit: 1,
|
||||||
|
});
|
||||||
|
return lastEvents.length >= 1 ? lastEvents[0].counter : 0;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
countRequest = async () => {
|
||||||
|
const {
|
||||||
|
data: { count: eventCount },
|
||||||
|
} = await eventPromise;
|
||||||
|
return eventCount;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [
|
const [
|
||||||
{
|
{
|
||||||
data: { results: fetchedEvents = [] },
|
data: { results: fetchedEvents = [] },
|
||||||
},
|
},
|
||||||
{
|
count,
|
||||||
data: { results: lastEvents = [] },
|
] = await Promise.all([eventPromise, countRequest()]);
|
||||||
},
|
|
||||||
] = await Promise.all([
|
|
||||||
getJobModel(job.type).readEvents(job.id, {
|
|
||||||
...params,
|
|
||||||
...parseQueryString(QS_CONFIG, location.search),
|
|
||||||
}),
|
|
||||||
getJobModel(job.type).readEvents(job.id, {
|
|
||||||
order_by: '-counter',
|
|
||||||
limit: 1,
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
let count = 0;
|
|
||||||
if (lastEvents.length >= 1 && lastEvents[0]?.counter) {
|
|
||||||
count = lastEvents[0]?.counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isMounted.current) {
|
if (isMounted.current) {
|
||||||
let countOffset = 0;
|
let countOffset = 0;
|
||||||
|
|||||||
@@ -13,6 +13,22 @@ import mockFilteredJobEventsData from './data.filtered_job_events.json';
|
|||||||
|
|
||||||
jest.mock('../../../api');
|
jest.mock('../../../api');
|
||||||
|
|
||||||
|
const applyJobEventMock = mockJobEvents => {
|
||||||
|
const mockReadEvents = async (jobId, params) => {
|
||||||
|
const [...results] = mockJobEvents.results;
|
||||||
|
if (params.order_by && params.order_by.includes('-')) {
|
||||||
|
results.reverse();
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
results,
|
||||||
|
count: mockJobEvents.count,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
JobsAPI.readEvents = jest.fn().mockImplementation(mockReadEvents);
|
||||||
|
};
|
||||||
|
|
||||||
const generateChattyRows = () => {
|
const generateChattyRows = () => {
|
||||||
const rows = [
|
const rows = [
|
||||||
'',
|
'',
|
||||||
@@ -82,24 +98,13 @@ const originalOffsetWidth = Object.getOwnPropertyDescriptor(
|
|||||||
describe('<JobOutput />', () => {
|
describe('<JobOutput />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
const mockJob = mockJobData;
|
const mockJob = mockJobData;
|
||||||
const mockJobEvents = mockJobEventsData;
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
JobsAPI.readEvents = (jobId, params) => {
|
applyJobEventMock(mockJobEventsData);
|
||||||
const [...results] = mockJobEvents.results;
|
|
||||||
if (params.order_by && params.order_by.includes('-')) {
|
|
||||||
results.reverse();
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
results,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
wrapper.unmount();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('initially renders successfully', async () => {
|
test('initially renders successfully', async () => {
|
||||||
@@ -141,7 +146,7 @@ describe('<JobOutput />', () => {
|
|||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
jobEvents = wrapper.find('JobEvent');
|
jobEvents = wrapper.find('JobEvent');
|
||||||
expect(jobEvents.at(jobEvents.length - 1).prop('stdout')).toBe(
|
expect(jobEvents.at(jobEvents.length - 2).prop('stdout')).toBe(
|
||||||
'\r\nPLAY RECAP *********************************************************************\r\n\u001b[0;32mlocalhost\u001b[0m : \u001b[0;32mok=1 \u001b[0m changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 \r\n'
|
'\r\nPLAY RECAP *********************************************************************\r\n\u001b[0;32mlocalhost\u001b[0m : \u001b[0;32mok=1 \u001b[0m changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 \r\n'
|
||||||
);
|
);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
@@ -149,10 +154,10 @@ describe('<JobOutput />', () => {
|
|||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
jobEvents = wrapper.find('JobEvent');
|
jobEvents = wrapper.find('JobEvent');
|
||||||
expect(jobEvents.at(1).prop('stdout')).toBe(
|
expect(jobEvents.at(0).prop('stdout')).toBe(
|
||||||
'\u001b[0;32mok: [localhost] => (item=76) => {\u001b[0m\r\n\u001b[0;32m "msg": "This is a debug message: 76"\u001b[0m\r\n\u001b[0;32m}\u001b[0m'
|
'\u001b[0;32mok: [localhost] => (item=76) => {\u001b[0m\r\n\u001b[0;32m "msg": "This is a debug message: 76"\u001b[0m\r\n\u001b[0;32m}\u001b[0m'
|
||||||
);
|
);
|
||||||
expect(jobEvents.at(2).prop('stdout')).toBe(
|
expect(jobEvents.at(1).prop('stdout')).toBe(
|
||||||
'\u001b[0;32mok: [localhost] => (item=77) => {\u001b[0m\r\n\u001b[0;32m "msg": "This is a debug message: 77"\u001b[0m\r\n\u001b[0;32m}\u001b[0m'
|
'\u001b[0;32mok: [localhost] => (item=77) => {\u001b[0m\r\n\u001b[0;32m "msg": "This is a debug message: 77"\u001b[0m\r\n\u001b[0;32m}\u001b[0m'
|
||||||
);
|
);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
@@ -169,7 +174,7 @@ describe('<JobOutput />', () => {
|
|||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
jobEvents = wrapper.find('JobEvent');
|
jobEvents = wrapper.find('JobEvent');
|
||||||
expect(jobEvents.at(jobEvents.length - 1).prop('stdout')).toBe(
|
expect(jobEvents.at(jobEvents.length - 2).prop('stdout')).toBe(
|
||||||
'\r\nPLAY RECAP *********************************************************************\r\n\u001b[0;32mlocalhost\u001b[0m : \u001b[0;32mok=1 \u001b[0m changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 \r\n'
|
'\r\nPLAY RECAP *********************************************************************\r\n\u001b[0;32mlocalhost\u001b[0m : \u001b[0;32mok=1 \u001b[0m changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 \r\n'
|
||||||
);
|
);
|
||||||
Object.defineProperty(
|
Object.defineProperty(
|
||||||
@@ -266,11 +271,7 @@ describe('<JobOutput />', () => {
|
|||||||
wrapper = mountWithContexts(<JobOutput job={mockJob} />);
|
wrapper = mountWithContexts(<JobOutput job={mockJob} />);
|
||||||
});
|
});
|
||||||
await waitForElement(wrapper, 'JobEvent', el => el.length > 0);
|
await waitForElement(wrapper, 'JobEvent', el => el.length > 0);
|
||||||
JobsAPI.readEvents = jest.fn();
|
applyJobEventMock(mockFilteredJobEventsData);
|
||||||
JobsAPI.readEvents.mockClear();
|
|
||||||
JobsAPI.readEvents.mockResolvedValueOnce({
|
|
||||||
data: mockFilteredJobEventsData,
|
|
||||||
});
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper.find(searchTextInput).instance().value = '99';
|
wrapper.find(searchTextInput).instance().value = '99';
|
||||||
wrapper.find(searchTextInput).simulate('change');
|
wrapper.find(searchTextInput).simulate('change');
|
||||||
@@ -281,14 +282,13 @@ describe('<JobOutput />', () => {
|
|||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(JobsAPI.readEvents).toHaveBeenCalled();
|
expect(JobsAPI.readEvents).toHaveBeenCalled();
|
||||||
// TODO: Fix these assertions
|
const jobEvents = wrapper.find('JobEvent');
|
||||||
// const jobEvents = wrapper.find('JobEvent');
|
expect(jobEvents.at(0).prop('stdout')).toBe(
|
||||||
// expect(jobEvents.at(0).prop('stdout')).toBe(
|
'\u001b[0;32mok: [localhost] => (item=99) => {\u001b[0m\r\n\u001b[0;32m "msg": "This is a debug message: 99"\u001b[0m\r\n\u001b[0;32m}\u001b[0m'
|
||||||
// '\u001b[0;32mok: [localhost] => (item=99) => {\u001b[0m\r\n\u001b[0;32m "msg": "This is a debug message: 99"\u001b[0m\r\n\u001b[0;32m}\u001b[0m'
|
);
|
||||||
// );
|
expect(jobEvents.at(1).prop('stdout')).toBe(
|
||||||
// expect(jobEvents.at(1).prop('stdout')).toBe(
|
'\u001b[0;32mok: [localhost] => (item=199) => {\u001b[0m\r\n\u001b[0;32m "msg": "This is a debug message: 199"\u001b[0m\r\n\u001b[0;32m}\u001b[0m'
|
||||||
// '\u001b[0;32mok: [localhost] => (item=199) => {\u001b[0m\r\n\u001b[0;32m "msg": "This is a debug message: 199"\u001b[0m\r\n\u001b[0;32m}\u001b[0m'
|
);
|
||||||
// );
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should throw error', async () => {
|
test('should throw error', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user