| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- import { GraphiteDatasource } from '../datasource';
- import moment from 'moment';
- import _ from 'lodash';
- import $q from 'q';
- import { TemplateSrvStub } from 'test/specs/helpers';
- describe('graphiteDatasource', () => {
- const ctx: any = {
- backendSrv: {},
- $q: $q,
- templateSrv: new TemplateSrvStub(),
- instanceSettings: { url: 'url', name: 'graphiteProd', jsonData: {} },
- };
- beforeEach(function() {
- ctx.instanceSettings.url = '/api/datasources/proxy/1';
- ctx.ds = new GraphiteDatasource(ctx.instanceSettings, ctx.$q, ctx.backendSrv, ctx.templateSrv);
- });
- describe('When querying graphite with one target using query editor target spec', function() {
- const query = {
- panelId: 3,
- dashboardId: 5,
- rangeRaw: { from: 'now-1h', to: 'now' },
- targets: [{ target: 'prod1.count' }, { target: 'prod2.count' }],
- maxDataPoints: 500,
- };
- let results;
- let requestOptions;
- beforeEach(async () => {
- ctx.backendSrv.datasourceRequest = function(options) {
- requestOptions = options;
- return ctx.$q.when({
- data: [{ target: 'prod1.count', datapoints: [[10, 1], [12, 1]] }],
- });
- };
- await ctx.ds.query(query).then(function(data) {
- results = data;
- });
- });
- it('X-Dashboard and X-Panel headers to be set!', () => {
- expect(requestOptions.headers['X-Dashboard-Id']).toBe(5);
- expect(requestOptions.headers['X-Panel-Id']).toBe(3);
- });
- it('should generate the correct query', function() {
- expect(requestOptions.url).toBe('/api/datasources/proxy/1/render');
- });
- it('should set unique requestId', function() {
- expect(requestOptions.requestId).toBe('graphiteProd.panelId.3');
- });
- it('should query correctly', function() {
- const params = requestOptions.data.split('&');
- expect(params).toContain('target=prod1.count');
- expect(params).toContain('target=prod2.count');
- expect(params).toContain('from=-1h');
- expect(params).toContain('until=now');
- });
- it('should exclude undefined params', function() {
- const params = requestOptions.data.split('&');
- expect(params).not.toContain('cacheTimeout=undefined');
- });
- it('should return series list', function() {
- expect(results.data.length).toBe(1);
- expect(results.data[0].target).toBe('prod1.count');
- });
- it('should convert to millisecond resolution', function() {
- expect(results.data[0].datapoints[0][0]).toBe(10);
- });
- });
- describe('when fetching Graphite Events as annotations', () => {
- let results;
- const options = {
- annotation: {
- tags: 'tag1',
- },
- range: {
- from: moment(1432288354),
- to: moment(1432288401),
- },
- rangeRaw: { from: 'now-24h', to: 'now' },
- };
- describe('and tags are returned as string', () => {
- const response = {
- data: [
- {
- when: 1507222850,
- tags: 'tag1 tag2',
- data: 'some text',
- id: 2,
- what: 'Event - deploy',
- },
- ],
- };
- beforeEach(async () => {
- ctx.backendSrv.datasourceRequest = function(options) {
- return ctx.$q.when(response);
- };
- await ctx.ds.annotationQuery(options).then(function(data) {
- results = data;
- });
- });
- it('should parse the tags string into an array', () => {
- expect(_.isArray(results[0].tags)).toEqual(true);
- expect(results[0].tags.length).toEqual(2);
- expect(results[0].tags[0]).toEqual('tag1');
- expect(results[0].tags[1]).toEqual('tag2');
- });
- });
- describe('and tags are returned as an array', () => {
- const response = {
- data: [
- {
- when: 1507222850,
- tags: ['tag1', 'tag2'],
- data: 'some text',
- id: 2,
- what: 'Event - deploy',
- },
- ],
- };
- beforeEach(() => {
- ctx.backendSrv.datasourceRequest = function(options) {
- return ctx.$q.when(response);
- };
- ctx.ds.annotationQuery(options).then(function(data) {
- results = data;
- });
- // ctx.$rootScope.$apply();
- });
- it('should parse the tags string into an array', () => {
- expect(_.isArray(results[0].tags)).toEqual(true);
- expect(results[0].tags.length).toEqual(2);
- expect(results[0].tags[0]).toEqual('tag1');
- expect(results[0].tags[1]).toEqual('tag2');
- });
- });
- });
- describe('building graphite params', function() {
- it('should return empty array if no targets', function() {
- const results = ctx.ds.buildGraphiteParams({
- targets: [{}],
- });
- expect(results.length).toBe(0);
- });
- it('should uri escape targets', function() {
- const results = ctx.ds.buildGraphiteParams({
- targets: [{ target: 'prod1.{test,test2}' }, { target: 'prod2.count' }],
- });
- expect(results).toContain('target=prod1.%7Btest%2Ctest2%7D');
- });
- it('should replace target placeholder', function() {
- const results = ctx.ds.buildGraphiteParams({
- targets: [{ target: 'series1' }, { target: 'series2' }, { target: 'asPercent(#A,#B)' }],
- });
- expect(results[2]).toBe('target=asPercent(series1%2Cseries2)');
- });
- it('should replace target placeholder for hidden series', function() {
- const results = ctx.ds.buildGraphiteParams({
- targets: [
- { target: 'series1', hide: true },
- { target: 'sumSeries(#A)', hide: true },
- { target: 'asPercent(#A,#B)' },
- ],
- });
- expect(results[0]).toBe('target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))'));
- });
- it('should replace target placeholder when nesting query references', function() {
- const results = ctx.ds.buildGraphiteParams({
- targets: [{ target: 'series1' }, { target: 'sumSeries(#A)' }, { target: 'asPercent(#A,#B)' }],
- });
- expect(results[2]).toBe('target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))'));
- });
- it('should fix wrong minute interval parameters', function() {
- const results = ctx.ds.buildGraphiteParams({
- targets: [{ target: "summarize(prod.25m.count, '25m', 'sum')" }],
- });
- expect(results[0]).toBe('target=' + encodeURIComponent("summarize(prod.25m.count, '25min', 'sum')"));
- });
- it('should fix wrong month interval parameters', function() {
- const results = ctx.ds.buildGraphiteParams({
- targets: [{ target: "summarize(prod.5M.count, '5M', 'sum')" }],
- });
- expect(results[0]).toBe('target=' + encodeURIComponent("summarize(prod.5M.count, '5mon', 'sum')"));
- });
- it('should ignore empty targets', function() {
- const results = ctx.ds.buildGraphiteParams({
- targets: [{ target: 'series1' }, { target: '' }],
- });
- expect(results.length).toBe(2);
- });
- });
- describe('querying for template variables', () => {
- let results;
- let requestOptions;
- beforeEach(() => {
- ctx.backendSrv.datasourceRequest = function(options) {
- requestOptions = options;
- return ctx.$q.when({
- data: ['backend_01', 'backend_02'],
- });
- };
- });
- it('should generate tags query', () => {
- ctx.ds.metricFindQuery('tags()').then(data => {
- results = data;
- });
- expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/tags');
- expect(requestOptions.params.expr).toEqual([]);
- expect(results).not.toBe(null);
- });
- it('should generate tags query with a filter expression', () => {
- ctx.ds.metricFindQuery('tags(server=backend_01)').then(data => {
- results = data;
- });
- expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/tags');
- expect(requestOptions.params.expr).toEqual(['server=backend_01']);
- expect(results).not.toBe(null);
- });
- it('should generate tags query for an expression with whitespace after', () => {
- ctx.ds.metricFindQuery('tags(server=backend_01 )').then(data => {
- results = data;
- });
- expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/tags');
- expect(requestOptions.params.expr).toEqual(['server=backend_01']);
- expect(results).not.toBe(null);
- });
- it('should generate tag values query for one tag', () => {
- ctx.ds.metricFindQuery('tag_values(server)').then(data => {
- results = data;
- });
- expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/values');
- expect(requestOptions.params.tag).toBe('server');
- expect(requestOptions.params.expr).toEqual([]);
- expect(results).not.toBe(null);
- });
- it('should generate tag values query for a tag and expression', () => {
- ctx.ds.metricFindQuery('tag_values(server,server=~backend*)').then(data => {
- results = data;
- });
- expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/values');
- expect(requestOptions.params.tag).toBe('server');
- expect(requestOptions.params.expr).toEqual(['server=~backend*']);
- expect(results).not.toBe(null);
- });
- it('should generate tag values query for a tag with whitespace after', () => {
- ctx.ds.metricFindQuery('tag_values(server )').then(data => {
- results = data;
- });
- expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/values');
- expect(requestOptions.params.tag).toBe('server');
- expect(requestOptions.params.expr).toEqual([]);
- expect(results).not.toBe(null);
- });
- it('should generate tag values query for a tag and expression with whitespace after', () => {
- ctx.ds.metricFindQuery('tag_values(server , server=~backend* )').then(data => {
- results = data;
- });
- expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/values');
- expect(requestOptions.params.tag).toBe('server');
- expect(requestOptions.params.expr).toEqual(['server=~backend*']);
- expect(results).not.toBe(null);
- });
- });
- });
- function accessScenario(name, url, fn) {
- describe('access scenario ' + name, function() {
- const ctx: any = {
- backendSrv: {},
- $q: $q,
- templateSrv: new TemplateSrvStub(),
- instanceSettings: { url: 'url', name: 'graphiteProd', jsonData: {} },
- };
- const httpOptions = {
- headers: {},
- };
- describe('when using proxy mode', () => {
- const options = { dashboardId: 1, panelId: 2 };
- it('tracing headers should be added', () => {
- ctx.instanceSettings.url = url;
- const ds = new GraphiteDatasource(ctx.instanceSettings, ctx.$q, ctx.backendSrv, ctx.templateSrv);
- ds.addTracingHeaders(httpOptions, options);
- fn(httpOptions);
- });
- });
- });
- }
- accessScenario('with proxy access', '/api/datasources/proxy/1', function(httpOptions) {
- expect(httpOptions.headers['X-Dashboard-Id']).toBe(1);
- expect(httpOptions.headers['X-Panel-Id']).toBe(2);
- });
- accessScenario('with direct access', 'http://localhost:8080', function(httpOptions) {
- expect(httpOptions.headers['X-Dashboard-Id']).toBe(undefined);
- expect(httpOptions.headers['X-Panel-Id']).toBe(undefined);
- });
|