| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- import {describe, beforeEach, it, expect, angularMocks} from 'test/lib/common';
- import moment from 'moment';
- import helpers from 'test/specs/helpers';
- import {PrometheusDatasource} from '../datasource';
- describe('PrometheusDatasource', function() {
- var ctx = new helpers.ServiceTestContext();
- var instanceSettings = {url: 'proxied', directUrl: 'direct', user: 'test', password: 'mupp', jsonData: {}};
- 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?query=' +
- encodeURIComponent('test{job="testjob"}') +
- '&start=1443438675&end=1443460275&step=60';
- var query = {
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- targets: [{ expr: 'test{job="testjob"}', format: 'time_series' }],
- interval: '60s'
- };
- var response = {
- status: "success",
- data: {
- resultType: "matrix",
- result: [{
- metric: {"__name__": "test", job: "testjob"},
- values: [[1443454528, "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 = 1443438675;
- var end = 1443460275;
- 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: moment(1443438674760), to: moment(1443460274760) },
- 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=1443460275';
- var query = {
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- 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: [1443454528, "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=1443438675&end=1443460275&step=60s';
- var options = {
- annotation: {
- expr: 'ALERTS{alertstate="firing"}',
- tagKeys: 'job',
- titleFormat: '{{alertname}}',
- textFormat: '{{instance}}'
- },
- range: {
- from: moment(1443438674760),
- to: moment(1443460274760)
- }
- };
- var response = {
- status: "success",
- data: {
- resultType: "matrix",
- result: [{
- metric: {"__name__": "ALERTS", alertname: "InstanceDown", alertstate: "firing", instance: "testinstance", job: "testjob"},
- values: [[1443454528, "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(1443454528 * 1000);
- });
- });
- describe('When resultFormat is table', function() {
- var response = {
- status: "success",
- data: {
- resultType: "matrix",
- result: [
- {
- metric: {"__name__": "test", job: "testjob"},
- values: [[1443454528, "3846"]]
- },
- {
- metric: {"__name__": "test", instance: "localhost:8080", job: "otherjob"},
- values: [[1443454529, "3847"]]
- },
- ]
- }
- };
- it('should return table model', function() {
- var table = ctx.ds.transformMetricDataToTable(response.data.result);
- expect(table.type).to.be('table');
- expect(table.rows).to.eql(
- [
- [ 1443454528000, 'test', '', 'testjob', 3846],
- [ 1443454529000, 'test', 'localhost:8080', "otherjob", 3847],
- ]);
- expect(table.columns).to.eql(
- [ { text: 'Time', type: 'time' },
- { text: '__name__' },
- { text: 'instance' },
- { text: 'job' },
- { text: 'Value' }
- ]
- );
- });
- });
- describe('When resultFormat is table and instant = true', function() {
- var results;
- var urlExpected = 'proxied/api/v1/query?query=' +
- encodeURIComponent('test{job="testjob"}') +
- '&time=1443460275';
- var query = {
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- 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: [1443454528, "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 table model', function() {
- var table = ctx.ds.transformMetricDataToTable(response.data.result);
- expect(table.type).to.be('table');
- expect(table.rows).to.eql(
- [
- [ 1443454528000, 'test', 'testjob', 3846]
- ]);
- expect(table.columns).to.eql(
- [ { text: 'Time', type: 'time' },
- { text: '__name__' },
- { text: 'job' },
- { text: 'Value' }
- ]
- );
- });
- });
- 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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- targets: [{
- expr: 'test',
- interval: '10s'
- }],
- interval: '5s'
- };
- var urlExpected = 'proxied/api/v1/query_range?query=test' +
- '&start=1443438675&end=1443460275&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 hour range
- range: { from: moment(1508318768202), to: moment(1508318770118) },
- targets: [{expr: 'test'}],
- interval: '100ms'
- };
- var urlExpected = 'proxied/api/v1/query_range?query=test&start=1508318769&end=1508318771&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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- targets: [{
- expr: 'test',
- interval: '5s'
- }],
- interval: '10s'
- };
- var urlExpected = 'proxied/api/v1/query_range?query=test' +
- '&start=1443438675&end=1443460275&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: moment(1443438674760), to: moment(1443460274760) },
- targets: [{ expr: 'test' }],
- interval: '1s'
- };
- var urlExpected = 'proxied/api/v1/query_range?query=test' +
- '&start=1443438675&end=1443460275&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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- targets: [{
- expr: 'test',
- interval: '10s',
- intervalFactor: 10
- }],
- interval: '5s'
- };
- var urlExpected = 'proxied/api/v1/query_range?query=test' +
- '&start=1443438675&end=1443460275&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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- targets: [{
- expr: 'test',
- interval: '15s',
- intervalFactor: 2
- }],
- interval: '5s'
- };
- var urlExpected = 'proxied/api/v1/query_range?query=test' +
- '&start=1443438675&end=1443460275&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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- targets: [{
- expr: 'test',
- interval: '5s',
- intervalFactor: 10
- }],
- interval: '10s'
- };
- var urlExpected = 'proxied/api/v1/query_range?query=test' +
- '&start=1443438675&end=1443460275&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: moment(1443438674760), to: moment(1444043474760) },
- targets: [{
- expr: 'test',
- intervalFactor: 10
- }],
- interval: '10s'
- };
- var urlExpected = 'proxied/api/v1/query_range?query=test' +
- '&start=1443438675&end=1444043475&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: moment(1443438674760), to: moment(1444043474760) },
- targets: [{
- expr: 'test',
- intervalFactor: 10
- }],
- interval: '5s'
- };
- var urlExpected = 'proxied/api/v1/query_range?query=test' +
- '&start=1443438675&end=1444043475&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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- 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=1443438675&end=1443460275&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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- 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=1443438675&end=1443460275&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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- 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=1443438675&end=1443460275&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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- 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=1443438675&end=1443460275&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 hour range
- range: { from: moment(1443438674760), to: moment(1443460274760) },
- 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=1443438675&end=1443460275&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: moment(1443438674760), to: moment(1444043474760) },
- targets: [{
- expr: 'rate(test[$__interval])',
- 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[60s])') +
- '&start=1443438675&end=1444043475&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);
- });
- });
- });
|