Alerting: Remove manual feature discovery mocking (#96243)

* Update mock methods to remove discovery API

* Update tests to remove mock discovery API

* Remove ref in TESTING.md

* Fix other references to 'mimir'
This commit is contained in:
Tom Ratcliffe
2024-12-12 19:11:04 +02:00
committed by GitHub
parent ebfa06e040
commit 482af91782
17 changed files with 40 additions and 62 deletions
@@ -3,6 +3,7 @@ import { FormProvider, useForm } from 'react-hook-form';
import { getWrapper, render, waitFor, waitForElementToBeRemoved, within } from 'test/test-utils';
import { byRole, byTestId, byText } from 'testing-library-selector';
import { MIMIR_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { RuleWithLocation } from 'app/types/unified-alerting';
import { AccessControlAction } from '../../../types';
@@ -15,7 +16,7 @@ import {
import { CloneRuleEditor, cloneRuleDefinition } from './CloneRuleEditor';
import { ExpressionEditorProps } from './components/rule-editor/ExpressionEditor';
import { mockFeatureDiscoveryApi, setupMswServer } from './mockApi';
import { setupMswServer } from './mockApi';
import {
grantUserPermissions,
mockDataSource,
@@ -27,7 +28,6 @@ import { grafanaRulerRule } from './mocks/grafanaRulerApi';
import { mockRulerRulesApiResponse, mockRulerRulesGroupApiResponse } from './mocks/rulerApi';
import { AlertingQueryRunner } from './state/AlertingQueryRunner';
import { setupDataSources } from './testSetup/datasources';
import { buildInfoResponse } from './testSetup/featureDiscovery';
import { RuleFormValues } from './types/rule-form';
import { Annotation } from './utils/constants';
import { getDefaultFormValues } from './utils/rule-form';
@@ -107,10 +107,10 @@ describe('CloneRuleEditor', function () {
it('should populate form values from the existing alert rule', async function () {
const dsSettings = mockDataSource({
name: 'my-prom-ds',
uid: 'my-prom-ds',
uid: MIMIR_DATASOURCE_UID,
});
setupDataSources(dsSettings);
mockFeatureDiscoveryApi(server).discoverDsFeatures(dsSettings, buildInfoResponse.mimir);
const originRule = mockRulerAlertingRule({
for: '1m',
alert: 'First Ruler Rule',
@@ -119,11 +119,11 @@ describe('CloneRuleEditor', function () {
annotations: { [Annotation.summary]: 'This is a very important alert rule' },
});
mockRulerRulesApiResponse(server, 'my-prom-ds', {
mockRulerRulesApiResponse(server, MIMIR_DATASOURCE_UID, {
'namespace-one': [{ name: 'group1', interval: '20s', rules: [originRule] }],
});
mockRulerRulesGroupApiResponse(server, 'my-prom-ds', 'namespace-one', 'group1', {
mockRulerRulesGroupApiResponse(server, MIMIR_DATASOURCE_UID, 'namespace-one', 'group1', {
name: 'group1',
interval: '20s',
rules: [originRule],
@@ -11,6 +11,7 @@ import {
makeAllAlertmanagerConfigFetchFail,
makeAllK8sGetEndpointsFail,
} from 'app/features/alerting/unified/mocks/server/configure';
import { MIMIR_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import {
getAlertmanagerConfig,
setAlertmanagerConfig,
@@ -97,9 +98,9 @@ const dataSources = {
},
}),
mimir: mockDataSource<AlertManagerDataSourceJsonData>({
name: 'mimir',
name: 'MimirAlertmanager',
type: DataSourceType.Alertmanager,
uid: 'mimir',
uid: MIMIR_DATASOURCE_UID,
jsonData: {
implementation: AlertManagerImplementation.mimir,
},
@@ -4,6 +4,7 @@ import { render, screen } from 'test/test-utils';
import { contextSrv } from 'app/core/services/context_srv';
import { setFolderResponse } from 'app/features/alerting/unified/mocks/server/configure';
import { MIMIR_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { captureRequests } from 'app/features/alerting/unified/mocks/server/events';
import { DashboardSearchItemType } from 'app/features/search/types';
@@ -75,7 +76,7 @@ describe('RuleEditor grafana managed rules', () => {
const dataSources = {
default: mockDataSource({
uid: 'mimir',
uid: MIMIR_DATASOURCE_UID,
type: 'prometheus',
name: 'Mimir',
isDefault: true,
@@ -5,13 +5,13 @@ import { screen } from 'test/test-utils';
import { byRole } from 'testing-library-selector';
import { contextSrv } from 'app/core/services/context_srv';
import { mockFeatureDiscoveryApi, setupMswServer } from 'app/features/alerting/unified/mockApi';
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import { PROMETHEUS_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { AccessControlAction } from 'app/types';
import { grantUserPermissions, mockDataSource } from './mocks';
import { grafanaRulerGroup } from './mocks/grafanaRulerApi';
import { setupDataSources } from './testSetup/datasources';
import { buildInfoResponse } from './testSetup/featureDiscovery';
jest.mock('app/core/components/AppChrome/AppChromeUpdate', () => ({
AppChromeUpdate: ({ actions }: { actions: React.ReactNode }) => <div>{actions}</div>,
@@ -19,7 +19,7 @@ jest.mock('app/core/components/AppChrome/AppChromeUpdate', () => ({
jest.setTimeout(60 * 1000);
const server = setupMswServer();
setupMswServer();
describe('RuleEditor grafana managed rules', () => {
beforeEach(() => {
@@ -47,6 +47,7 @@ describe('RuleEditor grafana managed rules', () => {
{
type: 'prometheus',
name: 'Prom',
uid: PROMETHEUS_DATASOURCE_UID,
isDefault: true,
},
{ alerting: false }
@@ -54,7 +55,6 @@ describe('RuleEditor grafana managed rules', () => {
};
setupDataSources(dataSources.default);
mockFeatureDiscoveryApi(server).discoverDsFeatures(dataSources.default, buildInfoResponse.mimir);
const { user } = renderRuleEditor();
@@ -13,8 +13,6 @@ If you don't find a helper for an endpoint you're looking for, please add it.
### Common API requests
- `/buildinfo`
Use `mockFeatureDiscoveryApi` and `buildInfoResponse` object to mock the endpoint response according to your needs
- `api/v1/eval` used by AlertingQueryRunner
Use `mockApi.eval` Usually an empty response should do the trick
@@ -11,7 +11,7 @@ exports[`RuleEditor cloud can create a new cloud alert 1`] = `
],
],
"method": "GET",
"url": "https://mimir.local:9000/api/v1/status/buildinfo",
"url": "http://localhost/api/datasources/proxy/uid/mimir/api/v1/status/buildinfo",
},
{
"body": "",
@@ -11,7 +11,7 @@ exports[`RuleEditor recording rules can create a new cloud recording rule 1`] =
],
],
"method": "GET",
"url": "https://mimir.local:9000/api/v1/status/buildinfo",
"url": "http://localhost/api/datasources/proxy/uid/mimir/api/v1/status/buildinfo",
},
{
"body": "",
@@ -3,6 +3,7 @@ import { ComponentProps, ReactNode } from 'react';
import { render, screen, userEvent, waitFor, waitForElementToBeRemoved, within } from 'test/test-utils';
import { selectors } from '@grafana/e2e-selectors';
import { MIMIR_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { flushMicrotasks, testWithFeatureToggles } from 'app/features/alerting/unified/test/test-utils';
import { K8sAnnotations } from 'app/features/alerting/unified/utils/k8s/constants';
import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types';
@@ -16,7 +17,7 @@ import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasourc
import { ContactPoint } from './ContactPoint';
import { ContactPointsPageContents } from './ContactPoints';
import setupMimirFlavoredServer, { MIMIR_DATASOURCE_UID } from './__mocks__/mimirFlavoredServer';
import setupMimirFlavoredServer from './__mocks__/mimirFlavoredServer';
import setupVanillaAlertmanagerFlavoredServer, {
VANILLA_ALERTMANAGER_DATASOURCE_UID,
} from './__mocks__/vanillaAlertmanagerServer';
@@ -1,13 +1,14 @@
import { HttpResponse, http } from 'msw';
import { SetupServer } from 'msw/node';
import { MIMIR_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
import mimirAlertmanagerMock from './alertmanager.mimir.config.mock.json';
// this one emulates a mimir server setup
export const MIMIR_DATASOURCE_UID = 'mimir';
/** @deprecated Move to main alerting MSW server instead */
export default (server: SetupServer) => {
server.use(
http.get(`/api/alertmanager/${MIMIR_DATASOURCE_UID}/config/api/v1/alerts`, () =>
@@ -8,14 +8,14 @@ import { byRole } from 'testing-library-selector';
import { config } from '@grafana/runtime';
import { contextSrv } from 'app/core/services/context_srv';
import RuleEditor from 'app/features/alerting/unified/RuleEditor';
import { mockFeatureDiscoveryApi, setupMswServer } from 'app/features/alerting/unified/mockApi';
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import { grantUserPermissions, mockDataSource } from 'app/features/alerting/unified/mocks';
import { setAlertmanagerChoices } from 'app/features/alerting/unified/mocks/server/configure';
import { PROMETHEUS_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { captureRequests, serializeRequests } from 'app/features/alerting/unified/mocks/server/events';
import { FOLDER_TITLE_HAPPY_PATH } from 'app/features/alerting/unified/mocks/server/handlers/search';
import { AlertmanagerProvider } from 'app/features/alerting/unified/state/AlertmanagerContext';
import { testWithFeatureToggles } from 'app/features/alerting/unified/test/test-utils';
import { buildInfoResponse } from 'app/features/alerting/unified/testSetup/featureDiscovery';
import { DataSourceType, GRAFANA_DATASOURCE_NAME } from 'app/features/alerting/unified/utils/datasource';
import { AlertmanagerChoice } from 'app/plugins/datasource/alertmanager/types';
import { AccessControlAction } from 'app/types';
@@ -29,13 +29,14 @@ jest.mock('app/core/components/AppChrome/AppChromeUpdate', () => ({
jest.setTimeout(60 * 1000);
const server = setupMswServer();
setupMswServer();
const dataSources = {
default: mockDataSource(
{
type: 'prometheus',
name: 'Prom',
uid: PROMETHEUS_DATASOURCE_UID,
isDefault: true,
},
{ alerting: false }
@@ -78,8 +79,6 @@ describe('Can create a new grafana managed alert using simplified routing', () =
AccessControlAction.AlertingNotificationsRead,
AccessControlAction.AlertingNotificationsWrite,
]);
mockFeatureDiscoveryApi(server).discoverDsFeatures(dataSources.default, buildInfoResponse.mimir);
});
it('cannot create new grafana managed alert when using simplified routing and not selecting a contact point', async () => {
@@ -5,7 +5,7 @@ import { config, locationService, setPluginLinksHook } from '@grafana/runtime';
import { interceptLinkClicks } from 'app/core/navigation/patch/interceptLinkClicks';
import { contextSrv } from 'app/core/services/context_srv';
import { RuleActionsButtons } from 'app/features/alerting/unified/components/rules/RuleActionsButtons';
import { mockFeatureDiscoveryApi, setupMswServer } from 'app/features/alerting/unified/mockApi';
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import {
getCloudRule,
getGrafanaRule,
@@ -14,19 +14,17 @@ import {
mockGrafanaRulerRule,
mockPromAlertingRule,
} from 'app/features/alerting/unified/mocks';
import { MIMIR_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { AccessControlAction } from 'app/types';
import { PromAlertingRuleState } from 'app/types/unified-alerting-dto';
import { setupDataSources } from '../../testSetup/datasources';
import { buildInfoResponse } from '../../testSetup/featureDiscovery';
import { fromCombinedRule, stringifyIdentifier } from '../../utils/rule-id';
const server = setupMswServer();
setupMswServer();
jest.mock('app/core/services/context_srv');
const mockContextSrv = jest.mocked(contextSrv);
// const locationPushSpy = jest.spyOn(locationService, 'push');
const ui = {
detailsButton: byRole('link', { name: /View/ }),
menu: byRole('menu'),
@@ -66,7 +64,7 @@ setPluginLinksHook(() => ({
isLoading: false,
}));
const mimirDs = mockDataSource({ uid: 'mimir', name: 'Mimir' });
const mimirDs = mockDataSource({ uid: MIMIR_DATASOURCE_UID, name: 'Mimir' });
const prometheusDs = mockDataSource({ uid: 'prometheus', name: 'Prometheus' });
setupDataSources(mimirDs, prometheusDs);
@@ -106,7 +104,6 @@ describe('RuleActionsButtons', () => {
const user = userEvent.setup();
grantAllPermissions();
const mockRule = getCloudRule(undefined, { rulesSource: mimirDs });
mockFeatureDiscoveryApi(server).discoverDsFeatures(mimirDs, buildInfoResponse.mimir);
render(<RuleActionsButtons rule={mockRule} rulesSource={mimirDs} />);
@@ -11,7 +11,7 @@ exports[`reorder rules for rule group should correctly reorder rules 1`] = `
],
],
"method": "GET",
"url": "https://mimir.local:9000/api/v1/status/buildinfo",
"url": "http://localhost/api/datasources/proxy/uid/mimir/api/v1/status/buildinfo",
},
{
"body": "",
@@ -89,7 +89,7 @@ exports[`useUpdateRuleGroupConfiguration should be able to move a Data Source ma
],
],
"method": "GET",
"url": "https://mimir.local:9000/api/v1/status/buildinfo",
"url": "http://localhost/api/datasources/proxy/uid/mimir/api/v1/status/buildinfo",
},
{
"body": "",
@@ -3,6 +3,7 @@ import { getWrapper, render, renderHook, screen, waitFor } from 'test/test-utils
import { setupMswServer } from 'app/features/alerting/unified/mockApi';
import { setFolderAccessControl } from 'app/features/alerting/unified/mocks/server/configure';
import { MIMIR_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types';
import { AccessControlAction } from 'app/types';
import { CombinedRule } from 'app/types/unified-alerting';
@@ -86,7 +87,7 @@ describe('alertmanager abilities', () => {
it('should report everything except exporting for Mimir alertmanager', () => {
setupDataSources(
mockDataSource<AlertManagerDataSourceJsonData>({
name: 'mimir',
name: MIMIR_DATASOURCE_UID,
type: DataSourceType.Alertmanager,
jsonData: {
implementation: AlertManagerImplementation.mimir,
@@ -3,13 +3,13 @@ import * as React from 'react';
import { Provider } from 'react-redux';
import { contextSrv } from 'app/core/services/context_srv';
import { MIMIR_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { configureStore } from 'app/store/configureStore';
import { AccessControlAction, FolderDTO } from 'app/types';
import { mockFeatureDiscoveryApi, setupMswServer } from '../mockApi';
import { setupMswServer } from '../mockApi';
import { mockDataSource, mockFolder, mockRulerAlertingRule, mockRulerGrafanaRule } from '../mocks';
import { setupDataSources } from '../testSetup/datasources';
import { buildInfoResponse } from '../testSetup/featureDiscovery';
import { useFolder } from './useFolder';
import { useIsRuleEditable } from './useIsRuleEditable';
@@ -20,10 +20,10 @@ const mocks = {
useFolder: jest.mocked(useFolder),
};
const server = setupMswServer();
setupMswServer();
const dataSources = {
mimir: mockDataSource({ uid: 'mimir', name: 'Mimir' }),
mimir: mockDataSource({ uid: MIMIR_DATASOURCE_UID, name: 'Mimir' }),
};
setupDataSources(dataSources.mimir);
@@ -107,8 +107,6 @@ describe('useIsRuleEditable', () => {
beforeEach(() => {
mocks.useFolder.mockReturnValue({ loading: false });
contextSrv.isEditor = true;
mockFeatureDiscoveryApi(server).discoverDsFeatures(dataSources.mimir, buildInfoResponse.mimir);
});
it('Should allow editing and deleting when the user has alert rule external write permission', async () => {
@@ -1,7 +1,6 @@
import { HttpResponse, http } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import { DataSourceInstanceSettings } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
import { AlertGroupUpdated } from 'app/features/alerting/unified/api/alertRuleApi';
import allHandlers from 'app/features/alerting/unified/mocks/server/all-handlers';
@@ -12,7 +11,6 @@ import {
import { resetRoutingTreeMap } from 'app/features/alerting/unified/mocks/server/entities/k8s/routingtrees';
import { DashboardDTO, FolderDTO, OrgUser } from 'app/types';
import {
PromBuildInfoResponse,
PromRulesResponse,
RulerGrafanaRuleDTO,
RulerRuleGroupDTO,
@@ -189,22 +187,6 @@ export function mockAlertRuleApi(server: SetupServer) {
};
}
/**
* Used to mock the response from the /api/v1/status/buildinfo endpoint
*/
export function mockFeatureDiscoveryApi(server: SetupServer) {
return {
/**
*
* @param dsSettings Use `mockDataSource` to create a faks data source settings
* @param response Use `buildInfoResponse` to get a pre-defined response for Prometheus and Mimir
*/
discoverDsFeatures: (dsSettings: DataSourceInstanceSettings, response: PromBuildInfoResponse) => {
server.use(http.get(`${dsSettings.url}/api/v1/status/buildinfo`, () => HttpResponse.json(response)));
},
};
}
export function mockExportApi(server: SetupServer) {
// exportRule, exportRulesGroup, exportRulesFolder use the same API endpoint but with different parameters
return {
@@ -2,7 +2,7 @@ import { HttpResponse, http } from 'msw';
import { DataSourceInstanceSettings } from '@grafana/data';
import { config } from '@grafana/runtime';
import server, { mockFeatureDiscoveryApi } from 'app/features/alerting/unified/mockApi';
import server from 'app/features/alerting/unified/mockApi';
import { mockDataSource, mockFolder } from 'app/features/alerting/unified/mocks';
import {
getAlertmanagerConfigHandler,
@@ -23,7 +23,6 @@ import { FolderDTO } from 'app/types';
import { PromRuleGroupDTO } from 'app/types/unified-alerting-dto';
import { setupDataSources } from '../../testSetup/datasources';
import { buildInfoResponse } from '../../testSetup/featureDiscovery';
import { DataSourceType } from '../../utils/datasource';
import { ApiMachineryError } from '../../utils/k8s/errors';
@@ -101,7 +100,6 @@ export function mimirDataSource() {
type: DataSourceType.Prometheus,
name: MIMIR_DATASOURCE_UID,
uid: MIMIR_DATASOURCE_UID,
url: 'https://mimir.local:9000',
jsonData: {
manageAlerts: true,
implementation: 'mimir',
@@ -111,7 +109,6 @@ export function mimirDataSource() {
);
setupDataSources(dataSource);
mockFeatureDiscoveryApi(server).discoverDsFeatures(dataSource, buildInfoResponse.mimir);
return { dataSource };
}
@@ -1,3 +1,5 @@
export const MIMIR_DATASOURCE_UID = 'mimir';
export const MIMIR_GROUP_NAME = 'group-1';
export const MIMIR_NAMESPACE_NAME = 'namespace-1';
export const PROMETHEUS_DATASOURCE_UID = 'prometheus';