D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
proc
/
thread-self
/
root
/
usr
/
share
/
grafana
/
public
/
app
/
features
/
explore
/
Logs
/
Filename :
LogsTable.test.tsx
back
Copy
import { render, screen, waitFor } from '@testing-library/react'; import React, { ComponentProps } from 'react'; import { DataFrame, FieldType, LogsSortOrder, standardTransformersRegistry, toUtc } from '@grafana/data'; import { organizeFieldsTransformer } from '@grafana/data/src/transformations/transformers/organize'; import { config } from '@grafana/runtime'; import { extractFieldsTransformer } from 'app/features/transformers/extractFields/extractFields'; import { parseLogsFrame } from '../../logs/logsFrame'; import { LogsTable } from './LogsTable'; import { getMockElasticFrame, getMockLokiFrame, getMockLokiFrameDataPlane } from './utils/testMocks.test'; jest.mock('@grafana/runtime', () => { const actual = jest.requireActual('@grafana/runtime'); return { ...actual, getTemplateSrv: () => ({ replace: (val: string) => (val ? val.replace('$input', '10').replace('$window', '10s') : val), }), }; }); const getComponent = (partialProps?: Partial<ComponentProps<typeof LogsTable>>, logs?: DataFrame) => { const testDataFrame = { fields: [ { config: {}, name: 'Time', type: FieldType.time, values: ['2019-01-01 10:00:00', '2019-01-01 11:00:00', '2019-01-01 12:00:00'], }, { config: {}, name: 'line', type: FieldType.string, values: ['log message 1', 'log message 2', 'log message 3'], }, { config: {}, name: 'tsNs', type: FieldType.string, values: ['ts1', 'ts2', 'ts3'], }, { config: {}, name: 'labels', type: FieldType.other, typeInfo: { frame: 'json.RawMessage', }, values: [{ foo: 'bar' }, { foo: 'bar' }, { foo: 'bar' }], }, ], length: 3, }; const logsFrame = parseLogsFrame(testDataFrame); return ( <LogsTable logsFrame={logsFrame} height={400} columnsWithMeta={{ Time: { active: true, percentOfLinesWithLabel: 3, index: 0 }, line: { active: true, percentOfLinesWithLabel: 3, index: 1 }, }} logsSortOrder={LogsSortOrder.Descending} splitOpen={() => undefined} timeZone={'utc'} width={50} range={{ from: toUtc('2019-01-01 10:00:00'), to: toUtc('2019-01-01 16:00:00'), raw: { from: 'now-1h', to: 'now' }, }} dataFrame={logs ?? testDataFrame} {...partialProps} /> ); }; const setup = (partialProps?: Partial<ComponentProps<typeof LogsTable>>, logs?: DataFrame) => { return render( getComponent( { ...partialProps, }, logs ) ); }; describe('LogsTable', () => { beforeAll(() => { const transformers = [extractFieldsTransformer, organizeFieldsTransformer]; standardTransformersRegistry.setInit(() => { return transformers.map((t) => { return { id: t.id, aliasIds: t.aliasIds, name: t.name, transformation: t, description: t.description, editor: () => null, }; }); }); }); let originalVisualisationTypeValue = config.featureToggles.logsExploreTableVisualisation; beforeAll(() => { originalVisualisationTypeValue = config.featureToggles.logsExploreTableVisualisation; config.featureToggles.logsExploreTableVisualisation = true; }); afterAll(() => { config.featureToggles.logsExploreTableVisualisation = originalVisualisationTypeValue; }); it('should render 4 table rows', async () => { setup(); await waitFor(() => { const rows = screen.getAllByRole('row'); // tableFrame has 3 rows + 1 header row expect(rows.length).toBe(4); }); }); it('should render extracted labels as columns (elastic)', async () => { setup({ dataFrame: getMockElasticFrame(), columnsWithMeta: { level: { active: true, percentOfLinesWithLabel: 3, index: 3 }, counter: { active: true, percentOfLinesWithLabel: 3, index: 2 }, line: { active: true, percentOfLinesWithLabel: 3, index: 1 }, '@timestamp': { active: true, percentOfLinesWithLabel: 3, index: 0 }, }, }); await waitFor(() => { const columns = screen.getAllByRole('columnheader'); expect(columns[0].textContent).toContain('@timestamp'); expect(columns[1].textContent).toContain('line'); expect(columns[2].textContent).toContain('counter'); expect(columns[3].textContent).toContain('level'); }); }); it('should render extracted labels as columns (loki)', async () => { setup({ columnsWithMeta: { Time: { active: true, percentOfLinesWithLabel: 3, index: 0 }, line: { active: true, percentOfLinesWithLabel: 3, index: 1 }, foo: { active: true, percentOfLinesWithLabel: 3, index: 2 }, }, }); await waitFor(() => { const columns = screen.getAllByRole('columnheader'); expect(columns[0].textContent).toContain('Time'); expect(columns[1].textContent).toContain('line'); expect(columns[2].textContent).toContain('foo'); }); }); it('should not render `tsNs` column', async () => { setup(undefined, getMockLokiFrame()); await waitFor(() => { const columns = screen.queryAllByRole('columnheader', { name: 'tsNs' }); expect(columns.length).toBe(0); }); }); it('should render numeric field aligned right', async () => { setup( { columnsWithMeta: { Time: { active: true, percentOfLinesWithLabel: 100, index: 0 }, line: { active: true, percentOfLinesWithLabel: 100, index: 1 }, tsNs: { active: true, percentOfLinesWithLabel: 100, index: 2 }, }, }, getMockLokiFrame() ); await waitFor(() => { const columns = screen.queryAllByRole('columnheader', { name: 'tsNs' }); expect(columns.length).toBe(1); }); const cells = screen.queryAllByRole('cell'); expect(cells[cells.length - 1].style.textAlign).toBe('right'); }); it('should not render `labels`', async () => { setup(); await waitFor(() => { const columns = screen.queryAllByRole('columnheader', { name: 'labels' }); expect(columns.length).toBe(0); }); }); describe('LogsTable (loki dataplane)', () => { let originalVisualisationTypeValue = config.featureToggles.logsExploreTableVisualisation; let originalLokiDataplaneValue = config.featureToggles.lokiLogsDataplane; beforeAll(() => { originalVisualisationTypeValue = config.featureToggles.logsExploreTableVisualisation; originalLokiDataplaneValue = config.featureToggles.lokiLogsDataplane; config.featureToggles.logsExploreTableVisualisation = true; config.featureToggles.lokiLogsDataplane = true; }); afterAll(() => { config.featureToggles.logsExploreTableVisualisation = originalVisualisationTypeValue; config.featureToggles.lokiLogsDataplane = originalLokiDataplaneValue; }); it('should render 4 table rows', async () => { setup( { columnsWithMeta: { timestamp: { active: true, percentOfLinesWithLabel: 3, index: 0 }, body: { active: true, percentOfLinesWithLabel: 3, index: 1 }, }, }, getMockLokiFrameDataPlane() ); await waitFor(() => { const rows = screen.getAllByRole('row'); // tableFrame has 3 rows + 1 header row expect(rows.length).toBe(4); }); }); it('should render a datalink for each row', async () => { render( getComponent( { columnsWithMeta: { traceID: { active: true, percentOfLinesWithLabel: 3, index: 0 }, }, }, getMockLokiFrameDataPlane() ) ); await waitFor(() => { const links = screen.getAllByRole('link'); expect(links.length).toBe(3); }); }); it('should not render `labels`', async () => { setup( { columnsWithMeta: { timestamp: { active: true, percentOfLinesWithLabel: 100, index: 0 }, body: { active: true, percentOfLinesWithLabel: 100, index: 1 }, }, }, getMockLokiFrameDataPlane() ); await waitFor(() => { const columns = screen.queryAllByRole('columnheader', { name: 'labels' }); expect(columns.length).toBe(0); }); }); it('should not render `tsNs`', async () => { setup( { columnsWithMeta: { timestamp: { active: true, percentOfLinesWithLabel: 100, index: 0 }, body: { active: true, percentOfLinesWithLabel: 100, index: 1 }, }, }, getMockLokiFrameDataPlane() ); await waitFor(() => { const columns = screen.queryAllByRole('columnheader', { name: 'tsNs' }); expect(columns.length).toBe(0); }); }); it('should render extracted labels as columns (loki dataplane)', async () => { setup({ columnsWithMeta: { foo: { active: true, percentOfLinesWithLabel: 3, index: 2 }, line: { active: true, percentOfLinesWithLabel: 3, index: 1 }, Time: { active: true, percentOfLinesWithLabel: 3, index: 0 }, }, }); await waitFor(() => { const columns = screen.getAllByRole('columnheader'); expect(columns[0].textContent).toContain('Time'); expect(columns[1].textContent).toContain('line'); expect(columns[2].textContent).toContain('foo'); }); }); }); });