MixedDataSource.test.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import { lastValueFrom } from 'rxjs';
  2. import { getQueryOptions } from 'test/helpers/getQueryOptions';
  3. import { DatasourceSrvMock, MockObservableDataSourceApi } from 'test/mocks/datasource_srv';
  4. import { LoadingState } from '@grafana/data';
  5. import { MIXED_DATASOURCE_NAME } from './MixedDataSource';
  6. import { MixedDatasource } from './module';
  7. const defaultDS = new MockObservableDataSourceApi('DefaultDS', [{ data: ['DDD'] }]);
  8. const datasourceSrv = new DatasourceSrvMock(defaultDS, {
  9. '-- Mixed --': new MockObservableDataSourceApi('mixed'),
  10. A: new MockObservableDataSourceApi('DSA', [{ data: ['AAAA'] }]),
  11. B: new MockObservableDataSourceApi('DSB', [{ data: ['BBBB'] }]),
  12. C: new MockObservableDataSourceApi('DSC', [{ data: ['CCCC'] }]),
  13. D: new MockObservableDataSourceApi('DSD', [{ data: [] }], {}, 'syntax error near FROM'),
  14. E: new MockObservableDataSourceApi('DSE', [{ data: [] }], {}, 'syntax error near WHERE'),
  15. Loki: new MockObservableDataSourceApi('Loki', [
  16. { data: ['A'], key: 'A' },
  17. { data: ['B'], key: 'B' },
  18. ]),
  19. });
  20. const getDataSourceSrvMock = jest.fn().mockReturnValue(datasourceSrv);
  21. jest.mock('@grafana/runtime', () => ({
  22. ...(jest.requireActual('@grafana/runtime') as unknown as object),
  23. getDataSourceSrv: () => getDataSourceSrvMock(),
  24. }));
  25. describe('MixedDatasource', () => {
  26. describe('with no errors', () => {
  27. it('direct query should return results', async () => {
  28. const ds = new MixedDatasource({} as any);
  29. const requestMixed = getQueryOptions({
  30. targets: [
  31. { refId: 'QA', datasource: { uid: 'A' } }, // 1
  32. { refId: 'QB', datasource: { uid: 'B' } }, // 2
  33. { refId: 'QC', datasource: { uid: 'C' } }, // 3
  34. ],
  35. });
  36. await expect(ds.query(requestMixed)).toEmitValuesWith((results) => {
  37. expect(results.length).toBe(3);
  38. expect(results[0].data).toEqual(['AAAA']);
  39. expect(results[0].state).toEqual(LoadingState.Loading);
  40. expect(results[1].data).toEqual(['BBBB']);
  41. expect(results[2].data).toEqual(['CCCC']);
  42. expect(results[2].state).toEqual(LoadingState.Done);
  43. });
  44. });
  45. });
  46. describe('with errors', () => {
  47. it('direct query should return results', async () => {
  48. const ds = new MixedDatasource({} as any);
  49. const requestMixed = getQueryOptions({
  50. targets: [
  51. { refId: 'QA', datasource: { uid: 'A' } }, // 1
  52. { refId: 'QD', datasource: { uid: 'D' } }, // 2
  53. { refId: 'QB', datasource: { uid: 'B' } }, // 3
  54. { refId: 'QE', datasource: { uid: 'E' } }, // 4
  55. { refId: 'QC', datasource: { uid: 'C' } }, // 5
  56. ],
  57. });
  58. await expect(ds.query(requestMixed)).toEmitValuesWith((results) => {
  59. expect(results[0].data).toEqual(['AAAA']);
  60. expect(results[0].state).toEqual(LoadingState.Loading);
  61. expect(results[1].data).toEqual([]);
  62. expect(results[1].state).toEqual(LoadingState.Error);
  63. expect(results[1].error).toEqual({ message: 'DSD: syntax error near FROM' });
  64. expect(results[2].data).toEqual(['BBBB']);
  65. expect(results[2].state).toEqual(LoadingState.Loading);
  66. expect(results[3].data).toEqual([]);
  67. expect(results[3].state).toEqual(LoadingState.Error);
  68. expect(results[3].error).toEqual({ message: 'DSE: syntax error near WHERE' });
  69. expect(results[4].data).toEqual(['CCCC']);
  70. expect(results[4].state).toEqual(LoadingState.Loading);
  71. expect(results[5].data).toEqual([]);
  72. expect(results[5].state).toEqual(LoadingState.Error);
  73. expect(results[5].error).toEqual({ message: 'DSD: syntax error near FROM' });
  74. });
  75. });
  76. });
  77. it('should return both query results from the same data source', async () => {
  78. const ds = new MixedDatasource({} as any);
  79. const request: any = {
  80. targets: [
  81. { refId: 'A', datasource: { uid: 'Loki' } },
  82. { refId: 'B', datasource: { uid: 'Loki' } },
  83. { refId: 'C', datasource: { uid: 'A' } },
  84. ],
  85. };
  86. await expect(ds.query(request)).toEmitValuesWith((results) => {
  87. expect(results).toHaveLength(3);
  88. expect(results[0].key).toBe('mixed-0-A');
  89. expect(results[1].key).toBe('mixed-0-B');
  90. expect(results[1].state).toBe(LoadingState.Loading);
  91. expect(results[2].key).toBe('mixed-1-');
  92. expect(results[2].state).toBe(LoadingState.Done);
  93. });
  94. });
  95. it('should not return the error for the second time', async () => {
  96. const ds = new MixedDatasource({} as any);
  97. const request: any = {
  98. targets: [
  99. { refId: 'A', datasource: 'Loki' },
  100. { refId: 'DD', datasource: 'D' },
  101. { refId: 'C', datasource: 'A' },
  102. ],
  103. };
  104. await lastValueFrom(ds.query(request));
  105. await expect(
  106. ds.query({
  107. targets: [
  108. { refId: 'QA', datasource: { uid: 'A' } },
  109. { refId: 'QB', datasource: { uid: 'B' } },
  110. ],
  111. } as any)
  112. ).toEmitValuesWith((results) => {
  113. expect(results).toHaveLength(2);
  114. expect(results[0].key).toBe('mixed-0-');
  115. expect(results[1].key).toBe('mixed-1-');
  116. expect(results[1].state).toBe(LoadingState.Done);
  117. });
  118. });
  119. it('should filter out MixedDataSource queries', async () => {
  120. const ds = new MixedDatasource({} as any);
  121. await expect(
  122. ds.query({
  123. targets: [{ refId: 'A', datasource: { uid: MIXED_DATASOURCE_NAME, id: 'datasource' } }],
  124. } as any)
  125. ).toEmitValuesWith((results) => {
  126. expect(results).toHaveLength(1);
  127. expect(results[0].data).toHaveLength(0);
  128. });
  129. });
  130. });