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. });