datasource_specs.ts 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. import _ from "lodash";
  2. import {
  3. describe,
  4. beforeEach,
  5. it,
  6. expect,
  7. angularMocks
  8. } from "test/lib/common";
  9. import moment from "moment";
  10. import angular from "angular";
  11. import helpers from "test/specs/helpers";
  12. import { ElasticDatasource } from "../datasource";
  13. describe("ElasticDatasource", function() {
  14. var ctx = new helpers.ServiceTestContext();
  15. beforeEach(angularMocks.module("grafana.core"));
  16. beforeEach(angularMocks.module("grafana.services"));
  17. beforeEach(ctx.providePhase(["templateSrv", "backendSrv", "timeSrv"]));
  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. function createDatasource(instanceSettings) {
  28. instanceSettings.jsonData = instanceSettings.jsonData || {};
  29. ctx.ds = ctx.$injector.instantiate(ElasticDatasource, {
  30. instanceSettings: instanceSettings
  31. });
  32. }
  33. describe("When testing datasource with index pattern", function() {
  34. beforeEach(function() {
  35. createDatasource({
  36. url: "http://es.com",
  37. index: "[asd-]YYYY.MM.DD",
  38. jsonData: { interval: "Daily", esVersion: "2" }
  39. });
  40. });
  41. it("should translate index pattern to current day", function() {
  42. var requestOptions;
  43. ctx.backendSrv.datasourceRequest = function(options) {
  44. requestOptions = options;
  45. return ctx.$q.when({ data: {} });
  46. };
  47. ctx.ds.testDatasource();
  48. ctx.$rootScope.$apply();
  49. var today = moment.utc().format("YYYY.MM.DD");
  50. expect(requestOptions.url).to.be(
  51. "http://es.com/asd-" + today + "/_mapping"
  52. );
  53. });
  54. });
  55. describe("When issueing metric query with interval pattern", function() {
  56. var requestOptions, parts, header;
  57. beforeEach(function() {
  58. createDatasource({
  59. url: "http://es.com",
  60. index: "[asd-]YYYY.MM.DD",
  61. jsonData: { interval: "Daily", esVersion: "2" }
  62. });
  63. ctx.backendSrv.datasourceRequest = function(options) {
  64. requestOptions = options;
  65. return ctx.$q.when({ data: { responses: [] } });
  66. };
  67. ctx.ds.query({
  68. range: {
  69. from: moment.utc([2015, 4, 30, 10]),
  70. to: moment.utc([2015, 5, 1, 10])
  71. },
  72. targets: [
  73. {
  74. bucketAggs: [],
  75. metrics: [{ type: "raw_document" }],
  76. query: "escape\\:test"
  77. }
  78. ]
  79. });
  80. ctx.$rootScope.$apply();
  81. parts = requestOptions.data.split("\n");
  82. header = angular.fromJson(parts[0]);
  83. });
  84. it("should translate index pattern to current day", function() {
  85. expect(header.index).to.eql([
  86. "asd-2015.05.30",
  87. "asd-2015.05.31",
  88. "asd-2015.06.01"
  89. ]);
  90. });
  91. it("should json escape lucene query", function() {
  92. var body = angular.fromJson(parts[1]);
  93. expect(body.query.bool.filter[1].query_string.query).to.be(
  94. "escape\\:test"
  95. );
  96. });
  97. });
  98. describe("When issueing document query", function() {
  99. var requestOptions, parts, header;
  100. beforeEach(function() {
  101. createDatasource({
  102. url: "http://es.com",
  103. index: "test",
  104. jsonData: { esVersion: "2" }
  105. });
  106. ctx.backendSrv.datasourceRequest = function(options) {
  107. requestOptions = options;
  108. return ctx.$q.when({ data: { responses: [] } });
  109. };
  110. ctx.ds.query({
  111. range: {
  112. from: moment([2015, 4, 30, 10]),
  113. to: moment([2015, 5, 1, 10])
  114. },
  115. targets: [
  116. {
  117. bucketAggs: [],
  118. metrics: [{ type: "raw_document" }],
  119. query: "test"
  120. }
  121. ]
  122. });
  123. ctx.$rootScope.$apply();
  124. parts = requestOptions.data.split("\n");
  125. header = angular.fromJson(parts[0]);
  126. });
  127. it("should set search type to query_then_fetch", function() {
  128. expect(header.search_type).to.eql("query_then_fetch");
  129. });
  130. it("should set size", function() {
  131. var body = angular.fromJson(parts[1]);
  132. expect(body.size).to.be(500);
  133. });
  134. });
  135. describe("When getting fields", function() {
  136. beforeEach(function() {
  137. createDatasource({ url: "http://es.com", index: "metricbeat" });
  138. ctx.backendSrv.datasourceRequest = function(options) {
  139. return ctx.$q.when({
  140. data: {
  141. metricbeat: {
  142. mappings: {
  143. metricsets: {
  144. _all: {},
  145. properties: {
  146. "@timestamp": { type: "date" },
  147. beat: {
  148. properties: {
  149. name: {
  150. fields: { raw: { type: "keyword" } },
  151. type: "string"
  152. },
  153. hostname: { type: "string" }
  154. }
  155. },
  156. system: {
  157. properties: {
  158. cpu: {
  159. properties: {
  160. system: { type: "float" },
  161. user: { type: "float" }
  162. }
  163. },
  164. process: {
  165. properties: {
  166. cpu: {
  167. properties: {
  168. total: { type: "float" }
  169. }
  170. },
  171. name: { type: "string" }
  172. }
  173. }
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }
  180. }
  181. });
  182. };
  183. });
  184. it("should return nested fields", function() {
  185. ctx.ds
  186. .getFields({
  187. find: "fields",
  188. query: "*"
  189. })
  190. .then(fieldObjects => {
  191. var fields = _.map(fieldObjects, "text");
  192. expect(fields).to.eql([
  193. "@timestamp",
  194. "beat.name.raw",
  195. "beat.name",
  196. "beat.hostname",
  197. "system.cpu.system",
  198. "system.cpu.user",
  199. "system.process.cpu.total",
  200. "system.process.name"
  201. ]);
  202. });
  203. ctx.$rootScope.$apply();
  204. });
  205. it("should return fields related to query type", function() {
  206. ctx.ds
  207. .getFields({
  208. find: "fields",
  209. query: "*",
  210. type: "number"
  211. })
  212. .then(fieldObjects => {
  213. var fields = _.map(fieldObjects, "text");
  214. expect(fields).to.eql([
  215. "system.cpu.system",
  216. "system.cpu.user",
  217. "system.process.cpu.total"
  218. ]);
  219. });
  220. ctx.ds
  221. .getFields({
  222. find: "fields",
  223. query: "*",
  224. type: "date"
  225. })
  226. .then(fieldObjects => {
  227. var fields = _.map(fieldObjects, "text");
  228. expect(fields).to.eql(["@timestamp"]);
  229. });
  230. ctx.$rootScope.$apply();
  231. });
  232. });
  233. describe("When issuing aggregation query on es5.x", function() {
  234. var requestOptions, parts, header;
  235. beforeEach(function() {
  236. createDatasource({
  237. url: "http://es.com",
  238. index: "test",
  239. jsonData: { esVersion: "5" }
  240. });
  241. ctx.backendSrv.datasourceRequest = function(options) {
  242. requestOptions = options;
  243. return ctx.$q.when({ data: { responses: [] } });
  244. };
  245. ctx.ds.query({
  246. range: {
  247. from: moment([2015, 4, 30, 10]),
  248. to: moment([2015, 5, 1, 10])
  249. },
  250. targets: [
  251. {
  252. bucketAggs: [
  253. { type: "date_histogram", field: "@timestamp", id: "2" }
  254. ],
  255. metrics: [{ type: "count" }],
  256. query: "test"
  257. }
  258. ]
  259. });
  260. ctx.$rootScope.$apply();
  261. parts = requestOptions.data.split("\n");
  262. header = angular.fromJson(parts[0]);
  263. });
  264. it("should not set search type to count", function() {
  265. expect(header.search_type).to.not.eql("count");
  266. });
  267. it("should set size to 0", function() {
  268. var body = angular.fromJson(parts[1]);
  269. expect(body.size).to.be(0);
  270. });
  271. });
  272. describe("When issuing metricFind query on es5.x", function() {
  273. var requestOptions, parts, header, body, results;
  274. beforeEach(function() {
  275. createDatasource({
  276. url: "http://es.com",
  277. index: "test",
  278. jsonData: { esVersion: "5" }
  279. });
  280. ctx.backendSrv.datasourceRequest = function(options) {
  281. requestOptions = options;
  282. return ctx.$q.when({
  283. data: {
  284. responses: [
  285. {
  286. aggregations: {
  287. "1": {
  288. buckets: [
  289. { doc_count: 1, key: "test" },
  290. {
  291. doc_count: 2,
  292. key: "test2",
  293. key_as_string: "test2_as_string"
  294. }
  295. ]
  296. }
  297. }
  298. }
  299. ]
  300. }
  301. });
  302. };
  303. ctx.ds.metricFindQuery('{"find": "terms", "field": "test"}').then(res => {
  304. results = res;
  305. });
  306. ctx.$rootScope.$apply();
  307. parts = requestOptions.data.split("\n");
  308. header = angular.fromJson(parts[0]);
  309. body = angular.fromJson(parts[1]);
  310. });
  311. it("should get results", function() {
  312. expect(results.length).to.eql(2);
  313. });
  314. it("should use key or key_as_string", function() {
  315. expect(results[0].text).to.eql("test");
  316. expect(results[1].text).to.eql("test2_as_string");
  317. });
  318. it("should not set search type to count", function() {
  319. expect(header.search_type).to.not.eql("count");
  320. });
  321. it("should set size to 0", function() {
  322. expect(body.size).to.be(0);
  323. });
  324. it("should not set terms aggregation size to 0", function() {
  325. expect(body["aggs"]["1"]["terms"].size).to.not.be(0);
  326. });
  327. });
  328. });