[Synthetics] Disable test now for private location (#149585)

Co-authored-by: florent-leborgne <florent.leborgne@elastic.co>
Fixes https://github.com/elastic/kibana/issues/137473
This commit is contained in:
Shahzad 2023-01-30 16:04:02 +01:00 committed by GitHub
parent a16806d90d
commit 15ddb87cdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 73 additions and 33 deletions

View file

@ -56,9 +56,7 @@ journey(`TestNowMode`, async ({ page, params }) => {
type: 'http',
urls: 'https://www.google.com',
custom_heartbeat_id: 'b9d9e146-746f-427f-bbf5-6e786b5b4e73',
locations: [
{ id: 'Test private location', label: 'Test private location', isServiceManaged: true },
],
locations: [{ id: 'us_central_qa', label: 'US Central QA', isServiceManaged: true }],
});
await services.addTestSummaryDocument({ timestamp: firstCheckTime });
});
@ -85,7 +83,7 @@ journey(`TestNowMode`, async ({ page, params }) => {
await services.addTestSummaryDocument({ testRunId });
await page.waitForSelector('text=Completed');
await page.waitForSelector('text=Took 155 ms');
await page.waitForSelector('text=Test private location');
await page.waitForSelector('text=US Central QA');
});
step('Displays data in expanded row', async () => {
@ -104,9 +102,7 @@ journey(`TestNowMode`, async ({ page, params }) => {
'source.inline.script':
"step('Go to https://www.google.com', async () => {\n await page.goto('https://www.google.com');\n});\n\nstep('Go to https://www.google.com', async () => {\n await page.goto('https://www.google.com');\n});",
urls: 'https://www.google.com',
locations: [
{ id: 'Test private location', label: 'Test private location', isServiceManaged: true },
],
locations: [{ id: 'us_central_qa', label: 'US Central QA', isServiceManaged: true }],
});
await page.click(byTestId('syntheticsMonitorManagementTab'));
@ -132,7 +128,7 @@ journey(`TestNowMode`, async ({ page, params }) => {
await page.waitForTimeout(1000);
await services.addTestSummaryDocument({ testRunId, docType: 'journeyStart' });
await page.waitForTimeout(1000);
await page.waitForSelector('text=Test private location');
await page.waitForSelector('text=US Central QA');
await page.waitForSelector('text=IN PROGRESS');
});

View file

@ -31,6 +31,7 @@ export const RunTestButton = () => {
setInProgress(true);
setTestRun({
id: uuidv4(),
name: config.name,
monitor: format(config) as MonitorFieldsType,
});
}
@ -80,6 +81,7 @@ export const RunTestButton = () => {
errors={data?.errors ?? []}
isPushing={Boolean(isPushing)}
testRun={testRun}
name={testRun.name}
inProgress={inProgress}
onClose={() => {
setTestRun(undefined);
@ -125,10 +127,10 @@ export const TEST_SCHEDULED_LABEL = i18n.translate(
}
);
const PRIVATE_AVAILABLE_LABEL = i18n.translate(
'xpack.synthetics.monitorList.testNow.available.private',
export const PRIVATE_AVAILABLE_LABEL = i18n.translate(
'xpack.synthetics.app.testNow.available.private',
{
defaultMessage: `You can't currently test monitors running on private locations on demand.`,
defaultMessage: `You can't manually start tests on a private location.`,
}
);

View file

@ -38,7 +38,9 @@ export const RunTestManually = () => {
isLoading={!Boolean(monitor) || testInProgress}
onClick={() => {
if (monitor) {
dispatch(manualTestMonitorAction.get(monitor.config_id));
dispatch(
manualTestMonitorAction.get({ configId: monitor.config_id, name: monitor.name })
);
}
}}
>

View file

@ -13,10 +13,13 @@ import {
useEuiShadow,
EuiPanel,
EuiLoadingSpinner,
EuiContextMenuPanelItemDescriptor,
EuiToolTip,
} from '@elastic/eui';
import { FETCH_STATUS } from '@kbn/observability-plugin/public';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import { PRIVATE_AVAILABLE_LABEL } from '../../../monitor_add_edit/form/run_test_btn';
import {
manualTestMonitorAction,
manualTestRunInProgressSelector,
@ -98,7 +101,10 @@ export function ActionsPopover({
}: Props) {
const euiShadow = useEuiShadow('l');
const dispatch = useDispatch();
const locationName = useLocationName({ locationId: monitor.location.id });
const location = useLocationName({ locationId: monitor.location.id });
const locationName = location?.label || monitor.location.id;
const isPrivateLocation = !Boolean(location?.isServiceManaged);
const detailUrl = useMonitorDetailLocator({
configId: monitor.configId,
@ -160,7 +166,7 @@ export function ActionsPopover({
const alertLoading = alertStatus(monitor.configId) === FETCH_STATUS.LOADING;
let popoverItems = [
let popoverItems: EuiContextMenuPanelItemDescriptor[] = [
{
name: actionsMenuGoToMonitorName,
icon: 'sortRight',
@ -168,11 +174,17 @@ export function ActionsPopover({
},
quickInspectPopoverItem,
{
name: runTestManually,
name: isPrivateLocation ? (
<EuiToolTip content={PRIVATE_AVAILABLE_LABEL}>
<span>{runTestManually}</span>
</EuiToolTip>
) : (
runTestManually
),
icon: 'beaker',
disabled: testInProgress,
disabled: testInProgress || isPrivateLocation,
onClick: () => {
dispatch(manualTestMonitorAction.get(monitor.configId));
dispatch(manualTestMonitorAction.get({ configId: monitor.configId, name: monitor.name }));
dispatch(setFlyoutConfig(null));
setIsPopoverOpen(false);
},

View file

@ -60,7 +60,8 @@ export const MetricItem = ({
}) => {
const [isMouseOver, setIsMouseOver] = useState(false);
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const locationName = useLocationName({ locationId: monitor.location?.id });
const locationName =
useLocationName({ locationId: monitor.location?.id })?.label || monitor.location?.id;
const { status, timestamp, ping, configIdByLocation } = useStatusByLocationOverview(
monitor.configId,
locationName

View file

@ -25,10 +25,12 @@ import { TestNowMode } from './test_now_mode';
export interface TestRun {
id: string;
name: string;
monitor: MonitorFields;
}
export function TestNowModeFlyout({
name,
testRun,
onClose,
onDone,
@ -37,6 +39,7 @@ export function TestNowModeFlyout({
errors,
serviceError,
}: {
name: string;
serviceError?: Error;
errors: ServiceLocationErrors;
testRun?: TestRun;
@ -56,7 +59,9 @@ export function TestNowModeFlyout({
>
<EuiFlyoutHeader>
<EuiTitle size="m">
<h2>{TEST_RESULTS}</h2>
<h2>
{name}-{TEST_RESULTS}
</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>

View file

@ -61,9 +61,14 @@ export function TestNowModeFlyoutContainer() {
<TestNowModeFlyout
testRun={
flyoutOpenTestRun?.testRunId && flyoutOpenTestRun?.monitor
? { id: flyoutOpenTestRun.testRunId, monitor: flyoutOpenTestRun.monitor }
? {
id: flyoutOpenTestRun.testRunId,
monitor: flyoutOpenTestRun.monitor,
name: flyoutOpenTestRun.name,
}
: undefined
}
name={flyoutOpenTestRun.name}
inProgress={
flyoutOpenTestRun.status === 'in-progress' || flyoutOpenTestRun.status === 'loading'
}

View file

@ -9,7 +9,7 @@ import { renderHook } from '@testing-library/react-hooks';
import { useLocationName } from './use_location_name';
import { WrappedHelper } from '../utils/testing';
describe('useMonitorListFilters', () => {
describe('useLocationName', () => {
beforeEach(() => {
jest.clearAllMocks();
});
@ -51,7 +51,14 @@ describe('useMonitorListFilters', () => {
}),
{ wrapper: WrapperWithState }
);
expect(result.current).toEqual('US Central');
expect(result.current).toEqual({
geo: { lat: 41.25, lon: -95.86 },
id: 'us_central',
isServiceManaged: true,
label: 'US Central',
status: 'ga',
url: 'mockUrl',
});
});
it('returns the location id if matching location cannot be found', () => {
@ -91,6 +98,6 @@ describe('useMonitorListFilters', () => {
}),
{ wrapper: WrapperWithState }
);
expect(result.current).toEqual('us_west');
expect(result.current).toEqual(undefined);
});
});

View file

@ -22,7 +22,7 @@ export function useLocationName({ locationId }: { locationId: string }) {
if (!locationsLoaded) {
return undefined;
} else {
return locations.find((location) => location.id === locationId)?.label || locationId;
return locations.find((location) => location.id === locationId);
}
}, [locationsLoaded, locations, locationId]);
}

View file

@ -13,9 +13,10 @@ import { createAsyncAction } from '../utils/actions';
export const toggleTestNowFlyoutAction = createAction<string>('TOGGLE TEST NOW FLYOUT ACTION');
export const hideTestNowFlyoutAction = createAction('HIDE ALL TEST NOW FLYOUT ACTION');
export const manualTestMonitorAction = createAsyncAction<string, TestNowResponse | undefined>(
'TEST_NOW_MONITOR_ACTION'
);
export const manualTestMonitorAction = createAsyncAction<
{ configId: string; name: string },
TestNowResponse | undefined
>('TEST_NOW_MONITOR_ACTION');
export const manualTestRunUpdateAction = createAction<
Partial<ManualTestRun> & { testRunId: string }

View file

@ -10,9 +10,12 @@ import { TestNowResponse } from '../../../../../common/types';
import { apiService } from '../../../../utils/api_service';
import { API_URLS } from '../../../../../common/constants';
export const triggerTestNowMonitor = async (
configId: string
): Promise<TestNowResponse | undefined> => {
export const triggerTestNowMonitor = async ({
configId,
}: {
configId: string;
name: string;
}): Promise<TestNowResponse | undefined> => {
return await apiService.get(API_URLS.TRIGGER_MONITOR + `/${configId}`);
};

View file

@ -33,6 +33,7 @@ export enum TestRunStatus {
export interface ManualTestRun {
configId: string;
name: string;
testRunId?: string;
status: TestRunStatus;
schedule: SyntheticsMonitorSchedule;
@ -53,7 +54,10 @@ export const manualTestRunsReducer = createReducer(initialState, (builder) => {
builder
.addCase(
String(manualTestMonitorAction.get),
(state: WritableDraft<ManualTestRunsState>, action: PayloadAction<string>) => {
(
state: WritableDraft<ManualTestRunsState>,
action: PayloadAction<{ configId: string; name: string }>
) => {
state = Object.values(state).reduce((acc, curr) => {
acc[curr.configId] = {
...curr,
@ -63,8 +67,9 @@ export const manualTestRunsReducer = createReducer(initialState, (builder) => {
return acc;
}, state);
state[action.payload] = {
configId: action.payload,
state[action.payload.configId] = {
configId: action.payload.configId,
name: action.payload.name,
status: TestRunStatus.LOADING,
schedule: { unit: ScheduleUnit.MINUTES, number: '3' },
locations: [],
@ -84,6 +89,7 @@ export const manualTestRunsReducer = createReducer(initialState, (builder) => {
locations: payload.locations,
isTestNowFlyoutOpen: true,
monitor: payload.monitor,
name: payload.monitor.name,
};
}
)