Chore: Cover CloudMonitoring function utils with tests (#46878)

This commit is contained in:
Andres Martinez Gotor
2022-03-24 09:47:59 +01:00
committed by GitHub
parent 3440e7c8f7
commit 987afeee38
3 changed files with 237 additions and 31 deletions
@@ -1,9 +1,126 @@
import { getAlignmentOptionsByMetric } from './functions';
import { ValueTypes, MetricKind } from './types';
import { AGGREGATIONS, SYSTEM_LABELS } from './constants';
import {
extractServicesFromMetricDescriptors,
getAggregationOptionsByMetric,
getAlignmentOptionsByMetric,
getAlignmentPickerData,
getLabelKeys,
getMetricTypes,
getMetricTypesByService,
labelsToGroupedOptions,
stringArrayToFilters,
} from './functions';
import { newMockDatasource } from './specs/testData';
import { AlignmentTypes, MetricDescriptor, MetricKind, ValueTypes } from './types';
jest.mock('@grafana/runtime', () => ({
...(jest.requireActual('@grafana/runtime') as unknown as object),
getTemplateSrv: () => ({
replace: jest.fn().mockImplementation((s: string) => s),
}),
}));
describe('functions', () => {
let result: any;
describe('extractServicesFromMetricDescriptors', () => {
it('should return unique metric descriptors', () => {
const desc: MetricDescriptor = {
valueType: '',
metricKind: MetricKind.CUMULATIVE,
type: '',
unit: '',
service: '1',
serviceShortName: '',
displayName: '',
description: '',
};
expect(extractServicesFromMetricDescriptors([desc, desc])).toEqual([desc]);
});
});
describe('getMetricTypesByService', () => {
it('filters by metric descriptiors', () => {
const desc1: MetricDescriptor = {
valueType: '',
metricKind: MetricKind.CUMULATIVE,
type: '',
unit: '',
service: '1',
serviceShortName: '',
displayName: '',
description: '',
};
const desc2: MetricDescriptor = {
valueType: '',
metricKind: MetricKind.CUMULATIVE,
type: '',
unit: '',
service: '2',
serviceShortName: '',
displayName: '',
description: '',
};
expect(getMetricTypesByService([desc1, desc2], '1')).toEqual([desc1]);
});
});
describe('getMetricTypes', () => {
it('gets metric type that exists in the array', () => {
const desc1: MetricDescriptor = {
valueType: '',
metricKind: MetricKind.CUMULATIVE,
type: '1',
unit: '',
service: 'svc1',
serviceShortName: '',
displayName: 'uno',
description: '',
};
const desc2: MetricDescriptor = {
valueType: '',
metricKind: MetricKind.CUMULATIVE,
type: '2',
unit: '',
service: 'svc2',
serviceShortName: '',
displayName: 'dos',
description: '',
};
expect(getMetricTypes([desc1, desc2], '1', '1', 'svc1')).toEqual({
metricTypes: [{ name: 'uno', value: '1' }],
selectedMetricType: '1',
});
});
it('gets metric type that does not exist in the array', () => {
const desc1: MetricDescriptor = {
valueType: '',
metricKind: MetricKind.CUMULATIVE,
type: '1',
unit: '',
service: 'svc1',
serviceShortName: '',
displayName: 'uno',
description: '',
};
const desc2: MetricDescriptor = {
valueType: '',
metricKind: MetricKind.CUMULATIVE,
type: '2',
unit: '',
service: 'svc2',
serviceShortName: '',
displayName: 'dos',
description: '',
};
expect(getMetricTypes([desc1, desc2], '3', '4', 'svc1')).toEqual({
metricTypes: [{ name: 'uno', value: '1' }],
selectedMetricType: '1',
});
});
});
describe('getAlignmentOptionsByMetric', () => {
let result: any;
describe('when double and gauge is passed', () => {
beforeEach(() => {
result = getAlignmentOptionsByMetric(ValueTypes.DOUBLE, MetricKind.GAUGE);
@@ -35,4 +152,78 @@ describe('functions', () => {
});
});
});
describe('getAggregationOptionsByMetric', () => {
it('gets a result for a type and a metric kind', () => {
expect(getAggregationOptionsByMetric(ValueTypes.BOOL, MetricKind.CUMULATIVE)).toEqual([
AGGREGATIONS[0],
AGGREGATIONS[6],
]);
});
});
describe('getLabelKeys', () => {
it('should return labels', async () => {
const ds = newMockDatasource();
ds.getLabels = jest.fn().mockResolvedValue({ l1: true, l2: true });
expect(await getLabelKeys(ds, 'type', 'project')).toEqual(['l1', 'l2', ...SYSTEM_LABELS]);
});
});
describe('getAlignmentPickerData', () => {
it('should return default data', () => {
const res = getAlignmentPickerData();
expect(res.alignOptions).toHaveLength(9);
expect(res.perSeriesAligner).toEqual(AlignmentTypes.ALIGN_MEAN);
});
it('should use provided data', () => {
const res = getAlignmentPickerData(ValueTypes.BOOL, MetricKind.CUMULATIVE);
expect(res.alignOptions).toHaveLength(0);
expect(res.perSeriesAligner).toEqual(AlignmentTypes.ALIGN_MEAN);
});
});
describe('labelsToGroupedOptions', () => {
it('should group in the same label', () => {
expect(labelsToGroupedOptions(['foo', 'bar'])).toEqual([
{
expanded: true,
label: '',
options: [
{ label: 'foo', value: 'foo' },
{ label: 'bar', value: 'bar' },
],
},
]);
});
it('should group in different labels', () => {
expect(labelsToGroupedOptions(['foo.bar', 'foobar'])).toEqual([
{
expanded: true,
label: 'Foo Bar',
options: [{ label: 'foo.bar', value: 'foo.bar' }],
},
{
expanded: true,
label: '',
options: [{ label: 'foobar', value: 'foobar' }],
},
]);
});
});
describe('stringArrayToFilters', () => {
it('chunks an array', () => {
expect(stringArrayToFilters(['key', 'operator', 'value', 'condition'])).toEqual([
{
condition: 'condition',
key: 'key',
operator: 'operator',
value: 'value',
},
]);
});
});
});
@@ -1,8 +1,9 @@
import { chunk, flatten, initial, startCase, uniqBy } from 'lodash';
import { ALIGNMENTS, AGGREGATIONS, SYSTEM_LABELS } from './constants';
import { getTemplateSrv, TemplateSrv } from '@grafana/runtime';
import { chunk, initial, startCase, uniqBy } from 'lodash';
import { AGGREGATIONS, ALIGNMENTS, SYSTEM_LABELS } from './constants';
import CloudMonitoringDatasource from './datasource';
import { TemplateSrv, getTemplateSrv } from '@grafana/runtime';
import { MetricDescriptor, ValueTypes, MetricKind, AlignmentTypes, PreprocessorType, Filter } from './types';
import { AlignmentTypes, MetricDescriptor, MetricKind, PreprocessorType, ValueTypes } from './types';
const templateSrv: TemplateSrv = getTemplateSrv();
@@ -104,11 +105,6 @@ export const labelsToGroupedOptions = (groupBys: string[]) => {
return Object.entries(groups).map(([label, options]) => ({ label, options, expanded: true }), []);
};
export const filtersToStringArray = (filters: Filter[]) => {
const strArr = flatten(filters.map(({ key, operator, value, condition }) => [key, operator, value, condition!]));
return strArr.filter((_, i) => i !== strArr.length - 1);
};
export const stringArrayToFilters = (filterArray: string[]) =>
chunk(filterArray, 4).map(([key, operator, value, condition = 'AND']) => ({
key,
@@ -116,22 +112,3 @@ export const stringArrayToFilters = (filterArray: string[]) =>
value,
condition,
}));
export const formatCloudMonitoringError = (error: any) => {
let message = error.statusText ?? '';
if (error.data && error.data.error) {
try {
const res = JSON.parse(error.data.error);
message += res.error.code + '. ' + res.error.message;
} catch (err) {
message += error.data.error;
}
} else if (error.data && error.data.message) {
try {
message = JSON.parse(error.data.message).error.message;
} catch (err) {
error.error = err;
}
}
return message;
};
@@ -1,3 +1,8 @@
import { PluginType } from '@grafana/data';
import { GoogleAuthType } from '@grafana/google-sdk';
import CloudMonitoringDatasource from '../datasource';
export const metricDescriptors = [
{
name: 'projects/grafana-prod/metricDescriptors/agent.googleapis.com/agent/api_request_count',
@@ -40,3 +45,36 @@ export const metricDescriptors = [
},
},
];
export const newMockDatasource = () =>
new CloudMonitoringDatasource({
id: 1,
uid: 'cm-id',
type: 'cloud-monitoring-datasource',
name: 'Cloud Monitoring Data Source',
jsonData: {
authenticationType: GoogleAuthType.JWT,
},
access: 'proxy',
meta: {
id: 'cloud-monitoring-datasource',
name: 'Cloud Monitoring Data Source',
type: PluginType.datasource,
module: '',
baseUrl: '',
info: {
description: '',
screenshots: [],
updated: '',
version: '',
logos: {
small: '',
large: '',
},
author: {
name: '',
},
links: [],
},
},
});