Chore: Refactors flaky Frontend test (#35645)

* Chore: Refactors flaky Frontend test

* Refactor: update after PR comments
This commit is contained in:
Hugo Häggmark 2021-06-15 13:33:24 +02:00 committed by GitHub
parent 303352a89b
commit 3395142ece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,9 +1,8 @@
import { asyncScheduler, Observable, of, scheduled } from 'rxjs';
import { AlertState, getDefaultTimeRange, LoadingState, PanelData, toDataFrame } from '@grafana/data'; import { AlertState, getDefaultTimeRange, LoadingState, PanelData, toDataFrame } from '@grafana/data';
import { DashboardQueryRunnerResult } from './DashboardQueryRunner/types'; import { DashboardQueryRunnerResult } from './DashboardQueryRunner/types';
import { mergePanelAndDashData } from './mergePanelAndDashData'; import { mergePanelAndDashData } from './mergePanelAndDashData';
import { delay } from 'rxjs/operators'; import { TestScheduler } from 'rxjs/testing';
function getTestContext() { function getTestContext() {
const timeRange = getDefaultTimeRange(); const timeRange = getDefaultTimeRange();
@ -17,104 +16,123 @@ function getTestContext() {
annotations: [{ id: 'dashData' }], annotations: [{ id: 'dashData' }],
alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' },
}; };
const panelObservable: Observable<PanelData> = scheduled(of(panelData), asyncScheduler); const scheduler: TestScheduler = new TestScheduler((actual, expected) => {
const dashObservable: Observable<DashboardQueryRunnerResult> = scheduled(of(dashData), asyncScheduler); expect(actual).toEqual(expected);
});
return { timeRange, panelObservable, dashObservable }; return { timeRange, scheduler, panelData, dashData };
} }
describe('mergePanelAndDashboardData', () => { describe('mergePanelAndDashboardData', () => {
describe('when both results are fast', () => { describe('when both results are fast', () => {
it('then just combine the results', async () => { it('then just combine the results', () => {
const { dashObservable, panelObservable, timeRange } = getTestContext(); const { panelData, dashData, timeRange, scheduler } = getTestContext();
await expect(mergePanelAndDashData(panelObservable, dashObservable)).toEmitValuesWith((received) => { scheduler.run(({ cold, expectObservable }) => {
expect(received).toHaveLength(1); const panelObservable = cold('10ms a', { a: panelData });
const results = received[0]; const dashObservable = cold('10ms a', { a: dashData });
expect(results).toEqual({
state: LoadingState.Done, const result = mergePanelAndDashData(panelObservable, dashObservable);
series: [],
annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], expectObservable(result).toBe('10ms a', {
alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, a: {
timeRange, state: LoadingState.Done,
series: [],
annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])],
alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' },
timeRange,
},
}); });
}); });
scheduler.flush();
}); });
}); });
describe('when dashboard results are slow', () => { describe('when dashboard results are slow', () => {
it('then flush panel data first', async () => { it('then flush panel data first', () => {
const { dashObservable, panelObservable, timeRange } = getTestContext(); const { panelData, dashData, timeRange, scheduler } = getTestContext();
await expect(mergePanelAndDashData(panelObservable, dashObservable.pipe(delay(250)))).toEmitValuesWith( scheduler.run(({ cold, expectObservable }) => {
(received) => { const panelObservable = cold('10ms a', { a: panelData });
expect(received).toHaveLength(2); const dashObservable = cold('210ms a', { a: dashData });
const fastResults = received[0];
const slowResults = received[1]; const result = mergePanelAndDashData(panelObservable, dashObservable);
expect(fastResults).toEqual({
expectObservable(result).toBe('200ms a 9ms b', {
a: {
state: LoadingState.Done, state: LoadingState.Done,
series: [], series: [],
annotations: [toDataFrame([{ id: 'panelData' }])], annotations: [toDataFrame([{ id: 'panelData' }])],
alertState: undefined,
timeRange, timeRange,
}); },
expect(slowResults).toEqual({ b: {
state: LoadingState.Done, state: LoadingState.Done,
series: [], series: [],
annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])],
alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' },
timeRange, timeRange,
}); },
} });
); });
scheduler.flush();
}); });
}); });
describe('when panel results are slow', () => { describe('when panel results are slow', () => {
it('then just combine the results', async () => { it('then just combine the results', () => {
const { dashObservable, panelObservable, timeRange } = getTestContext(); const { panelData, dashData, timeRange, scheduler } = getTestContext();
await expect(mergePanelAndDashData(panelObservable.pipe(delay(250)), dashObservable)).toEmitValuesWith( scheduler.run(({ cold, expectObservable }) => {
(received) => { const panelObservable = cold('210ms a', { a: panelData });
expect(received).toHaveLength(1); const dashObservable = cold('10ms a', { a: dashData });
const results = received[0];
expect(results).toEqual({ const result = mergePanelAndDashData(panelObservable, dashObservable);
expectObservable(result).toBe('210ms a', {
a: {
state: LoadingState.Done, state: LoadingState.Done,
series: [], series: [],
annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])],
alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' },
timeRange, timeRange,
}); },
} });
); });
scheduler.flush();
}); });
}); });
describe('when both results are slow', () => { describe('when both results are slow', () => {
it('then flush panel data first', async () => { it('then flush panel data first', () => {
const { dashObservable, panelObservable, timeRange } = getTestContext(); const { panelData, dashData, timeRange, scheduler } = getTestContext();
await expect( scheduler.run(({ cold, expectObservable }) => {
mergePanelAndDashData(panelObservable.pipe(delay(250)), dashObservable.pipe(delay(250))) const panelObservable = cold('210ms a', { a: panelData });
).toEmitValuesWith((received) => { const dashObservable = cold('210ms a', { a: dashData });
expect(received).toHaveLength(2);
const fastResults = received[0]; const result = mergePanelAndDashData(panelObservable, dashObservable);
const slowResults = received[1];
expect(fastResults).toEqual({ expectObservable(result).toBe('210ms (ab)', {
state: LoadingState.Done, a: {
series: [], state: LoadingState.Done,
annotations: [toDataFrame([{ id: 'panelData' }])], series: [],
alertState: undefined, annotations: [toDataFrame([{ id: 'panelData' }])],
timeRange, timeRange,
}); },
expect(slowResults).toEqual({ b: {
state: LoadingState.Done, state: LoadingState.Done,
series: [], series: [],
annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])], annotations: [toDataFrame([{ id: 'panelData' }]), toDataFrame([{ id: 'dashData' }])],
alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' }, alertState: { id: 1, state: AlertState.OK, dashboardId: 1, panelId: 1, newStateDate: '' },
timeRange, timeRange,
},
}); });
}); });
scheduler.flush();
}); });
}); });
}); });