metric_find_query.test.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import moment from 'moment';
  2. import { PrometheusDatasource } from '../datasource';
  3. import PrometheusMetricFindQuery from '../metric_find_query';
  4. import q from 'q';
  5. describe('PrometheusMetricFindQuery', () => {
  6. const instanceSettings = {
  7. url: 'proxied',
  8. directUrl: 'direct',
  9. user: 'test',
  10. password: 'mupp',
  11. jsonData: { httpMethod: 'GET' },
  12. };
  13. const raw = {
  14. from: moment.utc('2018-04-25 10:00'),
  15. to: moment.utc('2018-04-25 11:00'),
  16. };
  17. const ctx: any = {
  18. backendSrvMock: {
  19. datasourceRequest: jest.fn(() => Promise.resolve({})),
  20. },
  21. templateSrvMock: {
  22. replace: a => a,
  23. },
  24. timeSrvMock: {
  25. timeRange: () => ({
  26. from: raw.from,
  27. to: raw.to,
  28. raw: raw,
  29. }),
  30. },
  31. };
  32. ctx.setupMetricFindQuery = (data: any) => {
  33. ctx.backendSrvMock.datasourceRequest.mockReturnValue(Promise.resolve({ status: 'success', data: data.response }));
  34. return new PrometheusMetricFindQuery(ctx.ds, data.query, ctx.timeSrvMock);
  35. };
  36. beforeEach(() => {
  37. ctx.backendSrvMock.datasourceRequest.mockReset();
  38. ctx.ds = new PrometheusDatasource(instanceSettings, q, ctx.backendSrvMock, ctx.templateSrvMock, ctx.timeSrvMock);
  39. });
  40. describe('When performing metricFindQuery', () => {
  41. it('label_names() should generate label name search query', async () => {
  42. const query = ctx.setupMetricFindQuery({
  43. query: 'label_names()',
  44. response: {
  45. data: ['name1', 'name2', 'name3'],
  46. },
  47. });
  48. const results = await query.process();
  49. expect(results).toHaveLength(3);
  50. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  51. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  52. method: 'GET',
  53. url: 'proxied/api/v1/labels',
  54. silent: true,
  55. });
  56. });
  57. it('label_values(resource) should generate label search query', async () => {
  58. const query = ctx.setupMetricFindQuery({
  59. query: 'label_values(resource)',
  60. response: {
  61. data: ['value1', 'value2', 'value3'],
  62. },
  63. });
  64. const results = await query.process();
  65. expect(results).toHaveLength(3);
  66. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  67. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  68. method: 'GET',
  69. url: 'proxied/api/v1/label/resource/values',
  70. silent: true,
  71. });
  72. });
  73. it('label_values(metric, resource) should generate series query with correct time', async () => {
  74. const query = ctx.setupMetricFindQuery({
  75. query: 'label_values(metric, resource)',
  76. response: {
  77. data: [
  78. { __name__: 'metric', resource: 'value1' },
  79. { __name__: 'metric', resource: 'value2' },
  80. { __name__: 'metric', resource: 'value3' },
  81. ],
  82. },
  83. });
  84. const results = await query.process();
  85. expect(results).toHaveLength(3);
  86. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  87. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  88. method: 'GET',
  89. url: `proxied/api/v1/series?match[]=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
  90. silent: true,
  91. });
  92. });
  93. it('label_values(metric{label1="foo", label2="bar", label3="baz"}, resource) should generate series query with correct time', async () => {
  94. const query = ctx.setupMetricFindQuery({
  95. query: 'label_values(metric{label1="foo", label2="bar", label3="baz"}, resource)',
  96. response: {
  97. data: [
  98. { __name__: 'metric', resource: 'value1' },
  99. { __name__: 'metric', resource: 'value2' },
  100. { __name__: 'metric', resource: 'value3' },
  101. ],
  102. },
  103. });
  104. const results = await query.process();
  105. expect(results).toHaveLength(3);
  106. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  107. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  108. method: 'GET',
  109. url: `proxied/api/v1/series?match[]=${encodeURIComponent(
  110. 'metric{label1="foo", label2="bar", label3="baz"}'
  111. )}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
  112. silent: true,
  113. });
  114. });
  115. it('label_values(metric, resource) result should not contain empty string', async () => {
  116. const query = ctx.setupMetricFindQuery({
  117. query: 'label_values(metric, resource)',
  118. response: {
  119. data: [
  120. { __name__: 'metric', resource: 'value1' },
  121. { __name__: 'metric', resource: 'value2' },
  122. { __name__: 'metric', resource: '' },
  123. ],
  124. },
  125. });
  126. const results = await query.process();
  127. expect(results).toHaveLength(2);
  128. expect(results[0].text).toBe('value1');
  129. expect(results[1].text).toBe('value2');
  130. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  131. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  132. method: 'GET',
  133. url: `proxied/api/v1/series?match[]=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
  134. silent: true,
  135. });
  136. });
  137. it('metrics(metric.*) should generate metric name query', async () => {
  138. const query = ctx.setupMetricFindQuery({
  139. query: 'metrics(metric.*)',
  140. response: {
  141. data: ['metric1', 'metric2', 'metric3', 'nomatch'],
  142. },
  143. });
  144. const results = await query.process();
  145. expect(results).toHaveLength(3);
  146. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  147. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  148. method: 'GET',
  149. url: 'proxied/api/v1/label/__name__/values',
  150. silent: true,
  151. });
  152. });
  153. it('query_result(metric) should generate metric name query', async () => {
  154. const query = ctx.setupMetricFindQuery({
  155. query: 'query_result(metric)',
  156. response: {
  157. data: {
  158. resultType: 'vector',
  159. result: [
  160. {
  161. metric: { __name__: 'metric', job: 'testjob' },
  162. value: [1443454528.0, '3846'],
  163. },
  164. ],
  165. },
  166. },
  167. });
  168. const results = await query.process();
  169. expect(results).toHaveLength(1);
  170. expect(results[0].text).toBe('metric{job="testjob"} 3846 1443454528000');
  171. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  172. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  173. method: 'GET',
  174. url: `proxied/api/v1/query?query=metric&time=${raw.to.unix()}`,
  175. requestId: undefined,
  176. });
  177. });
  178. it('up{job="job1"} should fallback using generate series query', async () => {
  179. const query = ctx.setupMetricFindQuery({
  180. query: 'up{job="job1"}',
  181. response: {
  182. data: [
  183. { __name__: 'up', instance: '127.0.0.1:1234', job: 'job1' },
  184. { __name__: 'up', instance: '127.0.0.1:5678', job: 'job1' },
  185. { __name__: 'up', instance: '127.0.0.1:9102', job: 'job1' },
  186. ],
  187. },
  188. });
  189. const results = await query.process();
  190. expect(results).toHaveLength(3);
  191. expect(results[0].text).toBe('up{instance="127.0.0.1:1234",job="job1"}');
  192. expect(results[1].text).toBe('up{instance="127.0.0.1:5678",job="job1"}');
  193. expect(results[2].text).toBe('up{instance="127.0.0.1:9102",job="job1"}');
  194. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  195. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  196. method: 'GET',
  197. url: `proxied/api/v1/series?match[]=${encodeURIComponent(
  198. 'up{job="job1"}'
  199. )}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
  200. silent: true,
  201. });
  202. });
  203. });
  204. });