datasource_specs.ts 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import {
  2. describe,
  3. beforeEach,
  4. it,
  5. expect,
  6. angularMocks,
  7. } from 'test/lib/common';
  8. import helpers from 'test/specs/helpers';
  9. import { GraphiteDatasource } from '../datasource';
  10. import moment from 'moment';
  11. import _ from 'lodash';
  12. describe('graphiteDatasource', function() {
  13. let ctx = new helpers.ServiceTestContext();
  14. let instanceSettings: any = { url: [''], name: 'graphiteProd', jsonData: {} };
  15. beforeEach(angularMocks.module('grafana.core'));
  16. beforeEach(angularMocks.module('grafana.services'));
  17. beforeEach(ctx.providePhase(['backendSrv', 'templateSrv']));
  18. beforeEach(
  19. angularMocks.inject(function($q, $rootScope, $httpBackend, $injector) {
  20. ctx.$q = $q;
  21. ctx.$httpBackend = $httpBackend;
  22. ctx.$rootScope = $rootScope;
  23. ctx.$injector = $injector;
  24. $httpBackend.when('GET', /\.html$/).respond('');
  25. })
  26. );
  27. beforeEach(function() {
  28. ctx.ds = ctx.$injector.instantiate(GraphiteDatasource, {
  29. instanceSettings: instanceSettings,
  30. });
  31. });
  32. describe('When querying graphite with one target using query editor target spec', function() {
  33. let query = {
  34. panelId: 3,
  35. rangeRaw: { from: 'now-1h', to: 'now' },
  36. targets: [{ target: 'prod1.count' }, { target: 'prod2.count' }],
  37. maxDataPoints: 500,
  38. };
  39. let results;
  40. let requestOptions;
  41. beforeEach(function() {
  42. ctx.backendSrv.datasourceRequest = function(options) {
  43. requestOptions = options;
  44. return ctx.$q.when({
  45. data: [{ target: 'prod1.count', datapoints: [[10, 1], [12, 1]] }],
  46. });
  47. };
  48. ctx.ds.query(query).then(function(data) {
  49. results = data;
  50. });
  51. ctx.$rootScope.$apply();
  52. });
  53. it('should generate the correct query', function() {
  54. expect(requestOptions.url).to.be('/render');
  55. });
  56. it('should set unique requestId', function() {
  57. expect(requestOptions.requestId).to.be('graphiteProd.panelId.3');
  58. });
  59. it('should query correctly', function() {
  60. let params = requestOptions.data.split('&');
  61. expect(params).to.contain('target=prod1.count');
  62. expect(params).to.contain('target=prod2.count');
  63. expect(params).to.contain('from=-1h');
  64. expect(params).to.contain('until=now');
  65. });
  66. it('should exclude undefined params', function() {
  67. let params = requestOptions.data.split('&');
  68. expect(params).to.not.contain('cacheTimeout=undefined');
  69. });
  70. it('should return series list', function() {
  71. expect(results.data.length).to.be(1);
  72. expect(results.data[0].target).to.be('prod1.count');
  73. });
  74. it('should convert to millisecond resolution', function() {
  75. expect(results.data[0].datapoints[0][0]).to.be(10);
  76. });
  77. });
  78. describe('when fetching Graphite Events as annotations', () => {
  79. let results;
  80. const options = {
  81. annotation: {
  82. tags: 'tag1',
  83. },
  84. range: {
  85. from: moment(1432288354),
  86. to: moment(1432288401),
  87. },
  88. rangeRaw: { from: 'now-24h', to: 'now' },
  89. };
  90. describe('and tags are returned as string', () => {
  91. const response = {
  92. data: [
  93. {
  94. when: 1507222850,
  95. tags: 'tag1 tag2',
  96. data: 'some text',
  97. id: 2,
  98. what: 'Event - deploy',
  99. },
  100. ],
  101. };
  102. beforeEach(() => {
  103. ctx.backendSrv.datasourceRequest = function(options) {
  104. return ctx.$q.when(response);
  105. };
  106. ctx.ds.annotationQuery(options).then(function(data) {
  107. results = data;
  108. });
  109. ctx.$rootScope.$apply();
  110. });
  111. it('should parse the tags string into an array', () => {
  112. expect(_.isArray(results[0].tags)).to.eql(true);
  113. expect(results[0].tags.length).to.eql(2);
  114. expect(results[0].tags[0]).to.eql('tag1');
  115. expect(results[0].tags[1]).to.eql('tag2');
  116. });
  117. });
  118. describe('and tags are returned as an array', () => {
  119. const response = {
  120. data: [
  121. {
  122. when: 1507222850,
  123. tags: ['tag1', 'tag2'],
  124. data: 'some text',
  125. id: 2,
  126. what: 'Event - deploy',
  127. },
  128. ],
  129. };
  130. beforeEach(() => {
  131. ctx.backendSrv.datasourceRequest = function(options) {
  132. return ctx.$q.when(response);
  133. };
  134. ctx.ds.annotationQuery(options).then(function(data) {
  135. results = data;
  136. });
  137. ctx.$rootScope.$apply();
  138. });
  139. it('should parse the tags string into an array', () => {
  140. expect(_.isArray(results[0].tags)).to.eql(true);
  141. expect(results[0].tags.length).to.eql(2);
  142. expect(results[0].tags[0]).to.eql('tag1');
  143. expect(results[0].tags[1]).to.eql('tag2');
  144. });
  145. });
  146. });
  147. describe('building graphite params', function() {
  148. it('should return empty array if no targets', function() {
  149. let results = ctx.ds.buildGraphiteParams({
  150. targets: [{}],
  151. });
  152. expect(results.length).to.be(0);
  153. });
  154. it('should uri escape targets', function() {
  155. let results = ctx.ds.buildGraphiteParams({
  156. targets: [{ target: 'prod1.{test,test2}' }, { target: 'prod2.count' }],
  157. });
  158. expect(results).to.contain('target=prod1.%7Btest%2Ctest2%7D');
  159. });
  160. it('should replace target placeholder', function() {
  161. let results = ctx.ds.buildGraphiteParams({
  162. targets: [
  163. { target: 'series1' },
  164. { target: 'series2' },
  165. { target: 'asPercent(#A,#B)' },
  166. ],
  167. });
  168. expect(results[2]).to.be('target=asPercent(series1%2Cseries2)');
  169. });
  170. it('should replace target placeholder for hidden series', function() {
  171. let results = ctx.ds.buildGraphiteParams({
  172. targets: [
  173. { target: 'series1', hide: true },
  174. { target: 'sumSeries(#A)', hide: true },
  175. { target: 'asPercent(#A,#B)' },
  176. ],
  177. });
  178. expect(results[0]).to.be(
  179. 'target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))')
  180. );
  181. });
  182. it('should replace target placeholder when nesting query references', function() {
  183. let results = ctx.ds.buildGraphiteParams({
  184. targets: [
  185. { target: 'series1' },
  186. { target: 'sumSeries(#A)' },
  187. { target: 'asPercent(#A,#B)' },
  188. ],
  189. });
  190. expect(results[2]).to.be(
  191. 'target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))')
  192. );
  193. });
  194. it('should fix wrong minute interval parameters', function() {
  195. let results = ctx.ds.buildGraphiteParams({
  196. targets: [{ target: "summarize(prod.25m.count, '25m', 'sum')" }],
  197. });
  198. expect(results[0]).to.be(
  199. 'target=' +
  200. encodeURIComponent("summarize(prod.25m.count, '25min', 'sum')")
  201. );
  202. });
  203. it('should fix wrong month interval parameters', function() {
  204. let results = ctx.ds.buildGraphiteParams({
  205. targets: [{ target: "summarize(prod.5M.count, '5M', 'sum')" }],
  206. });
  207. expect(results[0]).to.be(
  208. 'target=' +
  209. encodeURIComponent("summarize(prod.5M.count, '5mon', 'sum')")
  210. );
  211. });
  212. it('should ignore empty targets', function() {
  213. let results = ctx.ds.buildGraphiteParams({
  214. targets: [{ target: 'series1' }, { target: '' }],
  215. });
  216. expect(results.length).to.be(2);
  217. });
  218. });
  219. });