diff --git a/public/app/plugins/panel/logs/LogsPanel.test.tsx b/public/app/plugins/panel/logs/LogsPanel.test.tsx
index 5e6130ac227..7c3fdbf0726 100644
--- a/public/app/plugins/panel/logs/LogsPanel.test.tsx
+++ b/public/app/plugins/panel/logs/LogsPanel.test.tsx
@@ -3,7 +3,17 @@ import userEvent from '@testing-library/user-event';
import React, { ComponentProps } from 'react';
import { DatasourceSrvMock, MockDataSourceApi } from 'test/mocks/datasource_srv';
-import { LoadingState, createDataFrame, FieldType, LogsSortOrder, CoreApp } from '@grafana/data';
+import {
+ LoadingState,
+ createDataFrame,
+ FieldType,
+ LogsSortOrder,
+ CoreApp,
+ getDefaultTimeRange,
+ LogsDedupStrategy,
+ EventBusSrv,
+} from '@grafana/data';
+import * as styles from 'app/features/logs/components/getLogRowStyles';
import { LogRowContextModal } from 'app/features/logs/components/log-context/LogRowContextModal';
import { LogsPanel } from './LogsPanel';
@@ -252,15 +262,76 @@ describe('LogsPanel', () => {
});
});
});
+
+ describe('Performance regressions', () => {
+ const series = [
+ createDataFrame({
+ refId: 'A',
+ fields: [
+ {
+ name: 'time',
+ type: FieldType.time,
+ values: ['2019-04-26T09:28:11.352440161Z'],
+ },
+ {
+ name: 'message',
+ type: FieldType.string,
+ values: ['logline text'],
+ labels: {
+ app: 'common_app',
+ job: 'common_job',
+ },
+ },
+ ],
+ }),
+ ];
+
+ beforeEach(() => {
+ /**
+ * For the lack of a better option, we spy on getLogRowStyles calls to count re-renders.
+ */
+ jest.spyOn(styles, 'getLogRowStyles');
+ jest.mocked(styles.getLogRowStyles).mockClear();
+ });
+
+ it('does not rerender without changes', async () => {
+ const { rerender, props } = setup({
+ data: {
+ series,
+ },
+ });
+
+ expect(await screen.findByRole('row')).toBeInTheDocument();
+
+ rerender();
+
+ expect(await screen.findByRole('row')).toBeInTheDocument();
+ expect(styles.getLogRowStyles).toHaveBeenCalledTimes(3);
+ });
+
+ it('rerenders when prop changes', async () => {
+ const { rerender, props } = setup({
+ data: {
+ series,
+ },
+ });
+
+ expect(await screen.findByRole('row')).toBeInTheDocument();
+
+ rerender();
+
+ expect(await screen.findByRole('row')).toBeInTheDocument();
+ expect(jest.mocked(styles.getLogRowStyles).mock.calls.length).toBeGreaterThan(3);
+ });
+ });
});
const setup = (propsOverrides?: {}) => {
- const props = {
+ const props: LogsPanelProps = {
data: {
error: undefined,
request: {
panelId: 4,
- dashboardId: 123,
app: 'dashboard',
requestId: 'A',
timezone: 'browser',
@@ -268,17 +339,44 @@ const setup = (propsOverrides?: {}) => {
intervalMs: 30000,
maxDataPoints: 823,
targets: [],
- range: {},
+ range: getDefaultTimeRange(),
+ scopedVars: {},
+ startTime: 1,
},
series: [],
state: LoadingState.Done,
+ timeRange: getDefaultTimeRange(),
},
timeZone: 'utc',
- options: {},
+ timeRange: getDefaultTimeRange(),
+ options: {
+ showLabels: false,
+ showTime: false,
+ wrapLogMessage: false,
+ showCommonLabels: false,
+ prettifyLogMessage: false,
+ sortOrder: LogsSortOrder.Descending,
+ dedupStrategy: LogsDedupStrategy.none,
+ enableLogDetails: false,
+ showLogContextToggle: false,
+ },
title: 'Logs panel',
id: 1,
+ transparent: false,
+ width: 400,
+ height: 100,
+ renderCounter: 0,
+ fieldConfig: {
+ defaults: {},
+ overrides: [],
+ },
+ eventBus: new EventBusSrv(),
+ onOptionsChange: jest.fn(),
+ onFieldConfigChange: jest.fn(),
+ replaceVariables: jest.fn(),
+ onChangeTimeRange: jest.fn(),
...propsOverrides,
- } as unknown as LogsPanelProps;
+ };
- return render();
+ return { ...render(), props };
};