[Synthetics] Limit retires for data for manual test run (#157148)

Co-authored-by: Abdul Zahid <awahab07@yahoo.com>
This commit is contained in:
Shahzad 2023-05-09 21:56:18 +02:00 committed by GitHub
parent a5ac5b62b6
commit 335379ac4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 132 additions and 22 deletions

View file

@ -19,6 +19,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import styled from 'styled-components';
import { FAILED_TO_SCHEDULE } from '../manual_test_run_mode/browser_test_results';
import { BrowserStepsList } from '../../common/monitor_test_result/browser_steps_list';
import {
CheckGroupResult,
@ -34,11 +35,16 @@ interface Props {
}
export const BrowserTestRunResult = ({ expectPings, onDone, testRunId }: Props) => {
const { euiTheme } = useEuiTheme();
const { summariesLoading, expectedSummariesLoaded, stepLoadingInProgress, checkGroupResults } =
useBrowserRunOnceMonitors({
testRunId,
expectSummaryDocs: expectPings,
});
const {
retriesExceeded,
summariesLoading,
expectedSummariesLoaded,
stepLoadingInProgress,
checkGroupResults,
} = useBrowserRunOnceMonitors({
testRunId,
expectSummaryDocs: expectPings,
});
useEffect(() => {
if (expectedSummariesLoaded) {
@ -46,6 +52,10 @@ export const BrowserTestRunResult = ({ expectPings, onDone, testRunId }: Props)
}
}, [onDone, expectedSummariesLoaded, testRunId]);
if (retriesExceeded) {
return <EuiCallOut title={FAILED_TO_SCHEDULE} color="danger" iconType="alert" />;
}
return (
<>
{checkGroupResults.map((checkGroupResult) => {

View file

@ -63,6 +63,8 @@ export const useBrowserEsResults = ({
);
};
const MAX_RETRIES = 25;
export const useBrowserRunOnceMonitors = ({
testRunId,
skipDetails = false,
@ -72,7 +74,9 @@ export const useBrowserRunOnceMonitors = ({
skipDetails?: boolean;
expectSummaryDocs: number;
}) => {
const { refreshTimer, lastRefresh } = useTickTick(5 * 1000);
const { refreshTimer, lastRefresh, clearTicks } = useTickTick(5 * 1000);
const [numberOfRetries, setNumberOfRetries] = useState(0);
const [checkGroupResults, setCheckGroupResults] = useState<CheckGroupResult[]>(() => {
return new Array(expectSummaryDocs)
@ -139,6 +143,14 @@ export const useBrowserRunOnceMonitors = ({
}
replaceCheckGroupResults(checkGroups);
} else {
setNumberOfRetries((prevState) => {
const attempts = prevState + 1;
if (attempts > MAX_RETRIES) {
clearTicks();
}
return attempts;
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [expectSummaryDocs, data, refreshTimer]);
@ -230,6 +242,7 @@ export const useBrowserRunOnceMonitors = ({
return {
data,
retriesExceeded: numberOfRetries > MAX_RETRIES,
summariesLoading,
stepLoadingInProgress,
expectedSummariesLoaded:

View file

@ -5,13 +5,15 @@
* 2.0.
*/
import { useMemo, useRef } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { createEsParams, useEsSearch } from '@kbn/observability-plugin/public';
import { SUMMARY_FILTER } from '../../../../../../common/constants/client_defaults';
import { Ping } from '../../../../../../common/runtime_types';
import { SYNTHETICS_INDEX_PATTERN } from '../../../../../../common/constants';
import { useTickTick } from './use_tick_tick';
const MAX_RETRIES = 50;
export const useSimpleRunOnceMonitors = ({
expectSummaryDocs,
testRunId,
@ -20,6 +22,7 @@ export const useSimpleRunOnceMonitors = ({
testRunId: string;
}) => {
const { refreshTimer, lastRefresh } = useTickTick(2 * 1000);
const [numberOfRetries, setNumberOfRetries] = useState(0);
const { data, loading } = useEsSearch(
createEsParams({
@ -54,6 +57,14 @@ export const useSimpleRunOnceMonitors = ({
time: Date.now(),
});
useEffect(() => {
const docs = data?.hits.hits ?? [];
if (docs.length === 0) {
setNumberOfRetries((prevState) => prevState + 1);
}
}, [data]);
return useMemo(() => {
const docs = data?.hits.hits ?? [];
@ -85,10 +96,11 @@ export const useSimpleRunOnceMonitors = ({
}
return {
retriesExceeded: numberOfRetries > MAX_RETRIES,
data,
loading,
summaryDocs: null,
lastUpdated: lastUpdated.current.time,
};
}, [expectSummaryDocs, data, loading, refreshTimer]);
}, [data, numberOfRetries, loading, expectSummaryDocs, refreshTimer]);
};

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { useEffect, useState } from 'react';
import { useEffect, useState, useCallback } from 'react';
export function useTickTick(interval?: number) {
const [nextTick, setNextTick] = useState(Date.now());
@ -16,11 +16,15 @@ export function useTickTick(interval?: number) {
}, interval ?? 5 * 1000)
);
useEffect(() => {
return () => {
clearInterval(tickTick);
};
const clear = useCallback(() => {
clearInterval(tickTick);
}, [tickTick]);
return { refreshTimer: tickTick, lastRefresh: nextTick };
useEffect(() => {
return () => {
clear();
};
}, [clear]);
return { refreshTimer: tickTick, lastRefresh: nextTick, clearTicks: clear };
}

View file

@ -7,20 +7,56 @@
import React, { Fragment, useEffect } from 'react';
import { i18n } from '@kbn/i18n';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { FormattedMessage } from '@kbn/i18n-react';
import { kibanaService } from '../../../../../utils/kibana_service';
import { useBrowserRunOnceMonitors } from '../hooks/use_browser_run_once_monitors';
interface Props {
name: string;
testRunId: string;
expectPings: number;
onDone: (testRunId: string) => void;
onProgress: (message: string) => void;
}
export const BrowserTestRunResult = ({ expectPings, onDone, testRunId, onProgress }: Props) => {
const { summariesLoading, expectedSummariesLoaded, stepLoadingInProgress, checkGroupResults } =
useBrowserRunOnceMonitors({
testRunId,
expectSummaryDocs: expectPings,
});
export const BrowserTestRunResult = ({
name,
expectPings,
onDone,
testRunId,
onProgress,
}: Props) => {
const {
summariesLoading,
expectedSummariesLoaded,
stepLoadingInProgress,
checkGroupResults,
retriesExceeded,
} = useBrowserRunOnceMonitors({
testRunId,
expectSummaryDocs: expectPings,
});
useEffect(() => {
if (retriesExceeded) {
kibanaService.toasts.addDanger(
{
text: FAILED_TO_SCHEDULE,
title: toMountPoint(
<FormattedMessage
id="xpack.synthetics.manualTestRun.failedTest.name"
defaultMessage="Manual test run failed for {name}"
values={{ name }}
/>
),
},
{
toastLifeTimeMs: 10000,
}
);
onDone(testRunId);
}
}, [name, onDone, retriesExceeded, testRunId]);
useEffect(() => {
if (expectedSummariesLoaded) {
@ -76,6 +112,13 @@ const FAILED_TO_RUN = i18n.translate('xpack.synthetics.monitorManagement.failedR
defaultMessage: 'Failed to run steps',
});
export const FAILED_TO_SCHEDULE = i18n.translate(
'xpack.synthetics.monitorManagement.failedScheduling',
{
defaultMessage: 'Failed to get any results back for manual test run.',
}
);
const LOADING_STEPS = i18n.translate('xpack.synthetics.monitorManagement.loadingSteps', {
defaultMessage: 'Loading steps...',
});

View file

@ -36,6 +36,7 @@ export function ManualTestRunMode({
<Fragment key={manualTestRun.testRunId}>
{isBrowserMonitor ? (
<BrowserTestRunResult
name={manualTestRun.monitor.name}
expectPings={expectPings}
onDone={onDone}
testRunId={manualTestRun.testRunId}
@ -43,6 +44,7 @@ export function ManualTestRunMode({
/>
) : (
<SimpleTestResults
name={manualTestRun.monitor.name}
expectPings={expectPings}
onDone={onDone}
testRunId={manualTestRun.testRunId}

View file

@ -5,19 +5,45 @@
* 2.0.
*/
import React, { useEffect } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { FAILED_TO_SCHEDULE } from './browser_test_results';
import { kibanaService } from '../../../../../utils/kibana_service';
import { useSimpleRunOnceMonitors } from '../hooks/use_simple_run_once_monitors';
interface Props {
name: string;
testRunId: string;
expectPings: number;
onDone: (testRunId: string) => void;
}
export function SimpleTestResults({ testRunId, expectPings, onDone }: Props) {
const { summaryDocs } = useSimpleRunOnceMonitors({
export function SimpleTestResults({ name, testRunId, expectPings, onDone }: Props) {
const { summaryDocs, retriesExceeded } = useSimpleRunOnceMonitors({
testRunId,
expectSummaryDocs: expectPings,
});
useEffect(() => {
if (retriesExceeded) {
kibanaService.toasts.addDanger(
{
text: FAILED_TO_SCHEDULE,
title: toMountPoint(
<FormattedMessage
id="xpack.synthetics.manualTestRun.failedTest.name"
defaultMessage="Manual test run failed for {name}"
values={{ name }}
/>
),
},
{
toastLifeTimeMs: 10000,
}
);
onDone(testRunId);
}
}, [name, onDone, retriesExceeded, testRunId]);
useEffect(() => {
if (summaryDocs) {
if (summaryDocs.length >= expectPings) {