variables.test.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. import { from } from 'rxjs';
  2. import { DataQueryRequest, DataQueryResponseData, toDataFrame } from '@grafana/data';
  3. import createMockDatasource from './__mocks__/datasource';
  4. import { invalidSubscriptionError } from './__mocks__/errors';
  5. import { AzureMonitorQuery, AzureQueryType } from './types';
  6. import { VariableSupport } from './variables';
  7. jest.mock('@grafana/runtime', () => ({
  8. ...(jest.requireActual('@grafana/runtime') as unknown as object),
  9. getTemplateSrv: () => ({
  10. replace: (val: string) => {
  11. return val;
  12. },
  13. }),
  14. }));
  15. describe('VariableSupport', () => {
  16. describe('querying for grafana template variable fns', () => {
  17. it('can fetch subscriptions', (done) => {
  18. const fakeSubscriptions = ['subscriptionId'];
  19. const variableSupport = new VariableSupport(
  20. createMockDatasource({
  21. getSubscriptions: jest.fn().mockResolvedValueOnce(fakeSubscriptions),
  22. })
  23. );
  24. const mockRequest = {
  25. targets: [
  26. {
  27. refId: 'A',
  28. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  29. grafanaTemplateVariableFn: {
  30. kind: 'SubscriptionsQuery',
  31. rawQuery: 'Subscriptions()',
  32. },
  33. } as AzureMonitorQuery,
  34. ],
  35. } as DataQueryRequest<AzureMonitorQuery>;
  36. const observables = variableSupport.query(mockRequest);
  37. observables.subscribe((result: DataQueryResponseData) => {
  38. expect(result.data[0].source).toEqual(fakeSubscriptions);
  39. done();
  40. });
  41. });
  42. it('can fetch resourceGroups with a default subscriptionId', (done) => {
  43. const expectedResults = ['test'];
  44. const variableSupport = new VariableSupport(
  45. createMockDatasource({
  46. azureLogAnalyticsDatasource: {
  47. defaultSubscriptionId: 'defaultSubscriptionId',
  48. },
  49. getResourceGroups: jest.fn().mockResolvedValueOnce(expectedResults),
  50. })
  51. );
  52. const mockRequest = {
  53. targets: [
  54. {
  55. refId: 'A',
  56. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  57. grafanaTemplateVariableFn: {
  58. kind: 'ResourceGroupsQuery',
  59. rawQuery: 'ResourceGroups()',
  60. },
  61. } as AzureMonitorQuery,
  62. ],
  63. } as DataQueryRequest<AzureMonitorQuery>;
  64. const observables = variableSupport.query(mockRequest);
  65. observables.subscribe((result: DataQueryResponseData) => {
  66. expect(result.data[0].source).toEqual(expectedResults);
  67. done();
  68. });
  69. });
  70. it('can fetch resourceGroups with a subscriptionId arg', (done) => {
  71. const expectedResults = ['test'];
  72. const variableSupport = new VariableSupport(
  73. createMockDatasource({
  74. getResourceGroups: jest.fn().mockResolvedValueOnce(expectedResults),
  75. })
  76. );
  77. const mockRequest = {
  78. targets: [
  79. {
  80. refId: 'A',
  81. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  82. grafanaTemplateVariableFn: {
  83. kind: 'ResourceGroupsQuery',
  84. rawQuery: 'ResourceGroups(sub)',
  85. },
  86. } as AzureMonitorQuery,
  87. ],
  88. } as DataQueryRequest<AzureMonitorQuery>;
  89. const observables = variableSupport.query(mockRequest);
  90. observables.subscribe((result: DataQueryResponseData) => {
  91. expect(result.data[0].source).toEqual(expectedResults);
  92. done();
  93. });
  94. });
  95. it('can fetch metricDefinitions with a default subscriptionId', (done) => {
  96. const expectedResults = ['test'];
  97. const variableSupport = new VariableSupport(
  98. createMockDatasource({
  99. azureLogAnalyticsDatasource: {
  100. defaultSubscriptionId: 'defaultSubscriptionId',
  101. },
  102. getMetricDefinitions: jest.fn().mockResolvedValueOnce(expectedResults),
  103. })
  104. );
  105. const mockRequest = {
  106. targets: [
  107. {
  108. refId: 'A',
  109. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  110. grafanaTemplateVariableFn: {
  111. kind: 'MetricDefinitionsQuery',
  112. rawQuery: 'Namespaces(resourceGroup)',
  113. },
  114. } as AzureMonitorQuery,
  115. ],
  116. } as DataQueryRequest<AzureMonitorQuery>;
  117. const observables = variableSupport.query(mockRequest);
  118. observables.subscribe((result: DataQueryResponseData) => {
  119. expect(result.data[0].source).toEqual(expectedResults);
  120. done();
  121. });
  122. });
  123. it('can fetch metricDefinitions with a subscriptionId', (done) => {
  124. const expectedResults = ['test'];
  125. const variableSupport = new VariableSupport(
  126. createMockDatasource({
  127. getMetricDefinitions: jest.fn().mockResolvedValueOnce(expectedResults),
  128. })
  129. );
  130. const mockRequest = {
  131. targets: [
  132. {
  133. refId: 'A',
  134. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  135. grafanaTemplateVariableFn: {
  136. kind: 'MetricDefinitionsQuery',
  137. rawQuery: 'Namespaces(resourceGroup, subscriptionId)',
  138. },
  139. } as AzureMonitorQuery,
  140. ],
  141. } as DataQueryRequest<AzureMonitorQuery>;
  142. const observables = variableSupport.query(mockRequest);
  143. observables.subscribe((result: DataQueryResponseData) => {
  144. expect(result.data[0].source).toEqual(expectedResults);
  145. done();
  146. });
  147. });
  148. it('can fetch resourceNames with a default subscriptionId', (done) => {
  149. const expectedResults = ['test'];
  150. const variableSupport = new VariableSupport(
  151. createMockDatasource({
  152. azureLogAnalyticsDatasource: {
  153. defaultSubscriptionId: 'defaultSubscriptionId',
  154. },
  155. getResourceNames: jest.fn().mockResolvedValueOnce(expectedResults),
  156. })
  157. );
  158. const mockRequest = {
  159. targets: [
  160. {
  161. refId: 'A',
  162. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  163. grafanaTemplateVariableFn: {
  164. kind: 'ResourceNamesQuery',
  165. rawQuery: 'ResourceNames(resourceGroup, metricDefinition)',
  166. },
  167. } as AzureMonitorQuery,
  168. ],
  169. } as DataQueryRequest<AzureMonitorQuery>;
  170. const observables = variableSupport.query(mockRequest);
  171. observables.subscribe((result: DataQueryResponseData) => {
  172. expect(result.data[0].source).toEqual(expectedResults);
  173. done();
  174. });
  175. });
  176. it('can fetch resourceNames with a subscriptionId', (done) => {
  177. const expectedResults = ['test'];
  178. const variableSupport = new VariableSupport(
  179. createMockDatasource({
  180. getResourceNames: jest.fn().mockResolvedValueOnce(expectedResults),
  181. })
  182. );
  183. const mockRequest = {
  184. targets: [
  185. {
  186. refId: 'A',
  187. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  188. grafanaTemplateVariableFn: {
  189. kind: 'ResourceNamesQuery',
  190. rawQuery: 'ResourceNames(subscriptionId, resourceGroup, metricDefinition)',
  191. },
  192. } as AzureMonitorQuery,
  193. ],
  194. } as DataQueryRequest<AzureMonitorQuery>;
  195. const observables = variableSupport.query(mockRequest);
  196. observables.subscribe((result: DataQueryResponseData) => {
  197. expect(result.data[0].source).toEqual(expectedResults);
  198. done();
  199. });
  200. });
  201. it('can fetch a metricNamespace with a default subscriptionId', (done) => {
  202. const expectedResults = ['test'];
  203. const variableSupport = new VariableSupport(
  204. createMockDatasource({
  205. azureLogAnalyticsDatasource: {
  206. defaultSubscriptionId: 'defaultSubscriptionId',
  207. },
  208. azureMonitorDatasource: {
  209. getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults),
  210. },
  211. })
  212. );
  213. const mockRequest = {
  214. targets: [
  215. {
  216. refId: 'A',
  217. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  218. grafanaTemplateVariableFn: {
  219. kind: 'MetricNamespaceQuery',
  220. rawQuery: 'metricNamespace(resourceGroup, metricDefinition, resourceName)',
  221. },
  222. } as AzureMonitorQuery,
  223. ],
  224. } as DataQueryRequest<AzureMonitorQuery>;
  225. const observables = variableSupport.query(mockRequest);
  226. observables.subscribe((result: DataQueryResponseData) => {
  227. expect(result.data[0].source).toEqual(expectedResults);
  228. done();
  229. });
  230. });
  231. it('can fetch a metricNamespace with a subscriptionId', (done) => {
  232. const expectedResults = ['test'];
  233. const variableSupport = new VariableSupport(
  234. createMockDatasource({
  235. azureMonitorDatasource: {
  236. getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults),
  237. },
  238. })
  239. );
  240. const mockRequest = {
  241. targets: [
  242. {
  243. refId: 'A',
  244. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  245. grafanaTemplateVariableFn: {
  246. kind: 'MetricNamespaceQuery',
  247. rawQuery: 'metricNamespace(subscriptionId, resourceGroup, metricDefinition, resourceName)',
  248. },
  249. } as AzureMonitorQuery,
  250. ],
  251. } as DataQueryRequest<AzureMonitorQuery>;
  252. const observables = variableSupport.query(mockRequest);
  253. observables.subscribe((result: DataQueryResponseData) => {
  254. expect(result.data[0].source).toEqual(expectedResults);
  255. done();
  256. });
  257. });
  258. it('can fetch metricNames with a default subscriptionId', (done) => {
  259. const expectedResults = ['test'];
  260. const variableSupport = new VariableSupport(
  261. createMockDatasource({
  262. azureLogAnalyticsDatasource: {
  263. defaultSubscriptionId: 'defaultSubscriptionId',
  264. },
  265. azureMonitorDatasource: {
  266. getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults),
  267. },
  268. })
  269. );
  270. const mockRequest = {
  271. targets: [
  272. {
  273. refId: 'A',
  274. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  275. grafanaTemplateVariableFn: {
  276. kind: 'MetricNamesQuery',
  277. rawQuery: 'metricNames(resourceGroup, metricDefinition, resourceName, metricNamespace)',
  278. },
  279. } as AzureMonitorQuery,
  280. ],
  281. } as DataQueryRequest<AzureMonitorQuery>;
  282. const observables = variableSupport.query(mockRequest);
  283. observables.subscribe((result: DataQueryResponseData) => {
  284. expect(result.data[0].source).toEqual(expectedResults);
  285. done();
  286. });
  287. });
  288. it('can fetch metricNames with a subscriptionId', (done) => {
  289. const expectedResults = ['test'];
  290. const variableSupport = new VariableSupport(
  291. createMockDatasource({
  292. azureMonitorDatasource: {
  293. getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults),
  294. },
  295. })
  296. );
  297. const mockRequest = {
  298. targets: [
  299. {
  300. refId: 'A',
  301. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  302. grafanaTemplateVariableFn: {
  303. kind: 'MetricNamesQuery',
  304. rawQuery: 'metricNames(subscription, resourceGroup, metricDefinition, resourceName, metricNamespace)',
  305. },
  306. } as AzureMonitorQuery,
  307. ],
  308. } as DataQueryRequest<AzureMonitorQuery>;
  309. const observables = variableSupport.query(mockRequest);
  310. observables.subscribe((result: DataQueryResponseData) => {
  311. expect(result.data[0].source).toEqual(expectedResults);
  312. done();
  313. });
  314. });
  315. it('can fetch workspaces with a default subscriptionId', (done) => {
  316. const expectedResults = ['test'];
  317. const variableSupport = new VariableSupport(
  318. createMockDatasource({
  319. azureLogAnalyticsDatasource: {
  320. defaultSubscriptionId: 'defaultSubscriptionId',
  321. getWorkspaces: jest.fn().mockResolvedValueOnce(expectedResults),
  322. },
  323. })
  324. );
  325. const mockRequest = {
  326. targets: [
  327. {
  328. refId: 'A',
  329. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  330. grafanaTemplateVariableFn: {
  331. kind: 'WorkspacesQuery',
  332. rawQuery: 'workspaces()',
  333. },
  334. } as AzureMonitorQuery,
  335. ],
  336. } as DataQueryRequest<AzureMonitorQuery>;
  337. const observables = variableSupport.query(mockRequest);
  338. observables.subscribe((result: DataQueryResponseData) => {
  339. expect(result.data[0].source).toEqual(expectedResults);
  340. done();
  341. });
  342. });
  343. it('can fetch workspaces with a subscriptionId', (done) => {
  344. const expectedResults = ['test'];
  345. const variableSupport = new VariableSupport(
  346. createMockDatasource({
  347. azureLogAnalyticsDatasource: {
  348. getWorkspaces: jest.fn().mockResolvedValueOnce(expectedResults),
  349. },
  350. })
  351. );
  352. const mockRequest = {
  353. targets: [
  354. {
  355. refId: 'A',
  356. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  357. grafanaTemplateVariableFn: {
  358. kind: 'WorkspacesQuery',
  359. rawQuery: 'workspaces(subscriptionId)',
  360. },
  361. } as AzureMonitorQuery,
  362. ],
  363. } as DataQueryRequest<AzureMonitorQuery>;
  364. const observables = variableSupport.query(mockRequest);
  365. observables.subscribe((result: DataQueryResponseData) => {
  366. expect(result.data[0].source).toEqual(expectedResults);
  367. done();
  368. });
  369. });
  370. it('can handle legacy string queries', (done) => {
  371. const expectedResults = ['test'];
  372. const variableSupport = new VariableSupport(
  373. createMockDatasource({
  374. azureMonitorDatasource: {
  375. defaultSubscriptionId: 'defaultSubscriptionId',
  376. },
  377. getMetricDefinitions: jest.fn((sub: string, rg: string) => {
  378. if (sub === 'subscriptionId' && rg === 'resourceGroup') {
  379. return Promise.resolve(expectedResults);
  380. }
  381. return Promise.resolve([`getMetricDefinitions unexpected input: ${sub}, ${rg}`]);
  382. }),
  383. })
  384. );
  385. const mockRequest = {
  386. targets: ['Namespaces(subscriptionId, resourceGroup)' as unknown as AzureMonitorQuery],
  387. } as DataQueryRequest<AzureMonitorQuery>;
  388. const observables = variableSupport.query(mockRequest);
  389. observables.subscribe((result: DataQueryResponseData) => {
  390. expect(result.data[0].source).toEqual(expectedResults);
  391. done();
  392. });
  393. });
  394. it('returns an empty array for unknown queries', (done) => {
  395. const variableSupport = new VariableSupport(createMockDatasource());
  396. const mockRequest = {
  397. targets: [
  398. {
  399. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  400. grafanaTemplateVariableFn: {
  401. rawQuery: 'nonsense',
  402. },
  403. } as AzureMonitorQuery,
  404. ],
  405. } as DataQueryRequest<AzureMonitorQuery>;
  406. const observables = variableSupport.query(mockRequest);
  407. observables.subscribe((result: DataQueryResponseData) => {
  408. expect(result.data).toEqual([]);
  409. done();
  410. });
  411. });
  412. it('should return None when there is no data', (done) => {
  413. const variableSupport = new VariableSupport(
  414. createMockDatasource({
  415. azureLogAnalyticsDatasource: {
  416. defaultSubscriptionId: 'defaultSubscriptionId',
  417. },
  418. azureMonitorDatasource: {
  419. getMetricNames: jest.fn().mockResolvedValueOnce([]),
  420. },
  421. })
  422. );
  423. const mockRequest = {
  424. targets: [
  425. {
  426. refId: 'A',
  427. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  428. grafanaTemplateVariableFn: {
  429. kind: 'MetricNamesQuery',
  430. rawQuery: 'metricNames(resourceGroup, metricDefinition, resourceName, metricNamespace)',
  431. },
  432. } as AzureMonitorQuery,
  433. ],
  434. } as DataQueryRequest<AzureMonitorQuery>;
  435. const observables = variableSupport.query(mockRequest);
  436. observables.subscribe((result: DataQueryResponseData) => {
  437. expect(result.data.length).toBe(0);
  438. done();
  439. });
  440. });
  441. });
  442. it('passes on the query to the main datasource for all non-grafana template variable fns', (done) => {
  443. const expectedResults = ['test'];
  444. const variableSupport = new VariableSupport(
  445. createMockDatasource({
  446. query: () =>
  447. from(
  448. Promise.resolve({
  449. data: [toDataFrame(expectedResults)],
  450. })
  451. ),
  452. })
  453. );
  454. const mockRequest = {
  455. targets: [
  456. {
  457. queryType: AzureQueryType.LogAnalytics,
  458. azureLogAnalytics: {
  459. query: 'some log thing',
  460. },
  461. } as AzureMonitorQuery,
  462. ],
  463. } as DataQueryRequest<AzureMonitorQuery>;
  464. const observables = variableSupport.query(mockRequest);
  465. observables.subscribe((result: DataQueryResponseData) => {
  466. expect(result.data[0].source).toEqual(expectedResults);
  467. done();
  468. });
  469. });
  470. it('should handle http error', (done) => {
  471. const error = invalidSubscriptionError();
  472. const variableSupport = new VariableSupport(
  473. createMockDatasource({
  474. azureLogAnalyticsDatasource: {
  475. defaultSubscriptionId: 'defaultSubscriptionId',
  476. },
  477. getResourceGroups: jest.fn().mockRejectedValue(error),
  478. })
  479. );
  480. const mockRequest = {
  481. targets: [
  482. {
  483. refId: 'A',
  484. queryType: AzureQueryType.GrafanaTemplateVariableFn,
  485. grafanaTemplateVariableFn: {
  486. kind: 'ResourceGroupsQuery',
  487. rawQuery: 'ResourceGroups()',
  488. },
  489. } as AzureMonitorQuery,
  490. ],
  491. } as DataQueryRequest<AzureMonitorQuery>;
  492. const observables = variableSupport.query(mockRequest);
  493. observables.subscribe((result: DataQueryResponseData) => {
  494. expect(result.error?.message).toBe(error.data.error.message);
  495. done();
  496. });
  497. });
  498. });