mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
This fixes a regression introduced by #16724 when datasource is configured to use HTTP method POST and testing the datasource which results in an 'options.headers is undefined'. Same error probably happens if datasource is configured to use basic auth and testing datasource.
232 lines
7.9 KiB
TypeScript
232 lines
7.9 KiB
TypeScript
import moment from 'moment';
|
|
import { PrometheusDatasource } from '../datasource';
|
|
import PrometheusMetricFindQuery from '../metric_find_query';
|
|
import q from 'q';
|
|
|
|
describe('PrometheusMetricFindQuery', () => {
|
|
const instanceSettings = {
|
|
url: 'proxied',
|
|
directUrl: 'direct',
|
|
user: 'test',
|
|
password: 'mupp',
|
|
jsonData: { httpMethod: 'GET' },
|
|
};
|
|
const raw = {
|
|
from: moment.utc('2018-04-25 10:00'),
|
|
to: moment.utc('2018-04-25 11:00'),
|
|
};
|
|
const ctx: any = {
|
|
backendSrvMock: {
|
|
datasourceRequest: jest.fn(() => Promise.resolve({})),
|
|
},
|
|
templateSrvMock: {
|
|
replace: a => a,
|
|
},
|
|
timeSrvMock: {
|
|
timeRange: () => ({
|
|
from: raw.from,
|
|
to: raw.to,
|
|
raw: raw,
|
|
}),
|
|
},
|
|
};
|
|
|
|
ctx.setupMetricFindQuery = (data: any) => {
|
|
ctx.backendSrvMock.datasourceRequest.mockReturnValue(Promise.resolve({ status: 'success', data: data.response }));
|
|
return new PrometheusMetricFindQuery(ctx.ds, data.query, ctx.timeSrvMock);
|
|
};
|
|
|
|
beforeEach(() => {
|
|
ctx.backendSrvMock.datasourceRequest.mockReset();
|
|
ctx.ds = new PrometheusDatasource(instanceSettings, q, ctx.backendSrvMock, ctx.templateSrvMock, ctx.timeSrvMock);
|
|
});
|
|
|
|
describe('When performing metricFindQuery', () => {
|
|
it('label_names() should generate label name search query', async () => {
|
|
const query = ctx.setupMetricFindQuery({
|
|
query: 'label_names()',
|
|
response: {
|
|
data: ['name1', 'name2', 'name3'],
|
|
},
|
|
});
|
|
const results = await query.process();
|
|
|
|
expect(results).toHaveLength(3);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
url: 'proxied/api/v1/labels',
|
|
silent: true,
|
|
headers: {},
|
|
});
|
|
});
|
|
|
|
it('label_values(resource) should generate label search query', async () => {
|
|
const query = ctx.setupMetricFindQuery({
|
|
query: 'label_values(resource)',
|
|
response: {
|
|
data: ['value1', 'value2', 'value3'],
|
|
},
|
|
});
|
|
const results = await query.process();
|
|
|
|
expect(results).toHaveLength(3);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
url: 'proxied/api/v1/label/resource/values',
|
|
silent: true,
|
|
headers: {},
|
|
});
|
|
});
|
|
|
|
it('label_values(metric, resource) should generate series query with correct time', async () => {
|
|
const query = ctx.setupMetricFindQuery({
|
|
query: 'label_values(metric, resource)',
|
|
response: {
|
|
data: [
|
|
{ __name__: 'metric', resource: 'value1' },
|
|
{ __name__: 'metric', resource: 'value2' },
|
|
{ __name__: 'metric', resource: 'value3' },
|
|
],
|
|
},
|
|
});
|
|
const results = await query.process();
|
|
|
|
expect(results).toHaveLength(3);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
url: `proxied/api/v1/series?match[]=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
|
silent: true,
|
|
headers: {},
|
|
});
|
|
});
|
|
|
|
it('label_values(metric{label1="foo", label2="bar", label3="baz"}, resource) should generate series query with correct time', async () => {
|
|
const query = ctx.setupMetricFindQuery({
|
|
query: 'label_values(metric{label1="foo", label2="bar", label3="baz"}, resource)',
|
|
response: {
|
|
data: [
|
|
{ __name__: 'metric', resource: 'value1' },
|
|
{ __name__: 'metric', resource: 'value2' },
|
|
{ __name__: 'metric', resource: 'value3' },
|
|
],
|
|
},
|
|
});
|
|
const results = await query.process();
|
|
|
|
expect(results).toHaveLength(3);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
url: `proxied/api/v1/series?match[]=${encodeURIComponent(
|
|
'metric{label1="foo", label2="bar", label3="baz"}'
|
|
)}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
|
silent: true,
|
|
headers: {},
|
|
});
|
|
});
|
|
|
|
it('label_values(metric, resource) result should not contain empty string', async () => {
|
|
const query = ctx.setupMetricFindQuery({
|
|
query: 'label_values(metric, resource)',
|
|
response: {
|
|
data: [
|
|
{ __name__: 'metric', resource: 'value1' },
|
|
{ __name__: 'metric', resource: 'value2' },
|
|
{ __name__: 'metric', resource: '' },
|
|
],
|
|
},
|
|
});
|
|
const results = await query.process();
|
|
|
|
expect(results).toHaveLength(2);
|
|
expect(results[0].text).toBe('value1');
|
|
expect(results[1].text).toBe('value2');
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
url: `proxied/api/v1/series?match[]=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
|
silent: true,
|
|
headers: {},
|
|
});
|
|
});
|
|
|
|
it('metrics(metric.*) should generate metric name query', async () => {
|
|
const query = ctx.setupMetricFindQuery({
|
|
query: 'metrics(metric.*)',
|
|
response: {
|
|
data: ['metric1', 'metric2', 'metric3', 'nomatch'],
|
|
},
|
|
});
|
|
const results = await query.process();
|
|
|
|
expect(results).toHaveLength(3);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
url: 'proxied/api/v1/label/__name__/values',
|
|
silent: true,
|
|
headers: {},
|
|
});
|
|
});
|
|
|
|
it('query_result(metric) should generate metric name query', async () => {
|
|
const query = ctx.setupMetricFindQuery({
|
|
query: 'query_result(metric)',
|
|
response: {
|
|
data: {
|
|
resultType: 'vector',
|
|
result: [
|
|
{
|
|
metric: { __name__: 'metric', job: 'testjob' },
|
|
value: [1443454528.0, '3846'],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
});
|
|
const results = await query.process();
|
|
|
|
expect(results).toHaveLength(1);
|
|
expect(results[0].text).toBe('metric{job="testjob"} 3846 1443454528000');
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
url: `proxied/api/v1/query?query=metric&time=${raw.to.unix()}`,
|
|
requestId: undefined,
|
|
headers: {},
|
|
});
|
|
});
|
|
|
|
it('up{job="job1"} should fallback using generate series query', async () => {
|
|
const query = ctx.setupMetricFindQuery({
|
|
query: 'up{job="job1"}',
|
|
response: {
|
|
data: [
|
|
{ __name__: 'up', instance: '127.0.0.1:1234', job: 'job1' },
|
|
{ __name__: 'up', instance: '127.0.0.1:5678', job: 'job1' },
|
|
{ __name__: 'up', instance: '127.0.0.1:9102', job: 'job1' },
|
|
],
|
|
},
|
|
});
|
|
const results = await query.process();
|
|
|
|
expect(results).toHaveLength(3);
|
|
expect(results[0].text).toBe('up{instance="127.0.0.1:1234",job="job1"}');
|
|
expect(results[1].text).toBe('up{instance="127.0.0.1:5678",job="job1"}');
|
|
expect(results[2].text).toBe('up{instance="127.0.0.1:9102",job="job1"}');
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
|
|
expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
url: `proxied/api/v1/series?match[]=${encodeURIComponent(
|
|
'up{job="job1"}'
|
|
)}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
|
|
silent: true,
|
|
headers: {},
|
|
});
|
|
});
|
|
});
|
|
});
|