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