buildInfo.test.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import { of, throwError } from 'rxjs';
  2. import { PromApplication } from 'app/types/unified-alerting-dto';
  3. import { discoverDataSourceFeatures } from './buildInfo';
  4. import { fetchRules } from './prometheus';
  5. import { fetchTestRulerRulesGroup } from './ruler';
  6. const fetch = jest.fn();
  7. jest.mock('./prometheus');
  8. jest.mock('./ruler');
  9. jest.mock('app/core/services/context_srv', () => {});
  10. jest.mock('@grafana/runtime', () => ({
  11. getBackendSrv: () => ({ fetch }),
  12. }));
  13. const mocks = {
  14. fetchRules: jest.mocked(fetchRules),
  15. fetchTestRulerRulesGroup: jest.mocked(fetchTestRulerRulesGroup),
  16. };
  17. beforeEach(() => jest.clearAllMocks());
  18. describe('discoverDataSourceFeatures', () => {
  19. describe('When buildinfo returns 200 response', () => {
  20. it('Should return Prometheus with disabled ruler API when application and features fields are missing', async () => {
  21. fetch.mockReturnValue(
  22. of({
  23. data: {
  24. status: 'success',
  25. data: {
  26. version: '2.32.1',
  27. },
  28. },
  29. })
  30. );
  31. const response = await discoverDataSourceFeatures({
  32. url: '/datasource/proxy',
  33. name: 'Prometheus',
  34. type: 'prometheus',
  35. });
  36. expect(response.application).toBe(PromApplication.Prometheus);
  37. expect(response.features.rulerApiEnabled).toBe(false);
  38. expect(mocks.fetchRules).not.toHaveBeenCalled();
  39. expect(mocks.fetchTestRulerRulesGroup).not.toHaveBeenCalled();
  40. });
  41. it.each([true, false])(
  42. `Should return Mimir with rulerApiEnabled set to %p according to the ruler_config_api value`,
  43. async (rulerApiEnabled) => {
  44. fetch.mockReturnValue(
  45. of({
  46. data: {
  47. status: 'success',
  48. data: {
  49. version: '2.32.1',
  50. features: {
  51. // 'true' and 'false' as strings is intentional
  52. // This is the format returned from the buildinfo endpoint
  53. ruler_config_api: rulerApiEnabled ? 'true' : 'false',
  54. },
  55. },
  56. },
  57. })
  58. );
  59. const response = await discoverDataSourceFeatures({
  60. url: '/datasource/proxy',
  61. name: 'Prometheus',
  62. type: 'prometheus',
  63. });
  64. expect(response.application).toBe(PromApplication.Mimir);
  65. expect(response.features.rulerApiEnabled).toBe(rulerApiEnabled);
  66. expect(mocks.fetchRules).not.toHaveBeenCalled();
  67. expect(mocks.fetchTestRulerRulesGroup).not.toHaveBeenCalled();
  68. }
  69. );
  70. it('When the data source is Loki should not call the buildinfo endpoint', async () => {
  71. await discoverDataSourceFeatures({ url: '/datasource/proxy', name: 'Loki', type: 'loki' });
  72. expect(fetch).not.toBeCalled();
  73. });
  74. it('When the data source is Loki should test Prom and Ruler API endpoints to discover available features', async () => {
  75. mocks.fetchTestRulerRulesGroup.mockResolvedValue(null);
  76. mocks.fetchRules.mockResolvedValue([]);
  77. const response = await discoverDataSourceFeatures({ url: '/datasource/proxy', name: 'Loki', type: 'loki' });
  78. expect(response.application).toBe(PromApplication.Lotex);
  79. expect(response.features.rulerApiEnabled).toBe(true);
  80. expect(mocks.fetchTestRulerRulesGroup).toHaveBeenCalledTimes(1);
  81. expect(mocks.fetchTestRulerRulesGroup).toHaveBeenCalledWith('Loki');
  82. expect(mocks.fetchRules).toHaveBeenCalledTimes(1);
  83. expect(mocks.fetchRules).toHaveBeenCalledWith('Loki');
  84. });
  85. });
  86. describe('When buildinfo returns 404 error', () => {
  87. it('Should return cortex with ruler API disabled when prom rules works and ruler api returns not avaiable errors', async () => {
  88. fetch.mockReturnValue(
  89. throwError(() => ({
  90. status: 404,
  91. }))
  92. );
  93. mocks.fetchTestRulerRulesGroup.mockRejectedValue({
  94. status: 404,
  95. data: {
  96. message: 'page not found',
  97. },
  98. });
  99. mocks.fetchRules.mockResolvedValue([]);
  100. const response = await discoverDataSourceFeatures({
  101. url: '/datasource/proxy',
  102. name: 'Cortex',
  103. type: 'prometheus',
  104. });
  105. expect(response.application).toBe(PromApplication.Lotex);
  106. expect(response.features.rulerApiEnabled).toBe(false);
  107. expect(mocks.fetchTestRulerRulesGroup).toHaveBeenCalledTimes(1);
  108. expect(mocks.fetchTestRulerRulesGroup).toHaveBeenCalledWith('Cortex');
  109. expect(mocks.fetchRules).toHaveBeenCalledTimes(1);
  110. expect(mocks.fetchRules).toHaveBeenCalledWith('Cortex');
  111. });
  112. it('Should return cortex with ruler API enabled when prom rules works and ruler api returns cortex error', async () => {
  113. fetch.mockReturnValue(
  114. throwError(() => ({
  115. status: 404,
  116. }))
  117. );
  118. mocks.fetchTestRulerRulesGroup.mockResolvedValue(null);
  119. mocks.fetchRules.mockResolvedValue([]);
  120. const response = await discoverDataSourceFeatures({
  121. url: '/datasource/proxy',
  122. name: 'Cortex',
  123. type: 'prometheus',
  124. });
  125. expect(response.application).toBe(PromApplication.Lotex);
  126. expect(response.features.rulerApiEnabled).toBe(true);
  127. expect(mocks.fetchTestRulerRulesGroup).toHaveBeenCalledTimes(1);
  128. expect(mocks.fetchTestRulerRulesGroup).toHaveBeenCalledWith('Cortex');
  129. expect(mocks.fetchRules).toHaveBeenCalledTimes(1);
  130. expect(mocks.fetchRules).toHaveBeenCalledWith('Cortex');
  131. });
  132. });
  133. });