Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
9d374377
Unverified
Commit
9d374377
authored
Aug 01, 2018
by
Marcus Efraimsson
Committed by
GitHub
Aug 01, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #12771 from dehrax/12224-prometheus-ds
Karma to Jest: prometheus datasource
parents
8d0c4cdc
951b623b
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
808 additions
and
698 deletions
+808
-698
public/app/plugins/datasource/prometheus/datasource.ts
+0
-1
public/app/plugins/datasource/prometheus/specs/datasource.jest.ts
+808
-14
public/app/plugins/datasource/prometheus/specs/datasource_specs.ts
+0
-683
No files found.
public/app/plugins/datasource/prometheus/datasource.ts
View file @
9d374377
...
@@ -175,7 +175,6 @@ export class PrometheusDatasource {
...
@@ -175,7 +175,6 @@ export class PrometheusDatasource {
responseIndex: index,
responseIndex: index,
refId: activeTargets[index].refId,
refId: activeTargets[index].refId,
};
};
this.resultTransformer.transform(result, response, transformerOptions);
this.resultTransformer.transform(result, response, transformerOptions);
});
});
...
...
public/app/plugins/datasource/prometheus/specs/datasource.jest.ts
View file @
9d374377
...
@@ -150,49 +150,49 @@ describe('PrometheusDatasource', () => {
...
@@ -150,49 +150,49 @@ describe('PrometheusDatasource', () => {
});
});
});
});
describe
(
'alignRange'
,
function
()
{
describe
(
'alignRange'
,
()
=>
{
it
(
'does not modify already aligned intervals with perfect step'
,
function
()
{
it
(
'does not modify already aligned intervals with perfect step'
,
()
=>
{
const
range
=
alignRange
(
0
,
3
,
3
);
const
range
=
alignRange
(
0
,
3
,
3
);
expect
(
range
.
start
).
toEqual
(
0
);
expect
(
range
.
start
).
toEqual
(
0
);
expect
(
range
.
end
).
toEqual
(
3
);
expect
(
range
.
end
).
toEqual
(
3
);
});
});
it
(
'does modify end-aligned intervals to reflect number of steps possible'
,
function
()
{
it
(
'does modify end-aligned intervals to reflect number of steps possible'
,
()
=>
{
const
range
=
alignRange
(
1
,
6
,
3
);
const
range
=
alignRange
(
1
,
6
,
3
);
expect
(
range
.
start
).
toEqual
(
0
);
expect
(
range
.
start
).
toEqual
(
0
);
expect
(
range
.
end
).
toEqual
(
6
);
expect
(
range
.
end
).
toEqual
(
6
);
});
});
it
(
'does align intervals that are a multiple of steps'
,
function
()
{
it
(
'does align intervals that are a multiple of steps'
,
()
=>
{
const
range
=
alignRange
(
1
,
4
,
3
);
const
range
=
alignRange
(
1
,
4
,
3
);
expect
(
range
.
start
).
toEqual
(
0
);
expect
(
range
.
start
).
toEqual
(
0
);
expect
(
range
.
end
).
toEqual
(
6
);
expect
(
range
.
end
).
toEqual
(
6
);
});
});
it
(
'does align intervals that are not a multiple of steps'
,
function
()
{
it
(
'does align intervals that are not a multiple of steps'
,
()
=>
{
const
range
=
alignRange
(
1
,
5
,
3
);
const
range
=
alignRange
(
1
,
5
,
3
);
expect
(
range
.
start
).
toEqual
(
0
);
expect
(
range
.
start
).
toEqual
(
0
);
expect
(
range
.
end
).
toEqual
(
6
);
expect
(
range
.
end
).
toEqual
(
6
);
});
});
});
});
describe
(
'Prometheus regular escaping'
,
function
()
{
describe
(
'Prometheus regular escaping'
,
()
=>
{
it
(
'should not escape non-string'
,
function
()
{
it
(
'should not escape non-string'
,
()
=>
{
expect
(
prometheusRegularEscape
(
12
)).
toEqual
(
12
);
expect
(
prometheusRegularEscape
(
12
)).
toEqual
(
12
);
});
});
it
(
'should not escape simple string'
,
function
()
{
it
(
'should not escape simple string'
,
()
=>
{
expect
(
prometheusRegularEscape
(
'cryptodepression'
)).
toEqual
(
'cryptodepression'
);
expect
(
prometheusRegularEscape
(
'cryptodepression'
)).
toEqual
(
'cryptodepression'
);
});
});
it
(
"should escape '"
,
function
()
{
it
(
"should escape '"
,
()
=>
{
expect
(
prometheusRegularEscape
(
"looking'glass"
)).
toEqual
(
"looking
\\\\
'glass"
);
expect
(
prometheusRegularEscape
(
"looking'glass"
)).
toEqual
(
"looking
\\\\
'glass"
);
});
});
it
(
'should escape multiple characters'
,
function
()
{
it
(
'should escape multiple characters'
,
()
=>
{
expect
(
prometheusRegularEscape
(
"'looking'glass'"
)).
toEqual
(
"
\\\\
'looking
\\\\
'glass
\\\\
'"
);
expect
(
prometheusRegularEscape
(
"'looking'glass'"
)).
toEqual
(
"
\\\\
'looking
\\\\
'glass
\\\\
'"
);
});
});
});
});
describe
(
'Prometheus regexes escaping'
,
function
()
{
describe
(
'Prometheus regexes escaping'
,
()
=>
{
it
(
'should not escape simple string'
,
function
()
{
it
(
'should not escape simple string'
,
()
=>
{
expect
(
prometheusSpecialRegexEscape
(
'cryptodepression'
)).
toEqual
(
'cryptodepression'
);
expect
(
prometheusSpecialRegexEscape
(
'cryptodepression'
)).
toEqual
(
'cryptodepression'
);
});
});
it
(
'should escape $^*+?.()
\
\'
,
function()
{
it
(
'should escape $^*+?.()
\
\'
,
() =>
{
expect(prometheusSpecialRegexEscape("looking'
glass
")).toEqual("
looking
\\\\
'glass");
expect(prometheusSpecialRegexEscape("looking'
glass
")).toEqual("
looking
\\\\
'glass");
expect(prometheusSpecialRegexEscape('
looking
{
glass
')).toEqual('
looking
\\\\
{
glass
');
expect(prometheusSpecialRegexEscape('
looking
{
glass
')).toEqual('
looking
\\\\
{
glass
');
expect(prometheusSpecialRegexEscape('
looking
}
glass
')).toEqual('
looking
\\\\
}
glass
');
expect(prometheusSpecialRegexEscape('
looking
}
glass
')).toEqual('
looking
\\\\
}
glass
');
...
@@ -208,7 +208,7 @@ describe('PrometheusDatasource', () => {
...
@@ -208,7 +208,7 @@ describe('PrometheusDatasource', () => {
expect(prometheusSpecialRegexEscape('
looking
)
glass
')).toEqual('
looking
\\\\
)
glass
');
expect(prometheusSpecialRegexEscape('
looking
)
glass
')).toEqual('
looking
\\\\
)
glass
');
expect(prometheusSpecialRegexEscape('
looking
\\
glass
')).toEqual('
looking
\\\\\\\\
glass
');
expect(prometheusSpecialRegexEscape('
looking
\\
glass
')).toEqual('
looking
\\\\\\\\
glass
');
});
});
it('
should
escape
multiple
special
characters
',
function()
{
it('
should
escape
multiple
special
characters
',
() =>
{
expect(prometheusSpecialRegexEscape('
+
looking$glass
?
')).toEqual('
\\\\
+
looking
\\\\
$glass
\\\\
?
');
expect(prometheusSpecialRegexEscape('
+
looking$glass
?
')).toEqual('
\\\\
+
looking
\\\\
$glass
\\\\
?
');
});
});
});
});
...
@@ -246,3 +246,797 @@ describe('PrometheusDatasource', () => {
...
@@ -246,3 +246,797 @@ describe('PrometheusDatasource', () => {
});
});
});
});
});
});
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const time = ({ hours = 0, seconds = 0, minutes = 0 }) => moment(hours * HOUR + minutes * MINUTE + seconds * SECOND);
let ctx = <any>{};
let instanceSettings = {
url: '
proxied
',
directUrl: '
direct
',
user: '
test
',
password: '
mupp
',
jsonData: { httpMethod: '
GET
' },
};
let backendSrv = <any>{
datasourceRequest: jest.fn(),
};
let templateSrv = {
replace: jest.fn(str => str),
};
let timeSrv = {
timeRange: () => {
return { to: { diff: () => 2000 }, from: '' };
},
};
describe('
PrometheusDatasource
', () => {
describe('
When
querying
prometheus
with
one
target
using
query
editor
target
spec
', async () => {
var results;
var query = {
range: { from: time({ seconds: 63 }), to: time({ seconds: 183 }) },
targets: [{ expr: '
test
{
job
=
"testjob"
}
', format: '
time_series
' }],
interval: '
60
s
',
};
// Interval alignment with step
var urlExpected =
'
proxied
/
api
/
v1
/
query_range
?
query
=
' + encodeURIComponent('
test
{
job
=
"testjob"
}
') + '
&
start
=
60
&
end
=
240
&
step
=
60
';
beforeEach(async () => {
let response = {
data: {
status: '
success
',
data: {
resultType: '
matrix
',
result: [
{
metric: { __name__: '
test
', job: '
testjob
' },
values: [[60, '
3846
']],
},
],
},
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
});
});
it('
should
generate
the
correct
query
', () => {
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
should
return
series
list
', async () => {
expect(results.data.length).toBe(1);
expect(results.data[0].target).toBe('
test
{
job
=
"testjob"
}
');
});
});
describe('
When
querying
prometheus
with
one
target
which
return
multiple
series
', () => {
var results;
var start = 60;
var end = 360;
var step = 60;
var query = {
range: { from: time({ seconds: start }), to: time({ seconds: end }) },
targets: [{ expr: '
test
{
job
=
"testjob"
}
', format: '
time_series
' }],
interval: '
60
s
',
};
beforeEach(async () => {
let response = {
status: '
success
',
data: {
data: {
resultType: '
matrix
',
result: [
{
metric: { __name__: '
test
', job: '
testjob
', series: '
series
1
' },
values: [[start + step * 1, '
3846
'], [start + step * 3, '
3847
'], [end - step * 1, '
3848
']],
},
{
metric: { __name__: '
test
', job: '
testjob
', series: '
series
2
' },
values: [[start + step * 2, '
4846
']],
},
],
},
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
});
});
it('
should
be
same
length
', () => {
expect(results.data.length).toBe(2);
expect(results.data[0].datapoints.length).toBe((end - start) / step + 1);
expect(results.data[1].datapoints.length).toBe((end - start) / step + 1);
});
it('
should
fill
null
until
first
datapoint
in
response
', () => {
expect(results.data[0].datapoints[0][1]).toBe(start * 1000);
expect(results.data[0].datapoints[0][0]).toBe(null);
expect(results.data[0].datapoints[1][1]).toBe((start + step * 1) * 1000);
expect(results.data[0].datapoints[1][0]).toBe(3846);
});
it('
should
fill
null
after
last
datapoint
in
response
', () => {
var length = (end - start) / step + 1;
expect(results.data[0].datapoints[length - 2][1]).toBe((end - step * 1) * 1000);
expect(results.data[0].datapoints[length - 2][0]).toBe(3848);
expect(results.data[0].datapoints[length - 1][1]).toBe(end * 1000);
expect(results.data[0].datapoints[length - 1][0]).toBe(null);
});
it('
should
fill
null
at
gap
between
series
', () => {
expect(results.data[0].datapoints[2][1]).toBe((start + step * 2) * 1000);
expect(results.data[0].datapoints[2][0]).toBe(null);
expect(results.data[1].datapoints[1][1]).toBe((start + step * 1) * 1000);
expect(results.data[1].datapoints[1][0]).toBe(null);
expect(results.data[1].datapoints[3][1]).toBe((start + step * 3) * 1000);
expect(results.data[1].datapoints[3][0]).toBe(null);
});
});
describe('
When
querying
prometheus
with
one
target
and
instant
=
true
', () => {
var results;
var urlExpected = '
proxied
/
api
/
v1
/
query
?
query
=
' + encodeURIComponent('
test
{
job
=
"testjob"
}
') + '
&
time
=
123
';
var query = {
range: { from: time({ seconds: 63 }), to: time({ seconds: 123 }) },
targets: [{ expr: '
test
{
job
=
"testjob"
}
', format: '
time_series
', instant: true }],
interval: '
60
s
',
};
beforeEach(async () => {
let response = {
status: '
success
',
data: {
data: {
resultType: '
vector
',
result: [
{
metric: { __name__: '
test
', job: '
testjob
' },
value: [123, '
3846
'],
},
],
},
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
});
});
it('
should
generate
the
correct
query
', () => {
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
should
return
series
list
', () => {
expect(results.data.length).toBe(1);
expect(results.data[0].target).toBe('
test
{
job
=
"testjob"
}
');
});
});
describe('
When
performing
annotationQuery
', () => {
var results;
var options = {
annotation: {
expr: '
ALERTS
{
alertstate
=
"firing"
}
',
tagKeys: '
job
',
titleFormat: '
{{
alertname
}}
',
textFormat: '
{{
instance
}}
',
},
range: {
from: time({ seconds: 63 }),
to: time({ seconds: 123 }),
},
};
beforeEach(async () => {
let response = {
status: '
success
',
data: {
data: {
resultType: '
matrix
',
result: [
{
metric: {
__name__: '
ALERTS
',
alertname: '
InstanceDown
',
alertstate: '
firing
',
instance: '
testinstance
',
job: '
testjob
',
},
values: [[123, '
1
']],
},
],
},
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.annotationQuery(options).then(function(data) {
results = data;
});
});
it('
should
return
annotation
list
', () => {
expect(results.length).toBe(1);
expect(results[0].tags).toContain('
testjob
');
expect(results[0].title).toBe('
InstanceDown
');
expect(results[0].text).toBe('
testinstance
');
expect(results[0].time).toBe(123 * 1000);
});
});
describe('
When
resultFormat
is
table
and
instant
=
true
', () => {
var results;
var query = {
range: { from: time({ seconds: 63 }), to: time({ seconds: 123 }) },
targets: [{ expr: '
test
{
job
=
"testjob"
}
', format: '
time_series
', instant: true }],
interval: '
60
s
',
};
beforeEach(async () => {
let response = {
status: '
success
',
data: {
data: {
resultType: '
vector
',
result: [
{
metric: { __name__: '
test
', job: '
testjob
' },
value: [123, '
3846
'],
},
],
},
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
});
});
it('
should
return
result
', () => {
expect(results).not.toBe(null);
});
});
describe('
The
"step"
query
parameter
', () => {
var response = {
status: '
success
',
data: {
data: {
resultType: '
matrix
',
result: [],
},
},
};
it('
should
be
min
interval
when
greater
than
auto
interval
', async () => {
let query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
test
',
interval: '
10
s
',
},
],
interval: '
5
s
',
};
let urlExpected = '
proxied
/
api
/
v1
/
query_range
?
query
=
test
&
start
=
60
&
end
=
420
&
step
=
10
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
step
should
never
go
below
1
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [{ expr: '
test
' }],
interval: '
100
ms
',
};
var urlExpected = '
proxied
/
api
/
v1
/
query_range
?
query
=
test
&
start
=
60
&
end
=
420
&
step
=
1
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
should
be
auto
interval
when
greater
than
min
interval
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
test
',
interval: '
5
s
',
},
],
interval: '
10
s
',
};
var urlExpected = '
proxied
/
api
/
v1
/
query_range
?
query
=
test
&
start
=
60
&
end
=
420
&
step
=
10
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
should
result
in
querying
fewer
than
11000
data
points
', async () => {
var query = {
// 6 hour range
range: { from: time({ hours: 1 }), to: time({ hours: 7 }) },
targets: [{ expr: '
test
' }],
interval: '
1
s
',
};
var end = 7 * 60 * 60;
var start = 60 * 60;
var urlExpected = '
proxied
/
api
/
v1
/
query_range
?
query
=
test
&
start
=
' + start + '
&
end
=
' + end + '
&
step
=
2
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
should
not
apply
min
interval
when
interval
*
intervalFactor
greater
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
test
',
interval: '
10
s
',
intervalFactor: 10,
},
],
interval: '
5
s
',
};
// times get rounded up to interval
var urlExpected = '
proxied
/
api
/
v1
/
query_range
?
query
=
test
&
start
=
50
&
end
=
450
&
step
=
50
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
should
apply
min
interval
when
interval
*
intervalFactor
smaller
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
test
',
interval: '
15
s
',
intervalFactor: 2,
},
],
interval: '
5
s
',
};
var urlExpected = '
proxied
/
api
/
v1
/
query_range
?
query
=
test
' + '
&
start
=
60
&
end
=
420
&
step
=
15
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
should
apply
intervalFactor
to
auto
interval
when
greater
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
test
',
interval: '
5
s
',
intervalFactor: 10,
},
],
interval: '
10
s
',
};
// times get aligned to interval
var urlExpected = '
proxied
/
api
/
v1
/
query_range
?
query
=
test
' + '
&
start
=
0
&
end
=
500
&
step
=
100
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
should
not
not
be
affected
by
the
11000
data
points
limit
when
large
enough
', async () => {
var query = {
// 1 week range
range: { from: time({}), to: time({ hours: 7 * 24 }) },
targets: [
{
expr: '
test
',
intervalFactor: 10,
},
],
interval: '
10
s
',
};
var end = 7 * 24 * 60 * 60;
var start = 0;
var urlExpected = '
proxied
/
api
/
v1
/
query_range
?
query
=
test
' + '
&
start
=
' + start + '
&
end
=
' + end + '
&
step
=
100
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
it('
should
be
determined
by
the
11000
data
points
limit
when
too
small
', async () => {
var query = {
// 1 week range
range: { from: time({}), to: time({ hours: 7 * 24 }) },
targets: [
{
expr: '
test
',
intervalFactor: 10,
},
],
interval: '
5
s
',
};
var end = 7 * 24 * 60 * 60;
var start = 0;
var urlExpected = '
proxied
/
api
/
v1
/
query_range
?
query
=
test
' + '
&
start
=
' + start + '
&
end
=
' + end + '
&
step
=
60
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
});
});
describe('
The
__interval
and
__interval_ms
template
variables
', () => {
var response = {
status: '
success
',
data: {
data: {
resultType: '
matrix
',
result: [],
},
},
};
it('
should
be
unchanged
when
auto
interval
is
greater
than
min
interval
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
rate
(
test
[
$__interval
])
',
interval: '
5
s
',
},
],
interval: '
10
s
',
scopedVars: {
__interval: { text: '
10
s
', value: '
10
s
' },
__interval_ms: { text: 10 * 1000, value: 10 * 1000 },
},
};
var urlExpected =
'
proxied
/
api
/
v1
/
query_range
?
query
=
' +
encodeURIComponent('
rate
(
test
[
$__interval
])
') +
'
&
start
=
60
&
end
=
420
&
step
=
10
';
templateSrv.replace = jest.fn(str => str);
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
expect(templateSrv.replace.mock.calls[0][1]).toEqual({
__interval: {
text: '
10
s
',
value: '
10
s
',
},
__interval_ms: {
text: 10000,
value: 10000,
},
});
});
it('
should
be
min
interval
when
it
is
greater
than
auto
interval
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
rate
(
test
[
$__interval
])
',
interval: '
10
s
',
},
],
interval: '
5
s
',
scopedVars: {
__interval: { text: '
5
s
', value: '
5
s
' },
__interval_ms: { text: 5 * 1000, value: 5 * 1000 },
},
};
var urlExpected =
'
proxied
/
api
/
v1
/
query_range
?
query
=
' +
encodeURIComponent('
rate
(
test
[
$__interval
])
') +
'
&
start
=
60
&
end
=
420
&
step
=
10
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
templateSrv.replace = jest.fn(str => str);
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
expect(templateSrv.replace.mock.calls[0][1]).toEqual({
__interval: {
text: '
5
s
',
value: '
5
s
',
},
__interval_ms: {
text: 5000,
value: 5000,
},
});
});
it('
should
account
for
intervalFactor
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
rate
(
test
[
$__interval
])
',
interval: '
5
s
',
intervalFactor: 10,
},
],
interval: '
10
s
',
scopedVars: {
__interval: { text: '
10
s
', value: '
10
s
' },
__interval_ms: { text: 10 * 1000, value: 10 * 1000 },
},
};
var urlExpected =
'
proxied
/
api
/
v1
/
query_range
?
query
=
' +
encodeURIComponent('
rate
(
test
[
$__interval
])
') +
'
&
start
=
0
&
end
=
500
&
step
=
100
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
templateSrv.replace = jest.fn(str => str);
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
expect(templateSrv.replace.mock.calls[0][1]).toEqual({
__interval: {
text: '
10
s
',
value: '
10
s
',
},
__interval_ms: {
text: 10000,
value: 10000,
},
});
expect(query.scopedVars.__interval.text).toBe('
10
s
');
expect(query.scopedVars.__interval.value).toBe('
10
s
');
expect(query.scopedVars.__interval_ms.text).toBe(10 * 1000);
expect(query.scopedVars.__interval_ms.value).toBe(10 * 1000);
});
it('
should
be
interval
*
intervalFactor
when
greater
than
min
interval
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
rate
(
test
[
$__interval
])
',
interval: '
10
s
',
intervalFactor: 10,
},
],
interval: '
5
s
',
scopedVars: {
__interval: { text: '
5
s
', value: '
5
s
' },
__interval_ms: { text: 5 * 1000, value: 5 * 1000 },
},
};
var urlExpected =
'
proxied
/
api
/
v1
/
query_range
?
query
=
' +
encodeURIComponent('
rate
(
test
[
$__interval
])
') +
'
&
start
=
50
&
end
=
450
&
step
=
50
';
templateSrv.replace = jest.fn(str => str);
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
expect(templateSrv.replace.mock.calls[0][1]).toEqual({
__interval: {
text: '
5
s
',
value: '
5
s
',
},
__interval_ms: {
text: 5000,
value: 5000,
},
});
});
it('
should
be
min
interval
when
greater
than
interval
*
intervalFactor
', async () => {
var query = {
// 6 minute range
range: { from: time({ minutes: 1 }), to: time({ minutes: 7 }) },
targets: [
{
expr: '
rate
(
test
[
$__interval
])
',
interval: '
15
s
',
intervalFactor: 2,
},
],
interval: '
5
s
',
scopedVars: {
__interval: { text: '
5
s
', value: '
5
s
' },
__interval_ms: { text: 5 * 1000, value: 5 * 1000 },
},
};
var urlExpected =
'
proxied
/
api
/
v1
/
query_range
?
query
=
' +
encodeURIComponent('
rate
(
test
[
$__interval
])
') +
'
&
start
=
60
&
end
=
420
&
step
=
15
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
expect(templateSrv.replace.mock.calls[0][1]).toEqual({
__interval: {
text: '
5
s
',
value: '
5
s
',
},
__interval_ms: {
text: 5000,
value: 5000,
},
});
});
it('
should
be
determined
by
the
11000
data
points
limit
,
accounting
for
intervalFactor
', async () => {
var query = {
// 1 week range
range: { from: time({}), to: time({ hours: 7 * 24 }) },
targets: [
{
expr: '
rate
(
test
[
$__interval
])
',
intervalFactor: 10,
},
],
interval: '
5
s
',
scopedVars: {
__interval: { text: '
5
s
', value: '
5
s
' },
__interval_ms: { text: 5 * 1000, value: 5 * 1000 },
},
};
var end = 7 * 24 * 60 * 60;
var start = 0;
var urlExpected =
'
proxied
/
api
/
v1
/
query_range
?
query
=
' +
encodeURIComponent('
rate
(
test
[
$__interval
])
') +
'
&
start
=
' +
start +
'
&
end
=
' +
end +
'
&
step
=
60
';
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
templateSrv.replace = jest.fn(str => str);
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query);
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
GET
');
expect(res.url).toBe(urlExpected);
expect(templateSrv.replace.mock.calls[0][1]).toEqual({
__interval: {
text: '
5
s
',
value: '
5
s
',
},
__interval_ms: {
text: 5000,
value: 5000,
},
});
});
});
});
describe('
PrometheusDatasource
for
POST
', () => {
// var ctx = new helpers.ServiceTestContext();
let instanceSettings = {
url: '
proxied
',
directUrl: '
direct
',
user: '
test
',
password: '
mupp
',
jsonData: { httpMethod: '
POST
' },
};
describe('
When
querying
prometheus
with
one
target
using
query
editor
target
spec
', () => {
var results;
var urlExpected = '
proxied
/
api
/
v1
/
query_range
';
var dataExpected = {
query: '
test
{
job
=
"testjob"
}
',
start: 1 * 60,
end: 3 * 60,
step: 60,
};
var query = {
range: { from: time({ minutes: 1, seconds: 3 }), to: time({ minutes: 2, seconds: 3 }) },
targets: [{ expr: '
test
{
job
=
"testjob"
}
', format: '
time_series
' }],
interval: '
60
s
',
};
beforeEach(async () => {
let response = {
status: '
success
',
data: {
data: {
resultType: '
matrix
',
result: [
{
metric: { __name__: '
test
', job: '
testjob
' },
values: [[2 * 60, '
3846
']],
},
],
},
},
};
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
ctx.ds = new PrometheusDatasource(instanceSettings, q, <any>backendSrv, templateSrv, timeSrv);
await ctx.ds.query(query).then(function(data) {
results = data;
});
});
it('
should
generate
the
correct
query
', () => {
let res = backendSrv.datasourceRequest.mock.calls[0][0];
expect(res.method).toBe('
POST
');
expect(res.url).toBe(urlExpected);
expect(res.data).toEqual(dataExpected);
});
it('
should
return
series
list
', () => {
expect(results.data.length).toBe(1);
expect(results.data[0].target).toBe('
test
{
job
=
"testjob"
}
');
});
});
});
public/app/plugins/datasource/prometheus/specs/datasource_specs.ts
deleted
100644 → 0
View file @
8d0c4cdc
import
{
describe
,
beforeEach
,
it
,
expect
,
angularMocks
}
from
'test/lib/common'
;
import
moment
from
'moment'
;
import
$
from
'jquery'
;
import
helpers
from
'test/specs/helpers'
;
import
{
PrometheusDatasource
}
from
'../datasource'
;
const
SECOND
=
1000
;
const
MINUTE
=
60
*
SECOND
;
const
HOUR
=
60
*
MINUTE
;
const
time
=
({
hours
=
0
,
seconds
=
0
,
minutes
=
0
})
=>
moment
(
hours
*
HOUR
+
minutes
*
MINUTE
+
seconds
*
SECOND
);
describe
(
'PrometheusDatasource'
,
function
()
{
var
ctx
=
new
helpers
.
ServiceTestContext
();
var
instanceSettings
=
{
url
:
'proxied'
,
directUrl
:
'direct'
,
user
:
'test'
,
password
:
'mupp'
,
jsonData
:
{
httpMethod
:
'GET'
},
};
beforeEach
(
angularMocks
.
module
(
'grafana.core'
));
beforeEach
(
angularMocks
.
module
(
'grafana.services'
));
beforeEach
(
ctx
.
providePhase
([
'timeSrv'
]));
beforeEach
(
angularMocks
.
inject
(
function
(
$q
,
$rootScope
,
$httpBackend
,
$injector
)
{
ctx
.
$q
=
$q
;
ctx
.
$httpBackend
=
$httpBackend
;
ctx
.
$rootScope
=
$rootScope
;
ctx
.
ds
=
$injector
.
instantiate
(
PrometheusDatasource
,
{
instanceSettings
:
instanceSettings
,
});
$httpBackend
.
when
(
'GET'
,
/
\.
html$/
).
respond
(
''
);
})
);
describe
(
'When querying prometheus with one target using query editor target spec'
,
function
()
{
var
results
;
var
query
=
{
range
:
{
from
:
time
({
seconds
:
63
}),
to
:
time
({
seconds
:
183
})
},
targets
:
[{
expr
:
'test{job="testjob"}'
,
format
:
'time_series'
}],
interval
:
'60s'
,
};
// Interval alignment with step
var
urlExpected
=
'proxied/api/v1/query_range?query='
+
encodeURIComponent
(
'test{job="testjob"}'
)
+
'&start=60&end=240&step=60'
;
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'matrix'
,
result
:
[
{
metric
:
{
__name__
:
'test'
,
job
:
'testjob'
},
values
:
[[
60
,
'3846'
]],
},
],
},
};
beforeEach
(
function
()
{
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
).
then
(
function
(
data
)
{
results
=
data
;
});
ctx
.
$httpBackend
.
flush
();
});
it
(
'should generate the correct query'
,
function
()
{
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should return series list'
,
function
()
{
expect
(
results
.
data
.
length
).
to
.
be
(
1
);
expect
(
results
.
data
[
0
].
target
).
to
.
be
(
'test{job="testjob"}'
);
});
});
describe
(
'When querying prometheus with one target which return multiple series'
,
function
()
{
var
results
;
var
start
=
60
;
var
end
=
360
;
var
step
=
60
;
var
urlExpected
=
'proxied/api/v1/query_range?query='
+
encodeURIComponent
(
'test{job="testjob"}'
)
+
'&start='
+
start
+
'&end='
+
end
+
'&step='
+
step
;
var
query
=
{
range
:
{
from
:
time
({
seconds
:
start
}),
to
:
time
({
seconds
:
end
})
},
targets
:
[{
expr
:
'test{job="testjob"}'
,
format
:
'time_series'
}],
interval
:
'60s'
,
};
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'matrix'
,
result
:
[
{
metric
:
{
__name__
:
'test'
,
job
:
'testjob'
,
series
:
'series 1'
},
values
:
[[
start
+
step
*
1
,
'3846'
],
[
start
+
step
*
3
,
'3847'
],
[
end
-
step
*
1
,
'3848'
]],
},
{
metric
:
{
__name__
:
'test'
,
job
:
'testjob'
,
series
:
'series 2'
},
values
:
[[
start
+
step
*
2
,
'4846'
]],
},
],
},
};
beforeEach
(
function
()
{
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
).
then
(
function
(
data
)
{
results
=
data
;
});
ctx
.
$httpBackend
.
flush
();
});
it
(
'should be same length'
,
function
()
{
expect
(
results
.
data
.
length
).
to
.
be
(
2
);
expect
(
results
.
data
[
0
].
datapoints
.
length
).
to
.
be
((
end
-
start
)
/
step
+
1
);
expect
(
results
.
data
[
1
].
datapoints
.
length
).
to
.
be
((
end
-
start
)
/
step
+
1
);
});
it
(
'should fill null until first datapoint in response'
,
function
()
{
expect
(
results
.
data
[
0
].
datapoints
[
0
][
1
]).
to
.
be
(
start
*
1000
);
expect
(
results
.
data
[
0
].
datapoints
[
0
][
0
]).
to
.
be
(
null
);
expect
(
results
.
data
[
0
].
datapoints
[
1
][
1
]).
to
.
be
((
start
+
step
*
1
)
*
1000
);
expect
(
results
.
data
[
0
].
datapoints
[
1
][
0
]).
to
.
be
(
3846
);
});
it
(
'should fill null after last datapoint in response'
,
function
()
{
var
length
=
(
end
-
start
)
/
step
+
1
;
expect
(
results
.
data
[
0
].
datapoints
[
length
-
2
][
1
]).
to
.
be
((
end
-
step
*
1
)
*
1000
);
expect
(
results
.
data
[
0
].
datapoints
[
length
-
2
][
0
]).
to
.
be
(
3848
);
expect
(
results
.
data
[
0
].
datapoints
[
length
-
1
][
1
]).
to
.
be
(
end
*
1000
);
expect
(
results
.
data
[
0
].
datapoints
[
length
-
1
][
0
]).
to
.
be
(
null
);
});
it
(
'should fill null at gap between series'
,
function
()
{
expect
(
results
.
data
[
0
].
datapoints
[
2
][
1
]).
to
.
be
((
start
+
step
*
2
)
*
1000
);
expect
(
results
.
data
[
0
].
datapoints
[
2
][
0
]).
to
.
be
(
null
);
expect
(
results
.
data
[
1
].
datapoints
[
1
][
1
]).
to
.
be
((
start
+
step
*
1
)
*
1000
);
expect
(
results
.
data
[
1
].
datapoints
[
1
][
0
]).
to
.
be
(
null
);
expect
(
results
.
data
[
1
].
datapoints
[
3
][
1
]).
to
.
be
((
start
+
step
*
3
)
*
1000
);
expect
(
results
.
data
[
1
].
datapoints
[
3
][
0
]).
to
.
be
(
null
);
});
});
describe
(
'When querying prometheus with one target and instant = true'
,
function
()
{
var
results
;
var
urlExpected
=
'proxied/api/v1/query?query='
+
encodeURIComponent
(
'test{job="testjob"}'
)
+
'&time=123'
;
var
query
=
{
range
:
{
from
:
time
({
seconds
:
63
}),
to
:
time
({
seconds
:
123
})
},
targets
:
[{
expr
:
'test{job="testjob"}'
,
format
:
'time_series'
,
instant
:
true
}],
interval
:
'60s'
,
};
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'vector'
,
result
:
[
{
metric
:
{
__name__
:
'test'
,
job
:
'testjob'
},
value
:
[
123
,
'3846'
],
},
],
},
};
beforeEach
(
function
()
{
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
).
then
(
function
(
data
)
{
results
=
data
;
});
ctx
.
$httpBackend
.
flush
();
});
it
(
'should generate the correct query'
,
function
()
{
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should return series list'
,
function
()
{
expect
(
results
.
data
.
length
).
to
.
be
(
1
);
expect
(
results
.
data
[
0
].
target
).
to
.
be
(
'test{job="testjob"}'
);
});
});
describe
(
'When performing annotationQuery'
,
function
()
{
var
results
;
var
urlExpected
=
'proxied/api/v1/query_range?query='
+
encodeURIComponent
(
'ALERTS{alertstate="firing"}'
)
+
'&start=60&end=180&step=60'
;
var
options
=
{
annotation
:
{
expr
:
'ALERTS{alertstate="firing"}'
,
tagKeys
:
'job'
,
titleFormat
:
'{{alertname}}'
,
textFormat
:
'{{instance}}'
,
},
range
:
{
from
:
time
({
seconds
:
63
}),
to
:
time
({
seconds
:
123
}),
},
};
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'matrix'
,
result
:
[
{
metric
:
{
__name__
:
'ALERTS'
,
alertname
:
'InstanceDown'
,
alertstate
:
'firing'
,
instance
:
'testinstance'
,
job
:
'testjob'
,
},
values
:
[[
123
,
'1'
]],
},
],
},
};
beforeEach
(
function
()
{
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
annotationQuery
(
options
).
then
(
function
(
data
)
{
results
=
data
;
});
ctx
.
$httpBackend
.
flush
();
});
it
(
'should return annotation list'
,
function
()
{
ctx
.
$rootScope
.
$apply
();
expect
(
results
.
length
).
to
.
be
(
1
);
expect
(
results
[
0
].
tags
).
to
.
contain
(
'testjob'
);
expect
(
results
[
0
].
title
).
to
.
be
(
'InstanceDown'
);
expect
(
results
[
0
].
text
).
to
.
be
(
'testinstance'
);
expect
(
results
[
0
].
time
).
to
.
be
(
123
*
1000
);
});
});
describe
(
'When resultFormat is table and instant = true'
,
function
()
{
var
results
;
var
urlExpected
=
'proxied/api/v1/query?query='
+
encodeURIComponent
(
'test{job="testjob"}'
)
+
'&time=123'
;
var
query
=
{
range
:
{
from
:
time
({
seconds
:
63
}),
to
:
time
({
seconds
:
123
})
},
targets
:
[{
expr
:
'test{job="testjob"}'
,
format
:
'time_series'
,
instant
:
true
}],
interval
:
'60s'
,
};
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'vector'
,
result
:
[
{
metric
:
{
__name__
:
'test'
,
job
:
'testjob'
},
value
:
[
123
,
'3846'
],
},
],
},
};
beforeEach
(
function
()
{
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
).
then
(
function
(
data
)
{
results
=
data
;
});
ctx
.
$httpBackend
.
flush
();
});
it
(
'should return result'
,
()
=>
{
expect
(
results
).
not
.
to
.
be
(
null
);
});
});
describe
(
'The "step" query parameter'
,
function
()
{
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'matrix'
,
result
:
[],
},
};
it
(
'should be min interval when greater than auto interval'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'test'
,
interval
:
'10s'
,
},
],
interval
:
'5s'
,
};
var
urlExpected
=
'proxied/api/v1/query_range?query=test&start=60&end=420&step=10'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'step should never go below 1'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[{
expr
:
'test'
}],
interval
:
'100ms'
,
};
var
urlExpected
=
'proxied/api/v1/query_range?query=test&start=60&end=420&step=1'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should be auto interval when greater than min interval'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'test'
,
interval
:
'5s'
,
},
],
interval
:
'10s'
,
};
var
urlExpected
=
'proxied/api/v1/query_range?query=test&start=60&end=420&step=10'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should result in querying fewer than 11000 data points'
,
function
()
{
var
query
=
{
// 6 hour range
range
:
{
from
:
time
({
hours
:
1
}),
to
:
time
({
hours
:
7
})
},
targets
:
[{
expr
:
'test'
}],
interval
:
'1s'
,
};
var
end
=
7
*
60
*
60
;
var
start
=
60
*
60
;
var
urlExpected
=
'proxied/api/v1/query_range?query=test&start='
+
start
+
'&end='
+
end
+
'&step=2'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should not apply min interval when interval * intervalFactor greater'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'test'
,
interval
:
'10s'
,
intervalFactor
:
10
,
},
],
interval
:
'5s'
,
};
// times get rounded up to interval
var
urlExpected
=
'proxied/api/v1/query_range?query=test&start=50&end=450&step=50'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should apply min interval when interval * intervalFactor smaller'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'test'
,
interval
:
'15s'
,
intervalFactor
:
2
,
},
],
interval
:
'5s'
,
};
var
urlExpected
=
'proxied/api/v1/query_range?query=test'
+
'&start=60&end=420&step=15'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should apply intervalFactor to auto interval when greater'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'test'
,
interval
:
'5s'
,
intervalFactor
:
10
,
},
],
interval
:
'10s'
,
};
// times get aligned to interval
var
urlExpected
=
'proxied/api/v1/query_range?query=test'
+
'&start=0&end=500&step=100'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should not not be affected by the 11000 data points limit when large enough'
,
function
()
{
var
query
=
{
// 1 week range
range
:
{
from
:
time
({}),
to
:
time
({
hours
:
7
*
24
})
},
targets
:
[
{
expr
:
'test'
,
intervalFactor
:
10
,
},
],
interval
:
'10s'
,
};
var
end
=
7
*
24
*
60
*
60
;
var
start
=
0
;
var
urlExpected
=
'proxied/api/v1/query_range?query=test'
+
'&start='
+
start
+
'&end='
+
end
+
'&step=100'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should be determined by the 11000 data points limit when too small'
,
function
()
{
var
query
=
{
// 1 week range
range
:
{
from
:
time
({}),
to
:
time
({
hours
:
7
*
24
})
},
targets
:
[
{
expr
:
'test'
,
intervalFactor
:
10
,
},
],
interval
:
'5s'
,
};
var
end
=
7
*
24
*
60
*
60
;
var
start
=
0
;
var
urlExpected
=
'proxied/api/v1/query_range?query=test'
+
'&start='
+
start
+
'&end='
+
end
+
'&step=60'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
});
describe
(
'The __interval and __interval_ms template variables'
,
function
()
{
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'matrix'
,
result
:
[],
},
};
it
(
'should be unchanged when auto interval is greater than min interval'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'rate(test[$__interval])'
,
interval
:
'5s'
,
},
],
interval
:
'10s'
,
scopedVars
:
{
__interval
:
{
text
:
'10s'
,
value
:
'10s'
},
__interval_ms
:
{
text
:
10
*
1000
,
value
:
10
*
1000
},
},
};
var
urlExpected
=
'proxied/api/v1/query_range?query='
+
encodeURIComponent
(
'rate(test[10s])'
)
+
'&start=60&end=420&step=10'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
expect
(
query
.
scopedVars
.
__interval
.
text
).
to
.
be
(
'10s'
);
expect
(
query
.
scopedVars
.
__interval
.
value
).
to
.
be
(
'10s'
);
expect
(
query
.
scopedVars
.
__interval_ms
.
text
).
to
.
be
(
10
*
1000
);
expect
(
query
.
scopedVars
.
__interval_ms
.
value
).
to
.
be
(
10
*
1000
);
});
it
(
'should be min interval when it is greater than auto interval'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'rate(test[$__interval])'
,
interval
:
'10s'
,
},
],
interval
:
'5s'
,
scopedVars
:
{
__interval
:
{
text
:
'5s'
,
value
:
'5s'
},
__interval_ms
:
{
text
:
5
*
1000
,
value
:
5
*
1000
},
},
};
var
urlExpected
=
'proxied/api/v1/query_range?query='
+
encodeURIComponent
(
'rate(test[10s])'
)
+
'&start=60&end=420&step=10'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
expect
(
query
.
scopedVars
.
__interval
.
text
).
to
.
be
(
'5s'
);
expect
(
query
.
scopedVars
.
__interval
.
value
).
to
.
be
(
'5s'
);
expect
(
query
.
scopedVars
.
__interval_ms
.
text
).
to
.
be
(
5
*
1000
);
expect
(
query
.
scopedVars
.
__interval_ms
.
value
).
to
.
be
(
5
*
1000
);
});
it
(
'should account for intervalFactor'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'rate(test[$__interval])'
,
interval
:
'5s'
,
intervalFactor
:
10
,
},
],
interval
:
'10s'
,
scopedVars
:
{
__interval
:
{
text
:
'10s'
,
value
:
'10s'
},
__interval_ms
:
{
text
:
10
*
1000
,
value
:
10
*
1000
},
},
};
var
urlExpected
=
'proxied/api/v1/query_range?query='
+
encodeURIComponent
(
'rate(test[100s])'
)
+
'&start=0&end=500&step=100'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
expect
(
query
.
scopedVars
.
__interval
.
text
).
to
.
be
(
'10s'
);
expect
(
query
.
scopedVars
.
__interval
.
value
).
to
.
be
(
'10s'
);
expect
(
query
.
scopedVars
.
__interval_ms
.
text
).
to
.
be
(
10
*
1000
);
expect
(
query
.
scopedVars
.
__interval_ms
.
value
).
to
.
be
(
10
*
1000
);
});
it
(
'should be interval * intervalFactor when greater than min interval'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'rate(test[$__interval])'
,
interval
:
'10s'
,
intervalFactor
:
10
,
},
],
interval
:
'5s'
,
scopedVars
:
{
__interval
:
{
text
:
'5s'
,
value
:
'5s'
},
__interval_ms
:
{
text
:
5
*
1000
,
value
:
5
*
1000
},
},
};
var
urlExpected
=
'proxied/api/v1/query_range?query='
+
encodeURIComponent
(
'rate(test[50s])'
)
+
'&start=50&end=450&step=50'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
expect
(
query
.
scopedVars
.
__interval
.
text
).
to
.
be
(
'5s'
);
expect
(
query
.
scopedVars
.
__interval
.
value
).
to
.
be
(
'5s'
);
expect
(
query
.
scopedVars
.
__interval_ms
.
text
).
to
.
be
(
5
*
1000
);
expect
(
query
.
scopedVars
.
__interval_ms
.
value
).
to
.
be
(
5
*
1000
);
});
it
(
'should be min interval when greater than interval * intervalFactor'
,
function
()
{
var
query
=
{
// 6 minute range
range
:
{
from
:
time
({
minutes
:
1
}),
to
:
time
({
minutes
:
7
})
},
targets
:
[
{
expr
:
'rate(test[$__interval])'
,
interval
:
'15s'
,
intervalFactor
:
2
,
},
],
interval
:
'5s'
,
scopedVars
:
{
__interval
:
{
text
:
'5s'
,
value
:
'5s'
},
__interval_ms
:
{
text
:
5
*
1000
,
value
:
5
*
1000
},
},
};
var
urlExpected
=
'proxied/api/v1/query_range?query='
+
encodeURIComponent
(
'rate(test[15s])'
)
+
'&start=60&end=420&step=15'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
expect
(
query
.
scopedVars
.
__interval
.
text
).
to
.
be
(
'5s'
);
expect
(
query
.
scopedVars
.
__interval
.
value
).
to
.
be
(
'5s'
);
expect
(
query
.
scopedVars
.
__interval_ms
.
text
).
to
.
be
(
5
*
1000
);
expect
(
query
.
scopedVars
.
__interval_ms
.
value
).
to
.
be
(
5
*
1000
);
});
it
(
'should be determined by the 11000 data points limit, accounting for intervalFactor'
,
function
()
{
var
query
=
{
// 1 week range
range
:
{
from
:
time
({}),
to
:
time
({
hours
:
7
*
24
})
},
targets
:
[
{
expr
:
'rate(test[$__interval])'
,
intervalFactor
:
10
,
},
],
interval
:
'5s'
,
scopedVars
:
{
__interval
:
{
text
:
'5s'
,
value
:
'5s'
},
__interval_ms
:
{
text
:
5
*
1000
,
value
:
5
*
1000
},
},
};
var
end
=
7
*
24
*
60
*
60
;
var
start
=
0
;
var
urlExpected
=
'proxied/api/v1/query_range?query='
+
encodeURIComponent
(
'rate(test[60s])'
)
+
'&start='
+
start
+
'&end='
+
end
+
'&step=60'
;
ctx
.
$httpBackend
.
expect
(
'GET'
,
urlExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
);
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
expect
(
query
.
scopedVars
.
__interval
.
text
).
to
.
be
(
'5s'
);
expect
(
query
.
scopedVars
.
__interval
.
value
).
to
.
be
(
'5s'
);
expect
(
query
.
scopedVars
.
__interval_ms
.
text
).
to
.
be
(
5
*
1000
);
expect
(
query
.
scopedVars
.
__interval_ms
.
value
).
to
.
be
(
5
*
1000
);
});
});
});
describe
(
'PrometheusDatasource for POST'
,
function
()
{
var
ctx
=
new
helpers
.
ServiceTestContext
();
var
instanceSettings
=
{
url
:
'proxied'
,
directUrl
:
'direct'
,
user
:
'test'
,
password
:
'mupp'
,
jsonData
:
{
httpMethod
:
'POST'
},
};
beforeEach
(
angularMocks
.
module
(
'grafana.core'
));
beforeEach
(
angularMocks
.
module
(
'grafana.services'
));
beforeEach
(
ctx
.
providePhase
([
'timeSrv'
]));
beforeEach
(
angularMocks
.
inject
(
function
(
$q
,
$rootScope
,
$httpBackend
,
$injector
)
{
ctx
.
$q
=
$q
;
ctx
.
$httpBackend
=
$httpBackend
;
ctx
.
$rootScope
=
$rootScope
;
ctx
.
ds
=
$injector
.
instantiate
(
PrometheusDatasource
,
{
instanceSettings
:
instanceSettings
});
$httpBackend
.
when
(
'GET'
,
/
\.
html$/
).
respond
(
''
);
})
);
describe
(
'When querying prometheus with one target using query editor target spec'
,
function
()
{
var
results
;
var
urlExpected
=
'proxied/api/v1/query_range'
;
var
dataExpected
=
$
.
param
({
query
:
'test{job="testjob"}'
,
start
:
1
*
60
,
end
:
3
*
60
,
step
:
60
,
});
var
query
=
{
range
:
{
from
:
time
({
minutes
:
1
,
seconds
:
3
}),
to
:
time
({
minutes
:
2
,
seconds
:
3
})
},
targets
:
[{
expr
:
'test{job="testjob"}'
,
format
:
'time_series'
}],
interval
:
'60s'
,
};
var
response
=
{
status
:
'success'
,
data
:
{
resultType
:
'matrix'
,
result
:
[
{
metric
:
{
__name__
:
'test'
,
job
:
'testjob'
},
values
:
[[
2
*
60
,
'3846'
]],
},
],
},
};
beforeEach
(
function
()
{
ctx
.
$httpBackend
.
expectPOST
(
urlExpected
,
dataExpected
).
respond
(
response
);
ctx
.
ds
.
query
(
query
).
then
(
function
(
data
)
{
results
=
data
;
});
ctx
.
$httpBackend
.
flush
();
});
it
(
'should generate the correct query'
,
function
()
{
ctx
.
$httpBackend
.
verifyNoOutstandingExpectation
();
});
it
(
'should return series list'
,
function
()
{
expect
(
results
.
data
.
length
).
to
.
be
(
1
);
expect
(
results
.
data
[
0
].
target
).
to
.
be
(
'test{job="testjob"}'
);
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment