From e0ee0b09dbf8234aebb38e234d1d8ff8f1a0e682 Mon Sep 17 00:00:00 2001 From: Tom Ratcliffe Date: Mon, 29 Apr 2024 13:10:43 +0100 Subject: [PATCH] Add test to check that a broken alertmanager will handle errors correctly --- .../alerting/unified/Silences.test.tsx | 21 +++++++++++++++++-- .../alerting/unified/mocks/alertmanagerApi.ts | 12 +++++++---- .../alerting/unified/mocks/datasources.ts | 5 +++++ .../alerting/unified/mocks/silences.ts | 8 ++++++- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/public/app/features/alerting/unified/Silences.test.tsx b/public/app/features/alerting/unified/Silences.test.tsx index 84c35a27d93..6552cdcd590 100644 --- a/public/app/features/alerting/unified/Silences.test.tsx +++ b/public/app/features/alerting/unified/Silences.test.tsx @@ -1,11 +1,15 @@ import React from 'react'; -import { render, waitFor, userEvent } from 'test/test-utils'; +import { render, waitFor, userEvent, screen } from 'test/test-utils'; import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector'; import { dateTime } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { config, locationService, setDataSourceSrv } from '@grafana/runtime'; import { setupMswServer } from 'app/features/alerting/unified/mockApi'; +import { + MOCK_DATASOURCE_UID_BROKEN_ALERTMANAGER, + MOCK_DATASOURCE_NAME_BROKEN_ALERTMANAGER, +} from 'app/features/alerting/unified/mocks/datasources'; import { waitForServerRequest } from 'app/features/alerting/unified/mocks/server/events'; import { silenceCreateHandler } from 'app/features/alerting/unified/mocks/silences'; import { MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; @@ -40,6 +44,11 @@ const dataSources = { name: 'Alertmanager', type: DataSourceType.Alertmanager, }), + [MOCK_DATASOURCE_NAME_BROKEN_ALERTMANAGER]: mockDataSource({ + uid: MOCK_DATASOURCE_UID_BROKEN_ALERTMANAGER, + name: MOCK_DATASOURCE_NAME_BROKEN_ALERTMANAGER, + type: DataSourceType.Alertmanager, + }), }; const ui = { @@ -100,6 +109,10 @@ const addAdditionalMatcher = async () => { setupMswServer(); +beforeEach(() => { + setupDataSources(dataSources.am, dataSources[MOCK_DATASOURCE_NAME_BROKEN_ALERTMANAGER]); +}); + describe('Silences', () => { beforeAll(resetMocks); afterEach(resetMocks); @@ -185,6 +198,11 @@ describe('Silences', () => { expect(ui.addSilenceButton.query()).not.toBeInTheDocument(); }); + + it('handles error case when broken alertmanager is used', async () => { + renderSilences(`/alerting/silences?alertmanager=${encodeURIComponent(MOCK_DATASOURCE_NAME_BROKEN_ALERTMANAGER)}`); + expect(await screen.findByText(/error loading silences/i)).toBeInTheDocument(); + }); }); describe('Silence create/edit', () => { @@ -194,7 +212,6 @@ describe('Silence create/edit', () => { beforeEach(() => { setUserLogged(true); - setupDataSources(dataSources.am); }); it('Should not render createdBy if user is logged in and has a name', async () => { diff --git a/public/app/features/alerting/unified/mocks/alertmanagerApi.ts b/public/app/features/alerting/unified/mocks/alertmanagerApi.ts index 9c30d8ef699..9083fd30a89 100644 --- a/public/app/features/alerting/unified/mocks/alertmanagerApi.ts +++ b/public/app/features/alerting/unified/mocks/alertmanagerApi.ts @@ -2,6 +2,7 @@ import { http, HttpResponse } from 'msw'; import { SetupServer } from 'msw/node'; import { MOCK_SILENCE_ID_EXISTING, mockAlertmanagerAlert } from 'app/features/alerting/unified/mocks'; +import { MOCK_DATASOURCE_UID_BROKEN_ALERTMANAGER } from 'app/features/alerting/unified/mocks/datasources'; import { AlertmanagerChoice, @@ -47,8 +48,11 @@ export function mockAlertmanagerConfigResponse( } export const alertmanagerAlertsListHandler = () => - http.get('/api/alertmanager/:datasourceUid/api/v2/alerts', () => - HttpResponse.json([ + http.get<{ datasourceUid: string }>('/api/alertmanager/:datasourceUid/api/v2/alerts', ({ params }) => { + if (params.datasourceUid === MOCK_DATASOURCE_UID_BROKEN_ALERTMANAGER) { + return HttpResponse.json({ traceId: '' }, { status: 502 }); + } + return HttpResponse.json([ mockAlertmanagerAlert({ labels: { foo: 'bar', buzz: 'bazz' }, status: { state: AlertState.Suppressed, silencedBy: [MOCK_SILENCE_ID_EXISTING], inhibitedBy: [] }, @@ -57,5 +61,5 @@ export const alertmanagerAlertsListHandler = () => labels: { foo: 'bar', buzz: 'bazz' }, status: { state: AlertState.Suppressed, silencedBy: [MOCK_SILENCE_ID_EXISTING], inhibitedBy: [] }, }), - ]) - ); + ]); + }); diff --git a/public/app/features/alerting/unified/mocks/datasources.ts b/public/app/features/alerting/unified/mocks/datasources.ts index 0ff5d12bf65..04f579a7c24 100644 --- a/public/app/features/alerting/unified/mocks/datasources.ts +++ b/public/app/features/alerting/unified/mocks/datasources.ts @@ -3,3 +3,8 @@ import { HttpResponse, http } from 'msw'; // TODO: Add more accurate endpoint responses as tests require export const datasourceBuildInfoHandler = () => http.get('/api/datasources/proxy/uid/:datasourceUid/api/v1/status/buildinfo', () => HttpResponse.json({})); + +/** UID of the alertmanager that is expected to be broken in tests */ +export const MOCK_DATASOURCE_UID_BROKEN_ALERTMANAGER = 'FwkfQfEmYlAthB'; +/** Display name of the alertmanager that is expected to be broken in tests */ +export const MOCK_DATASOURCE_NAME_BROKEN_ALERTMANAGER = 'broken alertmanager'; diff --git a/public/app/features/alerting/unified/mocks/silences.ts b/public/app/features/alerting/unified/mocks/silences.ts index 75bf988ed28..8ef9944d83f 100644 --- a/public/app/features/alerting/unified/mocks/silences.ts +++ b/public/app/features/alerting/unified/mocks/silences.ts @@ -1,13 +1,19 @@ import { HttpResponse, http } from 'msw'; import { mockSilences } from 'app/features/alerting/unified/mocks'; +import { MOCK_DATASOURCE_UID_BROKEN_ALERTMANAGER } from 'app/features/alerting/unified/mocks/datasources'; ////////////// // Silences // ////////////// export const silencesListHandler = (silences = mockSilences) => - http.get('/api/alertmanager/:datasourceUid/api/v2/silences', () => HttpResponse.json(silences)); + http.get<{ datasourceUid: string }>('/api/alertmanager/:datasourceUid/api/v2/silences', ({ params }) => { + if (params.datasourceUid === MOCK_DATASOURCE_UID_BROKEN_ALERTMANAGER) { + return HttpResponse.json({ traceId: '' }, { status: 502 }); + } + return HttpResponse.json(silences); + }); export const silenceGetHandler = () => http.get<{ uuid: string }>('/api/alertmanager/:datasourceUid/api/v2/silence/:uuid', ({ params }) => {