datasource.test.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import LokiDatasource from './datasource';
  2. import { LokiQuery } from './types';
  3. import { getQueryOptions } from 'test/helpers/getQueryOptions';
  4. import { DataSourceApi } from '@grafana/ui';
  5. import { DataFrame } from '@grafana/data';
  6. import { BackendSrv } from 'app/core/services/backend_srv';
  7. import { TemplateSrv } from 'app/features/templating/template_srv';
  8. describe('LokiDatasource', () => {
  9. const instanceSettings: any = {
  10. url: 'myloggingurl',
  11. };
  12. const testResp = {
  13. data: {
  14. streams: [
  15. {
  16. entries: [{ ts: '2019-02-01T10:27:37.498180581Z', line: 'hello' }],
  17. labels: '{}',
  18. },
  19. ],
  20. },
  21. };
  22. describe('when querying', () => {
  23. const backendSrvMock = { datasourceRequest: jest.fn() };
  24. const backendSrv = (backendSrvMock as unknown) as BackendSrv;
  25. const templateSrvMock = ({
  26. getAdhocFilters: (): any[] => [],
  27. replace: (a: string) => a,
  28. } as unknown) as TemplateSrv;
  29. const testLimit = makeLimitTest(instanceSettings, backendSrvMock, backendSrv, templateSrvMock, testResp);
  30. test('should use default max lines when no limit given', () => {
  31. testLimit({
  32. expectedLimit: 1000,
  33. });
  34. });
  35. test('should use custom max lines if limit is set', () => {
  36. testLimit({
  37. maxLines: 20,
  38. expectedLimit: 20,
  39. });
  40. });
  41. test('should use custom maxDataPoints if set in request', () => {
  42. testLimit({
  43. maxDataPoints: 500,
  44. expectedLimit: 500,
  45. });
  46. });
  47. test('should use datasource maxLimit if maxDataPoints is higher', () => {
  48. testLimit({
  49. maxLines: 20,
  50. maxDataPoints: 500,
  51. expectedLimit: 20,
  52. });
  53. });
  54. test('should return series data', async done => {
  55. const customData = { ...(instanceSettings.jsonData || {}), maxLines: 20 };
  56. const customSettings = { ...instanceSettings, jsonData: customData };
  57. const ds = new LokiDatasource(customSettings, backendSrv, templateSrvMock);
  58. backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
  59. const options = getQueryOptions<LokiQuery>({
  60. targets: [{ expr: '{} foo', refId: 'B' }],
  61. });
  62. const res = await ds.query(options);
  63. const dataFrame = res.data[0] as DataFrame;
  64. expect(dataFrame.fields[1].values.get(0)).toBe('hello');
  65. expect(dataFrame.meta.limit).toBe(20);
  66. expect(dataFrame.meta.searchWords).toEqual(['(?i)foo']);
  67. done();
  68. });
  69. });
  70. describe('when performing testDataSource', () => {
  71. let ds: DataSourceApi<any, any>;
  72. let result: any;
  73. describe('and call succeeds', () => {
  74. beforeEach(async () => {
  75. const backendSrv = ({
  76. async datasourceRequest() {
  77. return Promise.resolve({
  78. status: 200,
  79. data: {
  80. values: ['avalue'],
  81. },
  82. });
  83. },
  84. } as unknown) as BackendSrv;
  85. ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
  86. result = await ds.testDatasource();
  87. });
  88. it('should return successfully', () => {
  89. expect(result.status).toBe('success');
  90. });
  91. });
  92. describe('and call fails with 401 error', () => {
  93. beforeEach(async () => {
  94. const backendSrv = ({
  95. async datasourceRequest() {
  96. return Promise.reject({
  97. statusText: 'Unauthorized',
  98. status: 401,
  99. data: {
  100. message: 'Unauthorized',
  101. },
  102. });
  103. },
  104. } as unknown) as BackendSrv;
  105. ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
  106. result = await ds.testDatasource();
  107. });
  108. it('should return error status and a detailed error message', () => {
  109. expect(result.status).toEqual('error');
  110. expect(result.message).toBe('Loki: Unauthorized. 401. Unauthorized');
  111. });
  112. });
  113. describe('and call fails with 404 error', () => {
  114. beforeEach(async () => {
  115. const backendSrv = ({
  116. async datasourceRequest() {
  117. return Promise.reject({
  118. statusText: 'Not found',
  119. status: 404,
  120. data: '404 page not found',
  121. });
  122. },
  123. } as unknown) as BackendSrv;
  124. ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
  125. result = await ds.testDatasource();
  126. });
  127. it('should return error status and a detailed error message', () => {
  128. expect(result.status).toEqual('error');
  129. expect(result.message).toBe('Loki: Not found. 404. 404 page not found');
  130. });
  131. });
  132. describe('and call fails with 502 error', () => {
  133. beforeEach(async () => {
  134. const backendSrv = ({
  135. async datasourceRequest() {
  136. return Promise.reject({
  137. statusText: 'Bad Gateway',
  138. status: 502,
  139. data: '',
  140. });
  141. },
  142. } as unknown) as BackendSrv;
  143. ds = new LokiDatasource(instanceSettings, backendSrv, {} as TemplateSrv);
  144. result = await ds.testDatasource();
  145. });
  146. it('should return error status and a detailed error message', () => {
  147. expect(result.status).toEqual('error');
  148. expect(result.message).toBe('Loki: Bad Gateway. 502');
  149. });
  150. });
  151. });
  152. });
  153. type LimitTestArgs = {
  154. maxDataPoints?: number;
  155. maxLines?: number;
  156. expectedLimit: number;
  157. };
  158. function makeLimitTest(
  159. instanceSettings: any,
  160. backendSrvMock: any,
  161. backendSrv: any,
  162. templateSrvMock: any,
  163. testResp: any
  164. ) {
  165. return ({ maxDataPoints, maxLines, expectedLimit }: LimitTestArgs) => {
  166. let settings = instanceSettings;
  167. if (Number.isFinite(maxLines)) {
  168. const customData = { ...(instanceSettings.jsonData || {}), maxLines: 20 };
  169. settings = { ...instanceSettings, jsonData: customData };
  170. }
  171. const ds = new LokiDatasource(settings, backendSrv, templateSrvMock);
  172. backendSrvMock.datasourceRequest = jest.fn(() => Promise.resolve(testResp));
  173. const options = getQueryOptions<LokiQuery>({ targets: [{ expr: 'foo', refId: 'B' }] });
  174. if (Number.isFinite(maxDataPoints)) {
  175. options.maxDataPoints = maxDataPoints;
  176. } else {
  177. // By default is 500
  178. delete options.maxDataPoints;
  179. }
  180. ds.query(options);
  181. expect(backendSrvMock.datasourceRequest.mock.calls.length).toBe(1);
  182. expect(backendSrvMock.datasourceRequest.mock.calls[0][0].url).toContain(`limit=${expectedLimit}`);
  183. };
  184. }