Submit
Path:
~
/
/
usr
/
share
/
grafana
/
public
/
app
/
features
/
alerting
/
unified
/
File Content:
mocks.ts
import { produce } from 'immer'; import { Observable } from 'rxjs'; import { DataQuery, DataQueryRequest, DataQueryResponse, DataSourceApi, DataSourceInstanceSettings, DataSourceJsonData, DataSourcePluginMeta, DataSourceRef, PluginMeta, PluginType, ScopedVars, TestDataSourceResponse, } from '@grafana/data'; import { DataSourceSrv, GetDataSourceListFilters, config } from '@grafana/runtime'; import { defaultDashboard } from '@grafana/schema'; import { contextSrv } from 'app/core/services/context_srv'; import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; import { AlertManagerCortexConfig, AlertState, AlertmanagerAlert, AlertmanagerGroup, AlertmanagerStatus, GrafanaManagedReceiverConfig, MatcherOperator, Silence, SilenceState, } from 'app/plugins/datasource/alertmanager/types'; import { configureStore } from 'app/store/configureStore'; import { AccessControlAction, DashboardDTO, FolderDTO, NotifiersState, ReceiversState, StoreState } from 'app/types'; import { Alert, AlertingRule, CombinedRule, CombinedRuleGroup, CombinedRuleNamespace, RecordingRule, RuleGroup, RuleNamespace, } from 'app/types/unified-alerting'; import { AlertQuery, GrafanaAlertState, GrafanaAlertStateDecision, GrafanaRuleDefinition, PromAlertingRuleState, PromRuleType, RulerAlertingRuleDTO, RulerGrafanaRuleDTO, RulerRecordingRuleDTO, RulerRuleGroupDTO, RulerRulesConfigDTO, } from 'app/types/unified-alerting-dto'; import { DashboardSearchItem, DashboardSearchItemType } from '../../search/types'; let nextDataSourceId = 1; export function mockDataSource<T extends DataSourceJsonData = DataSourceJsonData>( partial: Partial<DataSourceInstanceSettings<T>> = {}, meta: Partial<DataSourcePluginMeta> = {} ): DataSourceInstanceSettings<T> { const id = partial.id ?? nextDataSourceId++; const uid = partial.uid ?? `mock-ds-${nextDataSourceId}`; return { id, uid, type: 'prometheus', name: `Prometheus-${id}`, access: 'proxy', url: `/api/datasources/proxy/uid/${uid}`, jsonData: {} as T, meta: { info: { logos: { small: 'https://prometheus.io/assets/prometheus_logo_grey.svg', large: 'https://prometheus.io/assets/prometheus_logo_grey.svg', }, }, ...meta, } as unknown as DataSourcePluginMeta, readOnly: false, ...partial, }; } export const mockPromAlert = (partial: Partial<Alert> = {}): Alert => ({ activeAt: '2021-03-18T13:47:05.04938691Z', annotations: { message: 'alert with severity "warning"', }, labels: { alertname: 'myalert', severity: 'warning', }, state: PromAlertingRuleState.Firing, value: '1e+00', ...partial, }); export const mockRulerGrafanaRule = ( partial: Partial<RulerGrafanaRuleDTO> = {}, partialDef: Partial<GrafanaRuleDefinition> = {} ): RulerGrafanaRuleDTO => { return { for: '1m', grafana_alert: { uid: '123', title: 'myalert', namespace_uid: '123', condition: 'A', no_data_state: GrafanaAlertStateDecision.Alerting, exec_err_state: GrafanaAlertStateDecision.Alerting, data: [ { datasourceUid: '123', refId: 'A', queryType: 'huh', model: {} as any, }, ], ...partialDef, }, annotations: { message: 'alert with severity "{{.warning}}}"', }, labels: { severity: 'warning', }, ...partial, }; }; export const mockRulerAlertingRule = (partial: Partial<RulerAlertingRuleDTO> = {}): RulerAlertingRuleDTO => ({ alert: 'alert1', expr: 'up = 1', labels: { severity: 'warning', }, annotations: { summary: 'test alert', }, ...partial, }); export const mockRulerRecordingRule = (partial: Partial<RulerRecordingRuleDTO> = {}): RulerAlertingRuleDTO => ({ alert: 'alert1', expr: 'up = 1', labels: { severity: 'warning', }, annotations: { summary: 'test alert', }, ...partial, }); export const mockRulerRuleGroup = (partial: Partial<RulerRuleGroupDTO> = {}): RulerRuleGroupDTO => ({ name: 'group1', rules: [mockRulerAlertingRule()], ...partial, }); export const promRuleFromRulerRule = ( rulerRule: RulerAlertingRuleDTO, override?: Partial<AlertingRule> ): AlertingRule => { return mockPromAlertingRule({ name: rulerRule.alert, query: rulerRule.expr, labels: rulerRule.labels, annotations: rulerRule.annotations, type: PromRuleType.Alerting, ...override, }); }; export const mockPromAlertingRule = (partial: Partial<AlertingRule> = {}): AlertingRule => { return { type: PromRuleType.Alerting, alerts: [mockPromAlert()], name: 'myalert', query: 'foo > 1', lastEvaluation: '2021-03-23T08:19:05.049595312Z', evaluationTime: 0.000395601, annotations: { message: 'alert with severity "{{.warning}}}"', }, labels: { severity: 'warning', }, state: PromAlertingRuleState.Firing, health: 'OK', totalsFiltered: { alerting: 1 }, ...partial, }; }; export const mockGrafanaRulerRule = (partial: Partial<GrafanaRuleDefinition> = {}): RulerGrafanaRuleDTO => { return { for: '', annotations: {}, labels: {}, grafana_alert: { uid: '', title: 'my rule', namespace_uid: 'NAMESPACE_UID', condition: '', no_data_state: GrafanaAlertStateDecision.NoData, exec_err_state: GrafanaAlertStateDecision.Error, data: [], ...partial, }, }; }; export const mockPromRecordingRule = (partial: Partial<RecordingRule> = {}): RecordingRule => { return { type: PromRuleType.Recording, query: 'bar < 3', labels: { cluster: 'eu-central', }, health: 'OK', name: 'myrecordingrule', lastEvaluation: '2021-03-23T08:19:05.049595312Z', evaluationTime: 0.000395601, ...partial, }; }; export const mockPromRuleGroup = (partial: Partial<RuleGroup> = {}): RuleGroup => { return { name: 'mygroup', interval: 60, rules: [mockPromAlertingRule()], ...partial, }; }; export const mockPromRuleNamespace = (partial: Partial<RuleNamespace> = {}): RuleNamespace => { return { dataSourceName: 'Prometheus-1', name: 'default', groups: [mockPromRuleGroup()], ...partial, }; }; export const mockAlertmanagerAlert = (partial: Partial<AlertmanagerAlert> = {}): AlertmanagerAlert => { return { annotations: { summary: 'US-Central region is on fire', }, endsAt: '2021-06-22T21:49:28.562Z', fingerprint: '88e013643c3df34ac3', receivers: [{ name: 'pagerduty' }], startsAt: '2021-06-21T17:25:28.562Z', status: { inhibitedBy: [], silencedBy: [], state: AlertState.Active }, updatedAt: '2021-06-22T21:45:28.564Z', generatorURL: 'https://play.grafana.com/explore', labels: { severity: 'warning', region: 'US-Central' }, ...partial, }; }; export const mockAlertGroup = (partial: Partial<AlertmanagerGroup> = {}): AlertmanagerGroup => { return { labels: { severity: 'warning', region: 'US-Central', }, receiver: { name: 'pagerduty', }, alerts: [ mockAlertmanagerAlert(), mockAlertmanagerAlert({ status: { state: AlertState.Suppressed, silencedBy: ['123456abcdef'], inhibitedBy: [] }, labels: { severity: 'warning', region: 'US-Central', foo: 'bar', ...partial.labels }, }), ], ...partial, }; }; export const mockSilence = (partial: Partial<Silence> = {}): Silence => { return { id: '1a2b3c4d5e6f', matchers: [{ name: 'foo', value: 'bar', isEqual: true, isRegex: false }], startsAt: new Date().toISOString(), endsAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(), updatedAt: new Date().toISOString(), createdBy: config.bootData.user.name || 'admin', comment: 'Silence noisy alerts', status: { state: SilenceState.Active, }, ...partial, }; }; export const mockNotifiersState = (partial: Partial<NotifiersState> = {}): NotifiersState => { return { email: [ { name: 'email', lastNotifyAttempt: new Date().toISOString(), lastNotifyAttemptError: 'this is the error message', lastNotifyAttemptDuration: '10s', }, ], ...partial, }; }; export const mockReceiversState = (partial: Partial<ReceiversState> = {}): ReceiversState => { return { 'broken-receiver': { active: false, errorCount: 1, notifiers: mockNotifiersState(), }, ...partial, }; }; class MockDataSourceApi extends DataSourceApi { constructor(instanceSettings: DataSourceInstanceSettings<DataSourceJsonData>) { super(instanceSettings); } query(request: DataQueryRequest<DataQuery>): Promise<DataQueryResponse> | Observable<DataQueryResponse> { throw new Error('Method not implemented.'); } testDatasource(): Promise<TestDataSourceResponse> { throw new Error('Method not implemented.'); } } // TODO This should be eventually moved to public/app/features/alerting/unified/testSetup/datasources.ts export class MockDataSourceSrv implements DataSourceSrv { datasources: Record<string, DataSourceApi> = {}; // @ts-ignore private settingsMapByName: Record<string, DataSourceInstanceSettings> = {}; private settingsMapByUid: Record<string, DataSourceInstanceSettings> = {}; private settingsMapById: Record<string, DataSourceInstanceSettings> = {}; // @ts-ignore private templateSrv = { getVariables: () => [], replace: (name: any) => name, }; defaultName = ''; constructor(datasources: Record<string, DataSourceInstanceSettings>) { this.datasources = {}; this.settingsMapByName = Object.values(datasources).reduce<Record<string, DataSourceInstanceSettings>>( (acc, ds) => { acc[ds.name] = ds; return acc; }, {} ); for (const dsSettings of Object.values(this.settingsMapByName)) { this.settingsMapByUid[dsSettings.uid] = dsSettings; this.settingsMapById[dsSettings.id] = dsSettings; if (dsSettings.isDefault) { this.defaultName = dsSettings.name; } this.datasources[dsSettings.uid] = new MockDataSourceApi(dsSettings); } } get(name?: string | null | DataSourceRef, scopedVars?: ScopedVars): Promise<DataSourceApi> { return DatasourceSrv.prototype.get.call(this, name, scopedVars); //return Promise.reject(new Error('not implemented')); } /** * Get a list of data sources */ getList(filters?: GetDataSourceListFilters): DataSourceInstanceSettings[] { return DatasourceSrv.prototype.getList.call(this, filters); } /** * Get settings and plugin metadata by name or uid */ getInstanceSettings(nameOrUid: string | null | undefined): DataSourceInstanceSettings | undefined { return DatasourceSrv.prototype.getInstanceSettings.call(this, nameOrUid); } async loadDatasource(name: string): Promise<DataSourceApi<any, any>> { return DatasourceSrv.prototype.loadDatasource.call(this, name); } reload() {} } export const mockGrafanaReceiver = ( type: string, overrides: Partial<GrafanaManagedReceiverConfig> = {} ): GrafanaManagedReceiverConfig => ({ type: type, name: type, disableResolveMessage: false, settings: {}, ...overrides, }); export const someGrafanaAlertManagerConfig: AlertManagerCortexConfig = { template_files: { 'first template': 'first template content', 'second template': 'second template content', 'third template': 'third template', }, alertmanager_config: { route: { receiver: 'default', routes: [ { receiver: 'critical', object_matchers: [['severity', MatcherOperator.equal, 'critical']], }, ], }, receivers: [ { name: 'default', grafana_managed_receiver_configs: [mockGrafanaReceiver('email')], }, { name: 'critical', grafana_managed_receiver_configs: [mockGrafanaReceiver('slack'), mockGrafanaReceiver('pagerduty')], }, ], }, }; export const someCloudAlertManagerStatus: AlertmanagerStatus = { cluster: { peers: [], status: 'ok', }, uptime: '10 hours', versionInfo: { branch: '', version: '', goVersion: '', buildDate: '', buildUser: '', revision: '', }, config: { route: { receiver: 'default-email', }, receivers: [ { name: 'default-email', email_configs: [ { to: 'example@example.com', }, ], }, ], }, }; export const someCloudAlertManagerConfig: AlertManagerCortexConfig = { template_files: { 'foo template': 'foo content', }, alertmanager_config: { route: { receiver: 'cloud-receiver', routes: [ { receiver: 'foo-receiver', }, { receiver: 'bar-receiver', }, ], }, receivers: [ { name: 'cloud-receiver', email_configs: [ { to: 'domas.lapinskas@grafana.com', }, ], slack_configs: [ { api_url: 'http://slack1', channel: '#mychannel', actions: [ { text: 'action1text', type: 'action1type', url: 'http://action1', }, ], fields: [ { title: 'field1', value: 'text1', }, { title: 'field2', value: 'text2', }, ], }, ], }, ], }, }; export const somePromRules = (dataSourceName = 'Prometheus'): RuleNamespace[] => [ { dataSourceName, name: 'namespace1', groups: [ mockPromRuleGroup({ name: 'group1', rules: [mockPromAlertingRule({ name: 'alert1' })] }), mockPromRuleGroup({ name: 'group2', rules: [mockPromAlertingRule({ name: 'alert2' })] }), ], }, { dataSourceName, name: 'namespace2', groups: [mockPromRuleGroup({ name: 'group3', rules: [mockPromAlertingRule({ name: 'alert3' })] })], }, ]; export const someRulerRules: RulerRulesConfigDTO = { namespace1: [ mockRulerRuleGroup({ name: 'group1', rules: [mockRulerAlertingRule({ alert: 'alert1' })] }), mockRulerRuleGroup({ name: 'group2', rules: [mockRulerAlertingRule({ alert: 'alert2' })] }), ], namespace2: [mockRulerRuleGroup({ name: 'group3', rules: [mockRulerAlertingRule({ alert: 'alert3' })] })], }; export const mockCombinedRule = (partial?: Partial<CombinedRule>): CombinedRule => ({ name: 'mockRule', query: 'expr', group: { name: 'mockCombinedRuleGroup', rules: [], totals: {}, }, namespace: { name: 'mockCombinedNamespace', groups: [{ name: 'mockCombinedRuleGroup', rules: [], totals: {} }], rulesSource: 'grafana', }, labels: {}, annotations: {}, promRule: mockPromAlertingRule(), rulerRule: mockRulerAlertingRule(), instanceTotals: {}, filteredInstanceTotals: {}, ...partial, }); export const mockFolder = (partial?: Partial<FolderDTO>): FolderDTO => { return { id: 1, uid: 'gdev-1', title: 'Gdev', version: 1, url: '', canAdmin: true, canDelete: true, canEdit: true, canSave: true, created: '', createdBy: '', hasAcl: false, updated: '', updatedBy: '', ...partial, }; }; export const grantUserPermissions = (permissions: AccessControlAction[]) => { jest .spyOn(contextSrv, 'hasPermission') .mockImplementation((action) => permissions.includes(action as AccessControlAction)); }; export function mockUnifiedAlertingStore(unifiedAlerting?: Partial<StoreState['unifiedAlerting']>) { const defaultState = configureStore().getState(); return configureStore({ ...defaultState, unifiedAlerting: { ...defaultState.unifiedAlerting, ...unifiedAlerting, }, }); } export function mockStore(recipe: (state: StoreState) => void) { const defaultState = configureStore().getState(); return configureStore(produce(defaultState, recipe)); } export function mockAlertQuery(query: Partial<AlertQuery>): AlertQuery { return { datasourceUid: '--uid--', refId: 'A', queryType: '', model: { refId: 'A' }, ...query, }; } export function mockCombinedRuleGroup(name: string, rules: CombinedRule[]): CombinedRuleGroup { return { name, rules, totals: {} }; } export function mockCombinedRuleNamespace(namespace: Partial<CombinedRuleNamespace>): CombinedRuleNamespace { return { name: 'Grafana', groups: [], rulesSource: 'grafana', ...namespace, }; } export function mockCombinedCloudRuleNamespace( namespace: Partial<CombinedRuleNamespace>, dataSourceName: string ): CombinedRuleNamespace { return { name: 'Grafana', groups: [], rulesSource: mockDataSource({ name: dataSourceName, uid: 'Prometheus-1' }), ...namespace, }; } export function getGrafanaRule(override?: Partial<CombinedRule>, rulerOverride?: Partial<GrafanaRuleDefinition>) { return mockCombinedRule({ namespace: { groups: [], name: 'Grafana', rulesSource: 'grafana', }, rulerRule: mockGrafanaRulerRule(rulerOverride), ...override, }); } export function getCloudRule(override?: Partial<CombinedRule>) { return mockCombinedRule({ namespace: { groups: [], name: 'Cortex', rulesSource: mockDataSource(), }, promRule: mockPromAlertingRule(), rulerRule: mockRulerAlertingRule(), ...override, }); } export function mockAlertWithState(state: GrafanaAlertState, labels?: {}): Alert { return { activeAt: '', annotations: {}, labels: labels || {}, state: state, value: '' }; } export function mockDashboardSearchItem(searchItem: Partial<DashboardSearchItem>) { return { title: '', uid: '', type: DashboardSearchItemType.DashDB, url: '', uri: '', items: [], tags: [], slug: '', isStarred: false, ...searchItem, }; } export function mockDashboardDto( dashboard: Partial<DashboardDTO['dashboard']>, meta?: Partial<DashboardDTO['meta']> ): DashboardDTO { return { dashboard: { uid: 'dashboard-test', title: 'Dashboard test', schemaVersion: defaultDashboard.schemaVersion, ...dashboard, }, meta: { ...meta }, }; } export const onCallPluginMetaMock: PluginMeta = { name: 'Grafana OnCall', id: 'grafana-oncall-app', type: PluginType.app, module: 'plugins/grafana-oncall-app/module', baseUrl: 'public/plugins/grafana-oncall-app', info: { author: { name: 'Grafana Labs' }, description: 'Grafana OnCall', updated: '', version: '', links: [], logos: { small: '', large: '', }, screenshots: [], }, };
Submit
FILE
FOLDER
INFO
Name
Size
Permission
Action
__mocks__
---
0755
__snapshots__
---
0755
api
---
0755
components
---
0755
home
---
0755
hooks
---
0755
insights
---
0755
integration
---
0755
mocks
---
0755
search
---
0755
state
---
0755
styles
---
0755
testSetup
---
0755
types
---
0755
utils
---
0755
Admin.tsx
950 bytes
0644
AlertGroups.test.tsx
7318 bytes
0644
AlertGroups.tsx
4151 bytes
0644
AlertWarning.tsx
643 bytes
0644
AlertsFolderView.test.tsx
5384 bytes
0644
AlertsFolderView.tsx
6841 bytes
0644
Analytics.test.ts
1283 bytes
0644
Analytics.ts
6136 bytes
0644
CloneRuleEditor.test.tsx
13662 bytes
0644
CloneRuleEditor.tsx
2563 bytes
0644
ExistingRuleEditor.tsx
2070 bytes
0644
GrafanaRuleQueryViewer.test.tsx
2163 bytes
0644
GrafanaRuleQueryViewer.tsx
15211 bytes
0644
MuteTimings.test.tsx
8845 bytes
0644
MuteTimings.tsx
3375 bytes
0644
NotificationPolicies.test.tsx
28082 bytes
0644
NotificationPolicies.tsx
14112 bytes
0644
PanelAlertTab.tsx
634 bytes
0644
PanelAlertTabContent.test.tsx
10087 bytes
0644
PanelAlertTabContent.tsx
2915 bytes
0644
Receivers.tsx
2183 bytes
0644
RedirectToRuleViewer.test.tsx
6476 bytes
0644
RedirectToRuleViewer.tsx
5092 bytes
0644
RuleEditor.tsx
3860 bytes
0644
RuleEditorCloudOnlyAllowed.test.tsx
7164 bytes
0644
RuleEditorCloudRules.test.tsx
7118 bytes
0644
RuleEditorExisting.test.tsx
8764 bytes
0644
RuleEditorGrafanaRules.test.tsx
8187 bytes
0644
RuleEditorRecordingRule.test.tsx
7031 bytes
0644
RuleList.test.tsx
30652 bytes
0644
RuleList.tsx
7456 bytes
0644
RuleViewer.tsx
2939 bytes
0644
Silences.test.tsx
14125 bytes
0644
Silences.tsx
4613 bytes
0644
TESTING.md
1445 bytes
0644
TODO.md
1411 bytes
0644
createRouteGroupsMatcherWorker.ts
296 bytes
0644
initAlerting.tsx
1151 bytes
0644
mockApi.ts
13689 bytes
0644
mockGrafanaNotifiers.ts
66886 bytes
0644
mocks.ts
18877 bytes
0644
routeGroupsMatcher.ts
2098 bytes
0644
routeGroupsMatcher.worker.ts
338 bytes
0644
useRouteGroupsMatcher.test.tsx
1384 bytes
0644
useRouteGroupsMatcher.ts
3343 bytes
0644
N4ST4R_ID | Naxtarrr