123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- import { TopOfViewRefType } from '@jaegertracing/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView';
- import { TraceData, TraceSpanData } from '@jaegertracing/jaeger-ui-components/src/types/trace';
- import { render, prettyDOM, screen } from '@testing-library/react';
- import userEvent from '@testing-library/user-event';
- import React, { createRef } from 'react';
- import { Provider } from 'react-redux';
- import { DataFrame, MutableDataFrame, getDefaultTimeRange, LoadingState } from '@grafana/data';
- import { setDataSourceSrv } from '@grafana/runtime';
- import { ExploreId } from 'app/types';
- import { configureStore } from '../../../store/configureStore';
- import { TraceView } from './TraceView';
- import { transformDataFrames } from './utils/transform';
- function getTraceView(frames: DataFrame[]) {
- const store = configureStore();
- const mockPanelData = {
- state: LoadingState.Done,
- series: [],
- timeRange: getDefaultTimeRange(),
- };
- const topOfViewRef = createRef<HTMLDivElement>();
- const traceView = (
- <Provider store={store}>
- <TraceView
- exploreId={ExploreId.left}
- dataFrames={frames}
- splitOpenFn={() => {}}
- traceProp={transformDataFrames(frames[0])!}
- search=""
- focusedSpanIdForSearch=""
- queryResponse={mockPanelData}
- datasource={undefined}
- topOfViewRef={topOfViewRef}
- topOfViewRefType={TopOfViewRefType.Explore}
- />
- </Provider>
- );
- return traceView;
- }
- function renderTraceView(frames = [frameOld]) {
- const { container, baseElement } = render(getTraceView(frames));
- return {
- header: container.children[0],
- timeline: container.children[1],
- container,
- baseElement,
- };
- }
- function renderTraceViewNew() {
- return renderTraceView([frameNew]);
- }
- describe('TraceView', () => {
- beforeAll(() => {
- setDataSourceSrv({
- getInstanceSettings() {
- return undefined;
- },
- } as any);
- });
- it('renders TraceTimelineViewer', () => {
- const { timeline, header } = renderTraceView();
- expect(timeline).toBeDefined();
- expect(header).toBeDefined();
- });
- it('renders TraceTimelineViewer with new format', () => {
- const { timeline, header } = renderTraceViewNew();
- expect(timeline).toBeDefined();
- expect(header).toBeDefined();
- });
- it('renders renders the same for old and new format', () => {
- const { baseElement } = renderTraceViewNew();
- const { baseElement: baseElementOld } = renderTraceView();
- expect(prettyDOM(baseElement)).toEqual(prettyDOM(baseElementOld));
- });
- it('only renders noDataMsg on missing trace', () => {
- // Simulating Explore's access to empty response data
- const { container } = renderTraceView([]);
- expect(container.childNodes.length === 1).toBeTruthy();
- });
- it('toggles detailState', async () => {
- renderTraceViewNew();
- expect(screen.queryByText(/Tags/)).toBeFalsy();
- const spanView = screen.getAllByText('', { selector: 'div[data-testid="span-view"]' })[0];
- await userEvent.click(spanView);
- expect(screen.queryByText(/Tags/)).toBeTruthy();
- await userEvent.click(spanView);
- screen.debug(screen.queryAllByText(/Tags/));
- expect(screen.queryByText(/Tags/)).toBeFalsy();
- });
- it('shows timeline ticks', () => {
- renderTraceViewNew();
- function ticks() {
- return screen.getByText('', { selector: 'div[data-test-id="TimelineHeaderRow"]' }).children[1].children[1]
- .textContent;
- }
- expect(ticks()).toBe('0μs274.5μs549μs823.5μs1.1ms');
- });
- it('correctly shows processes for each span', async () => {
- renderTraceView();
- let table: HTMLElement;
- expect(screen.queryAllByText('', { selector: 'div[data-testid="span-view"]' }).length).toBe(3);
- const firstSpan = screen.getAllByText('', { selector: 'div[data-testid="span-view"]' })[0];
- await userEvent.click(firstSpan);
- await userEvent.click(screen.getByText(/Process/));
- table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
- expect(table.innerHTML).toContain('client-uuid-1');
- await userEvent.click(firstSpan);
- const secondSpan = screen.getAllByText('', { selector: 'div[data-testid="span-view"]' })[1];
- await userEvent.click(secondSpan);
- await userEvent.click(screen.getByText(/Process/));
- table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
- expect(table.innerHTML).toContain('client-uuid-2');
- await userEvent.click(secondSpan);
- const thirdSpan = screen.getAllByText('', { selector: 'div[data-testid="span-view"]' })[2];
- await userEvent.click(thirdSpan);
- await userEvent.click(screen.getByText(/Process/));
- table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
- expect(table.innerHTML).toContain('client-uuid-3');
- });
- it('resets detail view for new trace with the identical spanID', async () => {
- const { rerender } = render(getTraceView([frameOld]));
- const span = screen.getAllByText('', { selector: 'div[data-testid="span-view"]' })[2];
- await userEvent.click(span);
- //Process is in detail view
- expect(screen.getByText(/Process/)).toBeInTheDocument();
- rerender(getTraceView([frameNew]));
- expect(screen.queryByText(/Process/)).not.toBeInTheDocument();
- });
- });
- const response: TraceData & { spans: TraceSpanData[] } = {
- traceID: '1ed38015486087ca',
- spans: [
- {
- traceID: '1ed38015486087ca',
- spanID: '1ed38015486087ca',
- flags: 1,
- operationName: 'HTTP POST - api_prom_push',
- references: [] as any,
- startTime: 1585244579835187,
- duration: 1098,
- tags: [
- { key: 'sampler.type', type: 'string', value: 'const' },
- { key: 'sampler.param', type: 'bool', value: true },
- { key: 'span.kind', type: 'string', value: 'server' },
- { key: 'http.method', type: 'string', value: 'POST' },
- { key: 'http.url', type: 'string', value: '/api/prom/push' },
- { key: 'component', type: 'string', value: 'net/http' },
- { key: 'http.status_code', type: 'int64', value: 204 },
- { key: 'internal.span.format', type: 'string', value: 'proto' },
- ],
- logs: [
- {
- timestamp: 1585244579835229,
- fields: [{ key: 'event', type: 'string', value: 'util.ParseProtoRequest[start reading]' }],
- },
- {
- timestamp: 1585244579835241,
- fields: [
- { key: 'event', type: 'string', value: 'util.ParseProtoRequest[decompress]' },
- { key: 'size', type: 'int64', value: 315 },
- ],
- },
- {
- timestamp: 1585244579835245,
- fields: [
- { key: 'event', type: 'string', value: 'util.ParseProtoRequest[unmarshal]' },
- { key: 'size', type: 'int64', value: 446 },
- ],
- },
- ],
- processID: '1ed38015486087ca',
- warnings: null as any,
- },
- {
- traceID: '1ed38015486087ca',
- spanID: '3fb050342773d333',
- flags: 1,
- operationName: '/logproto.Pusher/Push',
- references: [{ refType: 'CHILD_OF', traceID: '1ed38015486087ca', spanID: '1ed38015486087ca' }],
- startTime: 1585244579835341,
- duration: 921,
- tags: [
- { key: 'span.kind', type: 'string', value: 'client' },
- { key: 'component', type: 'string', value: 'gRPC' },
- { key: 'internal.span.format', type: 'string', value: 'proto' },
- ],
- logs: [],
- processID: '3fb050342773d333',
- warnings: null,
- },
- {
- traceID: '1ed38015486087ca',
- spanID: '35118c298fc91f68',
- flags: 1,
- operationName: '/logproto.Pusher/Push',
- references: [{ refType: 'CHILD_OF', traceID: '1ed38015486087ca', spanID: '3fb050342773d333' }],
- startTime: 1585244579836040,
- duration: 36,
- tags: [
- { key: 'span.kind', type: 'string', value: 'server' },
- { key: 'component', type: 'string', value: 'gRPC' },
- { key: 'internal.span.format', type: 'string', value: 'proto' },
- ],
- logs: [] as any,
- processID: '35118c298fc91f68',
- warnings: null as any,
- },
- ],
- processes: {
- '1ed38015486087ca': {
- serviceName: 'loki-all',
- tags: [
- { key: 'client-uuid', type: 'string', value: 'client-uuid-1' },
- { key: 'hostname', type: 'string', value: '0080b530fae3' },
- { key: 'ip', type: 'string', value: '172.18.0.6' },
- { key: 'jaeger.version', type: 'string', value: 'Go-2.20.1' },
- ],
- },
- '3fb050342773d333': {
- serviceName: 'loki-all',
- tags: [
- { key: 'client-uuid', type: 'string', value: 'client-uuid-2' },
- { key: 'hostname', type: 'string', value: '0080b530fae3' },
- { key: 'ip', type: 'string', value: '172.18.0.6' },
- { key: 'jaeger.version', type: 'string', value: 'Go-2.20.1' },
- ],
- },
- '35118c298fc91f68': {
- serviceName: 'loki-all',
- tags: [
- { key: 'client-uuid', type: 'string', value: 'client-uuid-3' },
- { key: 'hostname', type: 'string', value: '0080b530fae3' },
- { key: 'ip', type: 'string', value: '172.18.0.6' },
- { key: 'jaeger.version', type: 'string', value: 'Go-2.20.1' },
- ],
- },
- },
- warnings: null as any,
- };
- export const frameOld = new MutableDataFrame({
- fields: [
- {
- name: 'trace',
- values: [response],
- },
- ],
- meta: {
- preferredVisualisationType: 'trace',
- },
- });
- const frameNew = new MutableDataFrame({
- fields: [
- { name: 'traceID', values: ['1ed38015486087ca', '1ed38015486087ca', '1ed38015486087ca'] },
- { name: 'spanID', values: ['1ed38015486087ca', '3fb050342773d333', '35118c298fc91f68'] },
- { name: 'parentSpanID', values: [undefined, '1ed38015486087ca', '3fb050342773d333'] },
- { name: 'operationName', values: ['HTTP POST - api_prom_push', '/logproto.Pusher/Push', '/logproto.Pusher/Push'] },
- { name: 'serviceName', values: ['loki-all', 'loki-all', 'loki-all'] },
- {
- name: 'serviceTags',
- values: [
- [
- { key: 'client-uuid', value: '2a59d08899ef6a8a' },
- { key: 'hostname', value: '0080b530fae3' },
- { key: 'ip', value: '172.18.0.6' },
- { key: 'jaeger.version', value: 'Go-2.20.1' },
- ],
- [
- { key: 'client-uuid', value: '2a59d08899ef6a8a' },
- { key: 'hostname', value: '0080b530fae3' },
- { key: 'ip', value: '172.18.0.6' },
- { key: 'jaeger.version', value: 'Go-2.20.1' },
- ],
- [
- { key: 'client-uuid', value: '2a59d08899ef6a8a' },
- { key: 'hostname', value: '0080b530fae3' },
- { key: 'ip', value: '172.18.0.6' },
- { key: 'jaeger.version', value: 'Go-2.20.1' },
- ],
- ],
- },
- { name: 'startTime', values: [1585244579835.187, 1585244579835.341, 1585244579836.04] },
- { name: 'duration', values: [1.098, 0.921, 0.036] },
- {
- name: 'logs',
- values: [
- [
- {
- timestamp: 1585244579835.229,
- fields: [{ key: 'event', value: 'util.ParseProtoRequest[start reading]' }],
- },
- {
- timestamp: 1585244579835.241,
- fields: [
- { key: 'event', value: 'util.ParseProtoRequest[decompress]' },
- { key: 'size', value: 315 },
- ],
- },
- {
- timestamp: 1585244579835.245,
- fields: [
- { key: 'event', value: 'util.ParseProtoRequest[unmarshal]' },
- { key: 'size', value: 446 },
- ],
- },
- ],
- [],
- [],
- ],
- },
- {
- name: 'tags',
- values: [
- [
- { key: 'sampler.type', value: 'const' },
- { key: 'sampler.param', value: true },
- { key: 'span.kind', value: 'server' },
- { key: 'http.method', value: 'POST' },
- { key: 'http.url', value: '/api/prom/push' },
- { key: 'component', value: 'net/http' },
- { key: 'http.status_code', value: 204 },
- { key: 'internal.span.format', value: 'proto' },
- ],
- [
- { key: 'span.kind', value: 'client' },
- { key: 'component', value: 'gRPC' },
- { key: 'internal.span.format', value: 'proto' },
- ],
- [
- { key: 'span.kind', value: 'server' },
- { key: 'component', value: 'gRPC' },
- { key: 'internal.span.format', value: 'proto' },
- ],
- ],
- },
- { name: 'warnings', values: [undefined, undefined] },
- { name: 'stackTraces', values: [undefined, undefined] },
- ],
- meta: {
- preferredVisualisationType: 'trace',
- },
- });
|