metric_find_query.test.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import { PrometheusDatasource } from '../datasource';
  2. import PrometheusMetricFindQuery from '../metric_find_query';
  3. import q from 'q';
  4. import { toUtc } from '@grafana/ui/src/utils/moment_wrapper';
  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: toUtc('2018-04-25 10:00'),
  15. to: toUtc('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. headers: {},
  56. });
  57. });
  58. it('label_values(resource) should generate label search query', async () => {
  59. const query = ctx.setupMetricFindQuery({
  60. query: 'label_values(resource)',
  61. response: {
  62. data: ['value1', 'value2', 'value3'],
  63. },
  64. });
  65. const results = await query.process();
  66. expect(results).toHaveLength(3);
  67. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  68. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  69. method: 'GET',
  70. url: 'proxied/api/v1/label/resource/values',
  71. silent: true,
  72. headers: {},
  73. });
  74. });
  75. it('label_values(metric, resource) should generate series query with correct time', async () => {
  76. const query = ctx.setupMetricFindQuery({
  77. query: 'label_values(metric, resource)',
  78. response: {
  79. data: [
  80. { __name__: 'metric', resource: 'value1' },
  81. { __name__: 'metric', resource: 'value2' },
  82. { __name__: 'metric', resource: 'value3' },
  83. ],
  84. },
  85. });
  86. const results = await query.process();
  87. expect(results).toHaveLength(3);
  88. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  89. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  90. method: 'GET',
  91. url: `proxied/api/v1/series?match[]=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
  92. silent: true,
  93. headers: {},
  94. });
  95. });
  96. it('label_values(metric{label1="foo", label2="bar", label3="baz"}, resource) should generate series query with correct time', async () => {
  97. const query = ctx.setupMetricFindQuery({
  98. query: 'label_values(metric{label1="foo", label2="bar", label3="baz"}, resource)',
  99. response: {
  100. data: [
  101. { __name__: 'metric', resource: 'value1' },
  102. { __name__: 'metric', resource: 'value2' },
  103. { __name__: 'metric', resource: 'value3' },
  104. ],
  105. },
  106. });
  107. const results = await query.process();
  108. expect(results).toHaveLength(3);
  109. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  110. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  111. method: 'GET',
  112. url: `proxied/api/v1/series?match[]=${encodeURIComponent(
  113. 'metric{label1="foo", label2="bar", label3="baz"}'
  114. )}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
  115. silent: true,
  116. headers: {},
  117. });
  118. });
  119. it('label_values(metric, resource) result should not contain empty string', async () => {
  120. const query = ctx.setupMetricFindQuery({
  121. query: 'label_values(metric, resource)',
  122. response: {
  123. data: [
  124. { __name__: 'metric', resource: 'value1' },
  125. { __name__: 'metric', resource: 'value2' },
  126. { __name__: 'metric', resource: '' },
  127. ],
  128. },
  129. });
  130. const results = await query.process();
  131. expect(results).toHaveLength(2);
  132. expect(results[0].text).toBe('value1');
  133. expect(results[1].text).toBe('value2');
  134. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  135. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  136. method: 'GET',
  137. url: `proxied/api/v1/series?match[]=metric&start=${raw.from.unix()}&end=${raw.to.unix()}`,
  138. silent: true,
  139. headers: {},
  140. });
  141. });
  142. it('metrics(metric.*) should generate metric name query', async () => {
  143. const query = ctx.setupMetricFindQuery({
  144. query: 'metrics(metric.*)',
  145. response: {
  146. data: ['metric1', 'metric2', 'metric3', 'nomatch'],
  147. },
  148. });
  149. const results = await query.process();
  150. expect(results).toHaveLength(3);
  151. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  152. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  153. method: 'GET',
  154. url: 'proxied/api/v1/label/__name__/values',
  155. silent: true,
  156. headers: {},
  157. });
  158. });
  159. it('query_result(metric) should generate metric name query', async () => {
  160. const query = ctx.setupMetricFindQuery({
  161. query: 'query_result(metric)',
  162. response: {
  163. data: {
  164. resultType: 'vector',
  165. result: [
  166. {
  167. metric: { __name__: 'metric', job: 'testjob' },
  168. value: [1443454528.0, '3846'],
  169. },
  170. ],
  171. },
  172. },
  173. });
  174. const results = await query.process();
  175. expect(results).toHaveLength(1);
  176. expect(results[0].text).toBe('metric{job="testjob"} 3846 1443454528000');
  177. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  178. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  179. method: 'GET',
  180. url: `proxied/api/v1/query?query=metric&time=${raw.to.unix()}`,
  181. requestId: undefined,
  182. headers: {},
  183. });
  184. });
  185. it('up{job="job1"} should fallback using generate series query', async () => {
  186. const query = ctx.setupMetricFindQuery({
  187. query: 'up{job="job1"}',
  188. response: {
  189. data: [
  190. { __name__: 'up', instance: '127.0.0.1:1234', job: 'job1' },
  191. { __name__: 'up', instance: '127.0.0.1:5678', job: 'job1' },
  192. { __name__: 'up', instance: '127.0.0.1:9102', job: 'job1' },
  193. ],
  194. },
  195. });
  196. const results = await query.process();
  197. expect(results).toHaveLength(3);
  198. expect(results[0].text).toBe('up{instance="127.0.0.1:1234",job="job1"}');
  199. expect(results[1].text).toBe('up{instance="127.0.0.1:5678",job="job1"}');
  200. expect(results[2].text).toBe('up{instance="127.0.0.1:9102",job="job1"}');
  201. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
  202. expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
  203. method: 'GET',
  204. url: `proxied/api/v1/series?match[]=${encodeURIComponent(
  205. 'up{job="job1"}'
  206. )}&start=${raw.from.unix()}&end=${raw.to.unix()}`,
  207. silent: true,
  208. headers: {},
  209. });
  210. });
  211. });
  212. });