elastic_response_specs.ts 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. import { describe, beforeEach, it, expect } from 'test/lib/common';
  2. import { ElasticResponse } from '../elastic_response';
  3. describe('ElasticResponse', function() {
  4. var targets;
  5. var response;
  6. var result;
  7. describe('simple query and count', function() {
  8. beforeEach(function() {
  9. targets = [
  10. {
  11. refId: 'A',
  12. metrics: [{ type: 'count', id: '1' }],
  13. bucketAggs: [
  14. { type: 'date_histogram', field: '@timestamp', id: '2' },
  15. ],
  16. },
  17. ];
  18. response = {
  19. responses: [
  20. {
  21. aggregations: {
  22. '2': {
  23. buckets: [
  24. {
  25. doc_count: 10,
  26. key: 1000,
  27. },
  28. {
  29. doc_count: 15,
  30. key: 2000,
  31. },
  32. ],
  33. },
  34. },
  35. },
  36. ],
  37. };
  38. result = new ElasticResponse(targets, response).getTimeSeries();
  39. });
  40. it('should return 1 series', function() {
  41. expect(result.data.length).to.be(1);
  42. expect(result.data[0].target).to.be('Count');
  43. expect(result.data[0].datapoints.length).to.be(2);
  44. expect(result.data[0].datapoints[0][0]).to.be(10);
  45. expect(result.data[0].datapoints[0][1]).to.be(1000);
  46. });
  47. });
  48. describe('simple query count & avg aggregation', function() {
  49. var result;
  50. beforeEach(function() {
  51. targets = [
  52. {
  53. refId: 'A',
  54. metrics: [
  55. { type: 'count', id: '1' },
  56. { type: 'avg', field: 'value', id: '2' },
  57. ],
  58. bucketAggs: [
  59. { type: 'date_histogram', field: '@timestamp', id: '3' },
  60. ],
  61. },
  62. ];
  63. response = {
  64. responses: [
  65. {
  66. aggregations: {
  67. '3': {
  68. buckets: [
  69. {
  70. '2': { value: 88 },
  71. doc_count: 10,
  72. key: 1000,
  73. },
  74. {
  75. '2': { value: 99 },
  76. doc_count: 15,
  77. key: 2000,
  78. },
  79. ],
  80. },
  81. },
  82. },
  83. ],
  84. };
  85. result = new ElasticResponse(targets, response).getTimeSeries();
  86. });
  87. it('should return 2 series', function() {
  88. expect(result.data.length).to.be(2);
  89. expect(result.data[0].datapoints.length).to.be(2);
  90. expect(result.data[0].datapoints[0][0]).to.be(10);
  91. expect(result.data[0].datapoints[0][1]).to.be(1000);
  92. expect(result.data[1].target).to.be('Average value');
  93. expect(result.data[1].datapoints[0][0]).to.be(88);
  94. expect(result.data[1].datapoints[1][0]).to.be(99);
  95. });
  96. });
  97. describe('single group by query one metric', function() {
  98. var result;
  99. beforeEach(function() {
  100. targets = [
  101. {
  102. refId: 'A',
  103. metrics: [{ type: 'count', id: '1' }],
  104. bucketAggs: [
  105. { type: 'terms', field: 'host', id: '2' },
  106. { type: 'date_histogram', field: '@timestamp', id: '3' },
  107. ],
  108. },
  109. ];
  110. response = {
  111. responses: [
  112. {
  113. aggregations: {
  114. '2': {
  115. buckets: [
  116. {
  117. '3': {
  118. buckets: [
  119. { doc_count: 1, key: 1000 },
  120. { doc_count: 3, key: 2000 },
  121. ],
  122. },
  123. doc_count: 4,
  124. key: 'server1',
  125. },
  126. {
  127. '3': {
  128. buckets: [
  129. { doc_count: 2, key: 1000 },
  130. { doc_count: 8, key: 2000 },
  131. ],
  132. },
  133. doc_count: 10,
  134. key: 'server2',
  135. },
  136. ],
  137. },
  138. },
  139. },
  140. ],
  141. };
  142. result = new ElasticResponse(targets, response).getTimeSeries();
  143. });
  144. it('should return 2 series', function() {
  145. expect(result.data.length).to.be(2);
  146. expect(result.data[0].datapoints.length).to.be(2);
  147. expect(result.data[0].target).to.be('server1');
  148. expect(result.data[1].target).to.be('server2');
  149. });
  150. });
  151. describe('single group by query two metrics', function() {
  152. var result;
  153. beforeEach(function() {
  154. targets = [
  155. {
  156. refId: 'A',
  157. metrics: [
  158. { type: 'count', id: '1' },
  159. { type: 'avg', field: '@value', id: '4' },
  160. ],
  161. bucketAggs: [
  162. { type: 'terms', field: 'host', id: '2' },
  163. { type: 'date_histogram', field: '@timestamp', id: '3' },
  164. ],
  165. },
  166. ];
  167. response = {
  168. responses: [
  169. {
  170. aggregations: {
  171. '2': {
  172. buckets: [
  173. {
  174. '3': {
  175. buckets: [
  176. { '4': { value: 10 }, doc_count: 1, key: 1000 },
  177. { '4': { value: 12 }, doc_count: 3, key: 2000 },
  178. ],
  179. },
  180. doc_count: 4,
  181. key: 'server1',
  182. },
  183. {
  184. '3': {
  185. buckets: [
  186. { '4': { value: 20 }, doc_count: 1, key: 1000 },
  187. { '4': { value: 32 }, doc_count: 3, key: 2000 },
  188. ],
  189. },
  190. doc_count: 10,
  191. key: 'server2',
  192. },
  193. ],
  194. },
  195. },
  196. },
  197. ],
  198. };
  199. result = new ElasticResponse(targets, response).getTimeSeries();
  200. });
  201. it('should return 2 series', function() {
  202. expect(result.data.length).to.be(4);
  203. expect(result.data[0].datapoints.length).to.be(2);
  204. expect(result.data[0].target).to.be('server1 Count');
  205. expect(result.data[1].target).to.be('server1 Average @value');
  206. expect(result.data[2].target).to.be('server2 Count');
  207. expect(result.data[3].target).to.be('server2 Average @value');
  208. });
  209. });
  210. describe('with percentiles ', function() {
  211. var result;
  212. beforeEach(function() {
  213. targets = [
  214. {
  215. refId: 'A',
  216. metrics: [
  217. { type: 'percentiles', settings: { percents: [75, 90] }, id: '1' },
  218. ],
  219. bucketAggs: [
  220. { type: 'date_histogram', field: '@timestamp', id: '3' },
  221. ],
  222. },
  223. ];
  224. response = {
  225. responses: [
  226. {
  227. aggregations: {
  228. '3': {
  229. buckets: [
  230. {
  231. '1': { values: { '75': 3.3, '90': 5.5 } },
  232. doc_count: 10,
  233. key: 1000,
  234. },
  235. {
  236. '1': { values: { '75': 2.3, '90': 4.5 } },
  237. doc_count: 15,
  238. key: 2000,
  239. },
  240. ],
  241. },
  242. },
  243. },
  244. ],
  245. };
  246. result = new ElasticResponse(targets, response).getTimeSeries();
  247. });
  248. it('should return 2 series', function() {
  249. expect(result.data.length).to.be(2);
  250. expect(result.data[0].datapoints.length).to.be(2);
  251. expect(result.data[0].target).to.be('p75');
  252. expect(result.data[1].target).to.be('p90');
  253. expect(result.data[0].datapoints[0][0]).to.be(3.3);
  254. expect(result.data[0].datapoints[0][1]).to.be(1000);
  255. expect(result.data[1].datapoints[1][0]).to.be(4.5);
  256. });
  257. });
  258. describe('with extended_stats', function() {
  259. var result;
  260. beforeEach(function() {
  261. targets = [
  262. {
  263. refId: 'A',
  264. metrics: [
  265. {
  266. type: 'extended_stats',
  267. meta: { max: true, std_deviation_bounds_upper: true },
  268. id: '1',
  269. },
  270. ],
  271. bucketAggs: [
  272. { type: 'terms', field: 'host', id: '3' },
  273. { type: 'date_histogram', id: '4' },
  274. ],
  275. },
  276. ];
  277. response = {
  278. responses: [
  279. {
  280. aggregations: {
  281. '3': {
  282. buckets: [
  283. {
  284. key: 'server1',
  285. '4': {
  286. buckets: [
  287. {
  288. '1': {
  289. max: 10.2,
  290. min: 5.5,
  291. std_deviation_bounds: { upper: 3, lower: -2 },
  292. },
  293. doc_count: 10,
  294. key: 1000,
  295. },
  296. ],
  297. },
  298. },
  299. {
  300. key: 'server2',
  301. '4': {
  302. buckets: [
  303. {
  304. '1': {
  305. max: 10.2,
  306. min: 5.5,
  307. std_deviation_bounds: { upper: 3, lower: -2 },
  308. },
  309. doc_count: 10,
  310. key: 1000,
  311. },
  312. ],
  313. },
  314. },
  315. ],
  316. },
  317. },
  318. },
  319. ],
  320. };
  321. result = new ElasticResponse(targets, response).getTimeSeries();
  322. });
  323. it('should return 4 series', function() {
  324. expect(result.data.length).to.be(4);
  325. expect(result.data[0].datapoints.length).to.be(1);
  326. expect(result.data[0].target).to.be('server1 Max');
  327. expect(result.data[1].target).to.be('server1 Std Dev Upper');
  328. expect(result.data[0].datapoints[0][0]).to.be(10.2);
  329. expect(result.data[1].datapoints[0][0]).to.be(3);
  330. });
  331. });
  332. describe('single group by with alias pattern', function() {
  333. var result;
  334. beforeEach(function() {
  335. targets = [
  336. {
  337. refId: 'A',
  338. metrics: [{ type: 'count', id: '1' }],
  339. alias: '{{term @host}} {{metric}} and {{not_exist}} {{@host}}',
  340. bucketAggs: [
  341. { type: 'terms', field: '@host', id: '2' },
  342. { type: 'date_histogram', field: '@timestamp', id: '3' },
  343. ],
  344. },
  345. ];
  346. response = {
  347. responses: [
  348. {
  349. aggregations: {
  350. '2': {
  351. buckets: [
  352. {
  353. '3': {
  354. buckets: [
  355. { doc_count: 1, key: 1000 },
  356. { doc_count: 3, key: 2000 },
  357. ],
  358. },
  359. doc_count: 4,
  360. key: 'server1',
  361. },
  362. {
  363. '3': {
  364. buckets: [
  365. { doc_count: 2, key: 1000 },
  366. { doc_count: 8, key: 2000 },
  367. ],
  368. },
  369. doc_count: 10,
  370. key: 'server2',
  371. },
  372. {
  373. '3': {
  374. buckets: [
  375. { doc_count: 2, key: 1000 },
  376. { doc_count: 8, key: 2000 },
  377. ],
  378. },
  379. doc_count: 10,
  380. key: 0,
  381. },
  382. ],
  383. },
  384. },
  385. },
  386. ],
  387. };
  388. result = new ElasticResponse(targets, response).getTimeSeries();
  389. });
  390. it('should return 2 series', function() {
  391. expect(result.data.length).to.be(3);
  392. expect(result.data[0].datapoints.length).to.be(2);
  393. expect(result.data[0].target).to.be(
  394. 'server1 Count and {{not_exist}} server1'
  395. );
  396. expect(result.data[1].target).to.be(
  397. 'server2 Count and {{not_exist}} server2'
  398. );
  399. expect(result.data[2].target).to.be('0 Count and {{not_exist}} 0');
  400. });
  401. });
  402. describe('histogram response', function() {
  403. var result;
  404. beforeEach(function() {
  405. targets = [
  406. {
  407. refId: 'A',
  408. metrics: [{ type: 'count', id: '1' }],
  409. bucketAggs: [{ type: 'histogram', field: 'bytes', id: '3' }],
  410. },
  411. ];
  412. response = {
  413. responses: [
  414. {
  415. aggregations: {
  416. '3': {
  417. buckets: [
  418. { doc_count: 1, key: 1000 },
  419. { doc_count: 3, key: 2000 },
  420. { doc_count: 2, key: 1000 },
  421. ],
  422. },
  423. },
  424. },
  425. ],
  426. };
  427. result = new ElasticResponse(targets, response).getTimeSeries();
  428. });
  429. it('should return table with byte and count', function() {
  430. expect(result.data[0].rows.length).to.be(3);
  431. expect(result.data[0].columns).to.eql([
  432. { text: 'bytes', filterable: true },
  433. { text: 'Count' },
  434. ]);
  435. });
  436. });
  437. describe('with two filters agg', function() {
  438. var result;
  439. beforeEach(function() {
  440. targets = [
  441. {
  442. refId: 'A',
  443. metrics: [{ type: 'count', id: '1' }],
  444. bucketAggs: [
  445. {
  446. id: '2',
  447. type: 'filters',
  448. settings: {
  449. filters: [
  450. { query: '@metric:cpu' },
  451. { query: '@metric:logins.count' },
  452. ],
  453. },
  454. },
  455. { type: 'date_histogram', field: '@timestamp', id: '3' },
  456. ],
  457. },
  458. ];
  459. response = {
  460. responses: [
  461. {
  462. aggregations: {
  463. '2': {
  464. buckets: {
  465. '@metric:cpu': {
  466. '3': {
  467. buckets: [
  468. { doc_count: 1, key: 1000 },
  469. { doc_count: 3, key: 2000 },
  470. ],
  471. },
  472. },
  473. '@metric:logins.count': {
  474. '3': {
  475. buckets: [
  476. { doc_count: 2, key: 1000 },
  477. { doc_count: 8, key: 2000 },
  478. ],
  479. },
  480. },
  481. },
  482. },
  483. },
  484. },
  485. ],
  486. };
  487. result = new ElasticResponse(targets, response).getTimeSeries();
  488. });
  489. it('should return 2 series', function() {
  490. expect(result.data.length).to.be(2);
  491. expect(result.data[0].datapoints.length).to.be(2);
  492. expect(result.data[0].target).to.be('@metric:cpu');
  493. expect(result.data[1].target).to.be('@metric:logins.count');
  494. });
  495. });
  496. describe('with dropfirst and last aggregation', function() {
  497. beforeEach(function() {
  498. targets = [
  499. {
  500. refId: 'A',
  501. metrics: [{ type: 'avg', id: '1' }, { type: 'count' }],
  502. bucketAggs: [
  503. {
  504. id: '2',
  505. type: 'date_histogram',
  506. field: 'host',
  507. settings: { trimEdges: 1 },
  508. },
  509. ],
  510. },
  511. ];
  512. response = {
  513. responses: [
  514. {
  515. aggregations: {
  516. '2': {
  517. buckets: [
  518. {
  519. '1': { value: 1000 },
  520. key: 1,
  521. doc_count: 369,
  522. },
  523. {
  524. '1': { value: 2000 },
  525. key: 2,
  526. doc_count: 200,
  527. },
  528. {
  529. '1': { value: 2000 },
  530. key: 3,
  531. doc_count: 200,
  532. },
  533. ],
  534. },
  535. },
  536. },
  537. ],
  538. };
  539. result = new ElasticResponse(targets, response).getTimeSeries();
  540. });
  541. it('should remove first and last value', function() {
  542. expect(result.data.length).to.be(2);
  543. expect(result.data[0].datapoints.length).to.be(1);
  544. });
  545. });
  546. describe('No group by time', function() {
  547. beforeEach(function() {
  548. targets = [
  549. {
  550. refId: 'A',
  551. metrics: [{ type: 'avg', id: '1' }, { type: 'count' }],
  552. bucketAggs: [{ id: '2', type: 'terms', field: 'host' }],
  553. },
  554. ];
  555. response = {
  556. responses: [
  557. {
  558. aggregations: {
  559. '2': {
  560. buckets: [
  561. {
  562. '1': { value: 1000 },
  563. key: 'server-1',
  564. doc_count: 369,
  565. },
  566. {
  567. '1': { value: 2000 },
  568. key: 'server-2',
  569. doc_count: 200,
  570. },
  571. ],
  572. },
  573. },
  574. },
  575. ],
  576. };
  577. result = new ElasticResponse(targets, response).getTimeSeries();
  578. });
  579. it('should return table', function() {
  580. expect(result.data.length).to.be(1);
  581. expect(result.data[0].type).to.be('table');
  582. expect(result.data[0].rows.length).to.be(2);
  583. expect(result.data[0].rows[0][0]).to.be('server-1');
  584. expect(result.data[0].rows[0][1]).to.be(1000);
  585. expect(result.data[0].rows[0][2]).to.be(369);
  586. expect(result.data[0].rows[1][0]).to.be('server-2');
  587. expect(result.data[0].rows[1][1]).to.be(2000);
  588. });
  589. });
  590. describe('Multiple metrics of same type', function() {
  591. beforeEach(function() {
  592. targets = [
  593. {
  594. refId: 'A',
  595. metrics: [
  596. { type: 'avg', id: '1', field: 'test' },
  597. { type: 'avg', id: '2', field: 'test2' },
  598. ],
  599. bucketAggs: [{ id: '2', type: 'terms', field: 'host' }],
  600. },
  601. ];
  602. response = {
  603. responses: [
  604. {
  605. aggregations: {
  606. '2': {
  607. buckets: [
  608. {
  609. '1': { value: 1000 },
  610. '2': { value: 3000 },
  611. key: 'server-1',
  612. doc_count: 369,
  613. },
  614. ],
  615. },
  616. },
  617. },
  618. ],
  619. };
  620. result = new ElasticResponse(targets, response).getTimeSeries();
  621. });
  622. it('should include field in metric name', function() {
  623. expect(result.data[0].type).to.be('table');
  624. expect(result.data[0].rows[0][1]).to.be(1000);
  625. expect(result.data[0].rows[0][2]).to.be(3000);
  626. });
  627. });
  628. describe('Raw documents query', function() {
  629. beforeEach(function() {
  630. targets = [
  631. {
  632. refId: 'A',
  633. metrics: [{ type: 'raw_document', id: '1' }],
  634. bucketAggs: [],
  635. },
  636. ];
  637. response = {
  638. responses: [
  639. {
  640. hits: {
  641. total: 100,
  642. hits: [
  643. {
  644. _id: '1',
  645. _type: 'type',
  646. _index: 'index',
  647. _source: { sourceProp: 'asd' },
  648. fields: { fieldProp: 'field' },
  649. },
  650. {
  651. _source: { sourceProp: 'asd2' },
  652. fields: { fieldProp: 'field2' },
  653. },
  654. ],
  655. },
  656. },
  657. ],
  658. };
  659. result = new ElasticResponse(targets, response).getTimeSeries();
  660. });
  661. it('should return docs', function() {
  662. expect(result.data.length).to.be(1);
  663. expect(result.data[0].type).to.be('docs');
  664. expect(result.data[0].total).to.be(100);
  665. expect(result.data[0].datapoints.length).to.be(2);
  666. expect(result.data[0].datapoints[0].sourceProp).to.be('asd');
  667. expect(result.data[0].datapoints[0].fieldProp).to.be('field');
  668. });
  669. });
  670. });