diff --git a/packages/jaeger-ui/package.json b/packages/jaeger-ui/package.json index 287ccf0d26..4fcec05e97 100644 --- a/packages/jaeger-ui/package.json +++ b/packages/jaeger-ui/package.json @@ -73,7 +73,6 @@ "dagre": "^0.8.5", "deep-freeze": "^0.0.1", "drange": "^2.0.0", - "fuzzy": "^0.1.3", "global": "^4.3.2", "history": "^4.6.3", "is-promise": "^4.0.0", diff --git a/packages/jaeger-ui/src/selectors/process.js b/packages/jaeger-ui/src/selectors/process.js deleted file mode 100644 index 495c642849..0000000000 --- a/packages/jaeger-ui/src/selectors/process.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2017 Uber Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -export const getProcessServiceName = proc => proc.serviceName; -export const getProcessTags = proc => proc.tags; diff --git a/packages/jaeger-ui/src/selectors/process.test.js b/packages/jaeger-ui/src/selectors/process.test.js deleted file mode 100644 index 0326198fc9..0000000000 --- a/packages/jaeger-ui/src/selectors/process.test.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2017 Uber Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import * as processSelectors from './process'; -import traceGenerator from '../demo/trace-generators'; - -const generatedTrace = traceGenerator.trace({ numberOfSpans: 45 }); - -it('getProcessServiceName() should return the serviceName of the process', () => { - const proc = generatedTrace.processes[Object.keys(generatedTrace.processes)[0]]; - - expect(processSelectors.getProcessServiceName(proc)).toBe(proc.serviceName); -}); - -it('getProcessTags() should return the tags on the process', () => { - const proc = generatedTrace.processes[Object.keys(generatedTrace.processes)[0]]; - - expect(processSelectors.getProcessTags(proc)).toBe(proc.tags); -}); diff --git a/packages/jaeger-ui/src/selectors/span.js b/packages/jaeger-ui/src/selectors/span.js index f96b912d36..940a8e1407 100644 --- a/packages/jaeger-ui/src/selectors/span.js +++ b/packages/jaeger-ui/src/selectors/span.js @@ -12,77 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { createSelector } from 'reselect'; -import fuzzy from 'fuzzy'; - -import { getProcessServiceName } from './process'; - export const getSpanId = span => span.spanID; -export const getSpanName = span => span.operationName; -export const getSpanDuration = span => span.duration; -export const getSpanTimestamp = span => span.startTime; -export const getSpanProcessId = span => span.processID; -export const getSpanReferences = span => span.references || []; -export const getSpanReferenceByType = createSelector( - createSelector(({ span }) => span, getSpanReferences), - ({ type }) => type, - (references, type) => references.find(ref => ref.refType === type) -); -export const getSpanParentId = createSelector( - span => getSpanReferenceByType({ span, type: 'CHILD_OF' }), - childOfRef => (childOfRef ? childOfRef.spanID : null) -); - -export const getSpanProcess = span => { - if (!span.process) { - throw new Error( - ` - you must hydrate the spans with the processes, perhaps - using hydrateSpansWithProcesses(), before accessing a span's process - ` - ); - } - - return span.process; -}; - -export const getSpanServiceName = createSelector(getSpanProcess, getProcessServiceName); - -export const filterSpansForTimestamps = createSelector( - ({ spans }) => spans, - ({ leftBound }) => leftBound, - ({ rightBound }) => rightBound, - (spans, leftBound, rightBound) => - spans.filter(span => getSpanTimestamp(span) >= leftBound && getSpanTimestamp(span) <= rightBound) -); - -export const filterSpansForText = createSelector( - ({ spans }) => spans, - ({ text }) => text, - (spans, text) => - fuzzy - .filter(text, spans, { - extract: span => `${getSpanServiceName(span)} ${getSpanName(span)}`, - }) - .map(({ original }) => original) -); - -const getTextFilterdSpansAsMap = createSelector(filterSpansForText, matchingSpans => - matchingSpans.reduce( - (obj, span) => ({ - ...obj, - [getSpanId(span)]: span, - }), - {} - ) -); - -export const highlightSpansForTextFilter = createSelector( - ({ spans }) => spans, - getTextFilterdSpansAsMap, - (spans, textFilteredSpansMap) => - spans.map(span => ({ - ...span, - muted: !textFilteredSpansMap[getSpanId(span)], - })) -); diff --git a/packages/jaeger-ui/src/selectors/span.test.js b/packages/jaeger-ui/src/selectors/span.test.js index 2ae0543813..b6802f1d17 100644 --- a/packages/jaeger-ui/src/selectors/span.test.js +++ b/packages/jaeger-ui/src/selectors/span.test.js @@ -22,185 +22,3 @@ it('getSpanId() should return the name of the span', () => { expect(spanSelectors.getSpanId(span)).toBe(span.spanID); }); - -it('getSpanName() should return the name of the span', () => { - const span = generatedTrace.spans[0]; - - expect(spanSelectors.getSpanName(span)).toBe(span.operationName); -}); - -it('getSpanDuration() should return the duration of the span', () => { - const span = generatedTrace.spans[0]; - - expect(spanSelectors.getSpanDuration(span)).toBe(span.duration); -}); - -it('getSpanTimestamp() should return the timestamp of the span', () => { - const span = generatedTrace.spans[0]; - - expect(spanSelectors.getSpanTimestamp(span)).toBe(span.startTime); -}); - -it('getSpanReferences() should return the span reference array', () => { - expect(spanSelectors.getSpanReferences(generatedTrace.spans[0])).toEqual( - generatedTrace.spans[0].references - ); -}); - -it('getSpanReferences() should return empty array for null references', () => { - expect(spanSelectors.getSpanReferences({ references: null })).toEqual([]); -}); - -it('getSpanReferenceByType() should return the span reference requested', () => { - expect( - spanSelectors.getSpanReferenceByType({ - span: generatedTrace.spans[1], - type: 'CHILD_OF', - }).refType - ).toBe('CHILD_OF'); -}); - -it('getSpanReferenceByType() should return undefined if one does not exist', () => { - expect( - spanSelectors.getSpanReferenceByType({ - span: generatedTrace.spans[0], - type: 'FOLLOWS_FROM', - }) - ).toBe(undefined); -}); - -it('getSpanParentId() should return the spanID of the parent span', () => { - expect(spanSelectors.getSpanParentId(generatedTrace.spans[1])).toBe( - generatedTrace.spans[1].references.find(({ refType }) => refType === 'CHILD_OF').spanID - ); -}); - -it('getSpanParentId() should return null if no CHILD_OF reference exists', () => { - expect(spanSelectors.getSpanParentId(generatedTrace.spans[0])).toBe(null); -}); - -it('getSpanProcessId() should return the processID of the span', () => { - const span = generatedTrace.spans[0]; - - expect(spanSelectors.getSpanProcessId(span)).toBe(span.processID); -}); - -it('getSpanProcess() should return the process of the span', () => { - const span = { - ...generatedTrace.spans[0], - process: {}, - }; - - expect(spanSelectors.getSpanProcess(span)).toBe(span.process); -}); - -it('getSpanProcess() should throw if no process exists', () => { - expect(() => spanSelectors.getSpanProcess(generatedTrace.spans[0])).toThrow(); -}); - -it('getSpanServiceName() should return the service name of the span', () => { - const serviceName = 'bagel'; - const span = { - ...generatedTrace.spans[0], - process: { serviceName }, - }; - - expect(spanSelectors.getSpanServiceName(span)).toBe(serviceName); -}); - -it('filterSpansForTimestamps() should return a filtered list of spans between the times', () => { - const now = new Date().getTime() * 1000; - const spans = [ - { - startTime: now - 1000, - id: 'start-time-1', - }, - { - startTime: now, - id: 'start-time-2', - }, - { - startTime: now + 1000, - id: 'start-time-3', - }, - ]; - - expect( - spanSelectors.filterSpansForTimestamps({ - spans, - leftBound: now - 500, - rightBound: now + 500, - }) - ).toEqual([spans[1]]); - - expect( - spanSelectors.filterSpansForTimestamps({ - spans, - leftBound: now - 2000, - rightBound: now + 2000, - }) - ).toEqual([...spans]); - - expect( - spanSelectors.filterSpansForTimestamps({ - spans, - leftBound: now - 1000, - rightBound: now, - }) - ).toEqual([spans[0], spans[1]]); - - expect( - spanSelectors.filterSpansForTimestamps({ - spans, - leftBound: now, - rightBound: now + 1000, - }) - ).toEqual([spans[1], spans[2]]); -}); - -it('filterSpansForText() should return a filtered list of spans between the times', () => { - const spans = [ - { - operationName: 'GET /mything', - process: { - serviceName: 'alpha', - }, - id: 'start-time-1', - }, - { - operationName: 'GET /another', - process: { - serviceName: 'beta', - }, - id: 'start-time-1', - }, - { - operationName: 'POST /mything', - process: { - serviceName: 'alpha', - }, - id: 'start-time-1', - }, - ]; - - expect( - spanSelectors.filterSpansForText({ - spans, - text: '/mything', - }) - ).toEqual([spans[0], spans[2]]); - - expect( - spanSelectors.filterSpansForText({ - spans, - text: 'GET', - }) - ).toEqual([spans[0], spans[1]]); - - expect( - spanSelectors.filterSpansForText({ - spans, - text: 'alpha', - }) - ).toEqual([spans[0], spans[2]]); -}); diff --git a/packages/jaeger-ui/src/selectors/trace.js b/packages/jaeger-ui/src/selectors/trace.js index 481e73a459..9304eb562d 100644 --- a/packages/jaeger-ui/src/selectors/trace.js +++ b/packages/jaeger-ui/src/selectors/trace.js @@ -12,40 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { createSelector, createStructuredSelector } from 'reselect'; - -import { - getSpanId, - getSpanName, - getSpanServiceName, - getSpanTimestamp, - getSpanDuration, - getSpanProcessId, -} from './span'; -import { getProcessServiceName } from './process'; -import { formatMillisecondTime, formatSecondTime, ONE_SECOND } from '../utils/date'; -import { numberSortComparator } from '../utils/sort'; import TreeNode from '../utils/TreeNode'; -export const getTraceId = trace => trace.traceID; - -export const getTraceSpans = trace => trace.spans; - -const getTraceProcesses = trace => trace.processes; - -const getSpanWithProcess = createSelector( - state => state.span, - state => state.processes, - (span, processes) => ({ - ...span, - process: processes[getSpanProcessId(span)], - }) -); - -export const getTraceSpansAsMap = createSelector(getTraceSpans, spans => - spans.reduce((map, span) => map.set(getSpanId(span), span), new Map()) -); - export const TREE_ROOT_ID = '__root__'; /** @@ -94,205 +62,3 @@ export function getTraceSpanIdsAsTree(trace) { root.children.sort(comparator); return root; } - -// attach "process" as an object to each span. -export const hydrateSpansWithProcesses = trace => { - const spans = getTraceSpans(trace); - const processes = getTraceProcesses(trace); - - return { - ...trace, - spans: spans.map(span => getSpanWithProcess({ span, processes })), - }; -}; - -export const getTraceSpanCount = createSelector(getTraceSpans, spans => spans.length); - -export const getTraceTimestamp = createSelector(getTraceSpans, spans => - spans.reduce( - (prevTimestamp, span) => - prevTimestamp ? Math.min(prevTimestamp, getSpanTimestamp(span)) : getSpanTimestamp(span), - null - ) -); - -export const getTraceDuration = createSelector(getTraceSpans, getTraceTimestamp, (spans, timestamp) => - spans.reduce( - (prevDuration, span) => - prevDuration - ? Math.max(getSpanTimestamp(span) - timestamp + getSpanDuration(span), prevDuration) - : getSpanDuration(span), - null - ) -); - -export const getTraceEndTimestamp = createSelector( - getTraceTimestamp, - getTraceDuration, - (timestamp, duration) => timestamp + duration -); - -export const getParentSpan = createSelector( - getTraceSpanIdsAsTree, - getTraceSpansAsMap, - (tree, spanMap) => - tree.children - .map(node => spanMap.get(node.value)) - .sort((spanA, spanB) => numberSortComparator(getSpanTimestamp(spanA), getSpanTimestamp(spanB)))[0] -); - -export const getTraceDepth = createSelector(getTraceSpanIdsAsTree, spanTree => spanTree.depth - 1); - -export const getSpanDepthForTrace = createSelector( - createSelector(state => state.trace, getTraceSpanIdsAsTree), - createSelector(state => state.span, getSpanId), - (node, spanID) => node.getPath(spanID).length - 1 -); - -export const getTraceServices = createSelector(getTraceProcesses, processes => - Object.keys(processes).reduce( - (services, processID) => services.add(getProcessServiceName(processes[processID])), - new Set() - ) -); - -export const getTraceServiceCount = createSelector(getTraceServices, services => services.size); - -// establish constants to determine how math should be handled -// for nanosecond-to-millisecond conversions. -export const DURATION_FORMATTERS = { - ms: formatMillisecondTime, - s: formatSecondTime, -}; - -const getDurationFormatterForTrace = createSelector(getTraceDuration, totalDuration => - totalDuration >= ONE_SECOND ? DURATION_FORMATTERS.s : DURATION_FORMATTERS.ms -); - -export const formatDurationForUnit = createSelector( - ({ duration }) => duration, - ({ unit }) => DURATION_FORMATTERS[unit], - (duration, formatter) => formatter(duration) -); - -export const formatDurationForTrace = createSelector( - ({ duration }) => duration, - createSelector(({ trace }) => trace, getDurationFormatterForTrace), - (duration, formatter) => formatter(duration) -); - -export const getSortedSpans = createSelector( - ({ trace }) => trace, - ({ spans }) => spans, - ({ sort }) => sort, - (trace, spans, { dir, comparator, selector }) => - [...spans].sort((spanA, spanB) => dir * comparator(selector(spanA, trace), selector(spanB, trace))) -); - -const getTraceSpansByHierarchyPosition = createSelector(getTraceSpanIdsAsTree, tree => { - const hierarchyPositionMap = new Map(); - let i = 0; - tree.walk(spanID => hierarchyPositionMap.set(spanID, i++)); - return hierarchyPositionMap; -}); - -export const getTreeSizeForTraceSpan = createSelector( - createSelector(state => state.trace, getTraceSpanIdsAsTree), - createSelector(state => state.span, getSpanId), - (tree, spanID) => { - const node = tree.find(spanID); - if (!node) { - return -1; - } - return node.size - 1; - } -); - -export const getSpanHierarchySortPositionForTrace = createSelector( - createSelector(({ trace }) => trace, getTraceSpansByHierarchyPosition), - ({ span }) => span, - (hierarchyPositionMap, span) => hierarchyPositionMap.get(getSpanId(span)) -); - -export const getTraceName = createSelector( - createSelector( - createSelector(hydrateSpansWithProcesses, getParentSpan), - createStructuredSelector({ - name: getSpanName, - serviceName: getSpanServiceName, - }) - ), - ({ name, serviceName }) => `${serviceName}: ${name}` -); - -export const omitCollapsedSpans = createSelector( - ({ spans }) => spans, - createSelector(({ trace }) => trace, getTraceSpanIdsAsTree), - ({ collapsed }) => collapsed, - (spans, tree, collapse) => { - const hiddenSpanIds = collapse.reduce((result, collapsedSpanId) => { - tree.find(collapsedSpanId).walk(id => id !== collapsedSpanId && result.add(id)); - return result; - }, new Set()); - - return hiddenSpanIds.size > 0 ? spans.filter(span => !hiddenSpanIds.has(getSpanId(span))) : spans; - } -); - -export const DEFAULT_TICK_INTERVAL = 4; -export const DEFAULT_TICK_WIDTH = 3; -export const getTicksForTrace = createSelector( - ({ trace }) => trace, - ({ interval = DEFAULT_TICK_INTERVAL }) => interval, - ({ width = DEFAULT_TICK_WIDTH }) => width, - ( - trace, - interval, - width - // timestamps will be spaced over the interval, starting from the initial timestamp - ) => - [...Array(interval + 1).keys()].map(num => ({ - timestamp: getTraceTimestamp(trace) + getTraceDuration(trace) * (num / interval), - width, - })) -); - -// TODO: delete this when the backend can ensure uniqueness -/* istanbul ignore next */ -export const enforceUniqueSpanIds = createSelector( - /* istanbul ignore next */ trace => trace, - getTraceSpans, - /* istanbul ignore next */ (trace, spans) => { - const map = new Map(); - - return { - ...trace, - spans: spans.reduce((result, span) => { - const spanID = map.has(getSpanId(span)) - ? `${getSpanId(span)}_${map.get(getSpanId(span))}` - : getSpanId(span); - const updatedSpan = { ...span, spanID }; - - if (spanID !== getSpanId(span)) { - // eslint-disable-next-line no-console - console.warn('duplicate spanID in trace replaced', getSpanId(span), 'new:', spanID); - } - - // set the presence of the span in the map or increment the number - map.set(getSpanId(span), (map.get(getSpanId(span)) || 0) + 1); - - return result.concat([updatedSpan]); - }, []), - }; - } -); - -// TODO: delete this when the backend can ensure uniqueness -export const dropEmptyStartTimeSpans = createSelector( - /* istanbul ignore next */ trace => trace, - getTraceSpans, - /* istanbul ignore next */ (trace, spans) => ({ - ...trace, - spans: spans.filter(span => !!getSpanTimestamp(span)), - }) -); diff --git a/packages/jaeger-ui/src/selectors/trace.test.js b/packages/jaeger-ui/src/selectors/trace.test.js index 06c28736b5..10297d220a 100644 --- a/packages/jaeger-ui/src/selectors/trace.test.js +++ b/packages/jaeger-ui/src/selectors/trace.test.js @@ -12,52 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -import _values from 'lodash/values'; - import { followsFromRef } from './trace.fixture'; -import { - getSpanId, - getSpanName, - getSpanParentId, - getSpanProcess, - getSpanProcessId, - getSpanServiceName, - getSpanTimestamp, -} from './span'; +import { getSpanId } from './span'; import * as traceSelectors from './trace'; import traceGenerator from '../demo/trace-generators'; -import { numberSortComparator } from '../utils/sort'; const generatedTrace = traceGenerator.trace({ numberOfSpans: 45 }); -it('getTraceId() should return the traceID', () => { - expect(traceSelectors.getTraceId(generatedTrace)).toBe(generatedTrace.traceID); -}); - -it('hydrateSpansWithProcesses() should return the trace with processes on each span', () => { - const hydratedTrace = traceSelectors.hydrateSpansWithProcesses(generatedTrace); - - hydratedTrace.spans.forEach(span => - expect(getSpanProcess(span)).toBe(generatedTrace.processes[getSpanProcessId(span)]) - ); -}); - -it('getTraceSpansAsMap() should return a map of all of the spans', () => { - const spanMap = traceSelectors.getTraceSpansAsMap(generatedTrace); - [...spanMap.entries()].forEach(pair => { - expect(pair[1]).toEqual(generatedTrace.spans.find(span => getSpanId(span) === pair[0])); - }); -}); - describe('getTraceSpanIdsAsTree()', () => { + const getTraceSpansAsMap = trace => + trace.spans.reduce((map, span) => map.set(getSpanId(span), span), new Map()); it('builds the tree properly', () => { const tree = traceSelectors.getTraceSpanIdsAsTree(generatedTrace); - const spanMap = traceSelectors.getTraceSpansAsMap(generatedTrace); + const spanMap = getTraceSpansAsMap(generatedTrace); tree.walk((value, node) => { const expectedParentValue = value === traceSelectors.TREE_ROOT_ID ? null : value; node.children.forEach(childNode => { - expect(getSpanParentId(spanMap.get(childNode.value))).toBe(expectedParentValue); + const span = spanMap.get(childNode.value); + const parentId = span.references.find(ref => ref.refType === 'CHILD_OF')?.spanID ?? null; + expect(parentId).toBe(expectedParentValue); }); }); }); @@ -66,292 +40,3 @@ describe('getTraceSpanIdsAsTree()', () => { expect(() => traceSelectors.getTraceSpanIdsAsTree(followsFromRef)).not.toThrow(); }); }); - -it('getParentSpan() should return the parent span of the tree', () => { - expect(traceSelectors.getParentSpan(generatedTrace)).toBe( - traceSelectors - .getTraceSpansAsMap(generatedTrace) - .get(traceSelectors.getTraceSpanIdsAsTree(generatedTrace).children[0].value) - ); -}); - -it('getParentSpan() should return the first span if there are multiple parents', () => { - const initialTimestamp = new Date().getTime() * 1000; - const firstSpan = { - startTime: initialTimestamp, - spanID: 'my-span-1', - references: [], - }; - - const trace = { - spans: [ - { - startTime: initialTimestamp + 2000, - spanID: 'my-span-3', - references: [], - }, - firstSpan, - { - startTime: initialTimestamp + 1000, - spanID: 'my-span-2', - references: [], - }, - ], - }; - - expect(traceSelectors.getParentSpan(trace)).toBe(firstSpan); -}); - -it('getTraceName() should return a formatted name for the first span', () => { - const hydratedTrace = traceSelectors.hydrateSpansWithProcesses(generatedTrace); - const parentSpan = traceSelectors.getParentSpan(hydratedTrace); - - expect(traceSelectors.getTraceName(hydratedTrace)).toBe( - `${getSpanServiceName(parentSpan)}: ${getSpanName(parentSpan)}` - ); -}); - -it('getTraceSpanCount() should return the length of the spans array', () => { - expect(traceSelectors.getTraceSpanCount(generatedTrace)).toBe(generatedTrace.spans.length); -}); - -it('getTraceDuration() should return the duration for the span', () => { - expect(traceSelectors.getTraceDuration(generatedTrace)).toBe(generatedTrace.spans[0].duration); -}); - -it('getTraceTimestamp() should return the first timestamp for the conventional trace', () => { - expect(traceSelectors.getTraceTimestamp(generatedTrace)).toBe(generatedTrace.spans[0].startTime); -}); - -it('getTraceDepth() should determine the total depth of the trace tree', () => { - expect(traceSelectors.getTraceDepth(generatedTrace)).toBe( - traceSelectors.getTraceSpanIdsAsTree(generatedTrace).depth - 1 - ); -}); - -it('getSpanDepthForTrace() should determine the depth of a given span in the parent', () => { - function testDepthCalc(span) { - let depth = 2; - let currentId = getSpanParentId(span); - - const findCurrentSpanById = item => getSpanId(item) === currentId; - while (currentId !== getSpanId(generatedTrace.spans[0])) { - depth++; - currentId = getSpanParentId(generatedTrace.spans.find(findCurrentSpanById)); - } - - // console.log('hypothetical depth', depth); - - expect( - traceSelectors.getSpanDepthForTrace({ - trace: generatedTrace, - span, - }) - ).toBe(depth); - } - - // test depth calculations for a few random spans - testDepthCalc(generatedTrace.spans[1]); - testDepthCalc(generatedTrace.spans[Math.floor(generatedTrace.spans.length / 2)]); - testDepthCalc(generatedTrace.spans[Math.floor(generatedTrace.spans.length / 4)]); - testDepthCalc(generatedTrace.spans[Math.floor(generatedTrace.spans.length * 0.75)]); -}); - -it('getTraceServices() should return an unique array of all services in the trace', () => { - const svcs = [...traceSelectors.getTraceServices(generatedTrace)].sort(); - const set = new Set(_values(generatedTrace.processes).map(v => v.serviceName)); - const setSvcs = [...set.values()].sort(); - expect(svcs).toEqual(setSvcs); -}); - -it('getTraceServiceCount() should return the length of the service list', () => { - expect(traceSelectors.getTraceServiceCount(generatedTrace)).toBe( - generatedTrace.spans.reduce( - (results, { processID }) => results.add(generatedTrace.processes[processID].serviceName), - new Set() - ).size - ); -}); - -it('formatDurationForUnit() should use the formatters to return the proper value', () => { - expect(traceSelectors.formatDurationForUnit({ duration: 302000, unit: 'ms' })).toBe('302ms'); - - expect(traceSelectors.formatDurationForUnit({ duration: 1302000, unit: 'ms' })).toBe('1302ms'); - - expect(traceSelectors.formatDurationForUnit({ duration: 1302000, unit: 's' })).toBe('1.302s'); - - expect(traceSelectors.formatDurationForUnit({ duration: 90000, unit: 's' })).toBe('0.09s'); -}); - -it('formatDurationForTrace() should return a ms value for traces shorter than a second', () => { - expect( - traceSelectors.formatDurationForTrace({ - trace: { - spans: [{ duration: 600000 }], - }, - duration: 302000, - }) - ).toBe('302ms'); -}); - -it('formatDurationForTrace() should return a s value for traces longer than a second', () => { - expect( - traceSelectors.formatDurationForTrace({ - trace: { - ...generatedTrace, - spans: generatedTrace.spans.concat([ - { - ...generatedTrace.spans[0], - duration: 1000000, - }, - ]), - }, - duration: 302000, - }) - ).toBe('0.302s'); - - expect( - traceSelectors.formatDurationForTrace({ - trace: { - ...generatedTrace, - spans: generatedTrace.spans.concat([ - { - ...generatedTrace.spans[0], - duration: 1200000, - }, - ]), - }, - duration: 302000, - }) - ).toBe('0.302s'); -}); - -it('getSortedSpans() should sort spans given a sort object', () => { - expect( - traceSelectors.getSortedSpans({ - trace: generatedTrace, - spans: generatedTrace.spans, - sort: { - dir: 1, - comparator: numberSortComparator, - selector: getSpanTimestamp, - }, - }) - ).toEqual([...generatedTrace.spans].sort((spanA, spanB) => spanA.startTime - spanB.startTime)); - - expect( - traceSelectors.getSortedSpans({ - trace: generatedTrace, - spans: generatedTrace.spans, - sort: { - dir: -1, - comparator: numberSortComparator, - selector: getSpanTimestamp, - }, - }) - ).toEqual([...generatedTrace.spans].sort((spanA, spanB) => spanB.startTime - spanA.startTime)); -}); - -it('getTreeSizeForTraceSpan() should return the size for the parent span', () => { - expect( - traceSelectors.getTreeSizeForTraceSpan({ - trace: generatedTrace, - span: generatedTrace.spans[0], - }) - ).toBe(generatedTrace.spans.length - 1); -}); - -it('getTreeSizeForTraceSpan() should return the size for a child span', () => { - expect( - traceSelectors.getTreeSizeForTraceSpan({ - trace: generatedTrace, - span: generatedTrace.spans[1], - }) - ).toBe(traceSelectors.getTraceSpanIdsAsTree(generatedTrace).find(generatedTrace.spans[1].spanID).size - 1); -}); - -it('getTreeSizeForTraceSpan() should return -1 for an absent span', () => { - expect( - traceSelectors.getTreeSizeForTraceSpan({ - trace: generatedTrace, - span: { spanID: 'whatever' }, - }) - ).toBe(-1); -}); - -it('getTraceName() should return the trace name based on the parentSpan', () => { - const serviceName = generatedTrace.processes[generatedTrace.spans[0].processID].serviceName; - const operationName = generatedTrace.spans[0].operationName; - - expect(traceSelectors.getTraceName(generatedTrace)).toBe(`${serviceName}: ${operationName}`); -}); - -it('omitCollapsedSpans() should filter out collaped spans', () => { - const span = generatedTrace.spans[1]; - const size = traceSelectors.getTraceSpanIdsAsTree(generatedTrace).find(span.spanID).size - 1; - - expect( - traceSelectors.omitCollapsedSpans({ - trace: generatedTrace, - spans: generatedTrace.spans, - collapsed: [span.spanID], - }).length - ).toBe(generatedTrace.spans.length - size); -}); - -it('getTicksForTrace() should return a list of ticks given interval parameters', () => { - const timestamp = new Date().getTime() * 1000; - const trace = { - spans: [ - { - startTime: timestamp, - duration: 3000000, - }, - ], - }; - - expect( - traceSelectors.getTicksForTrace({ - trace, - interval: 3, - width: 10, - }) - ).toEqual([ - { timestamp, width: 10 }, - { timestamp: timestamp + 1000000, width: 10 }, - { timestamp: timestamp + 2000000, width: 10 }, - { timestamp: timestamp + 3000000, width: 10 }, - ]); -}); - -it('getTicksForTrace() should use defaults', () => { - const timestamp = new Date().getTime() * 1000; - const trace = { - spans: [ - { - startTime: timestamp, - duration: 4000000, - }, - ], - }; - - expect(traceSelectors.getTicksForTrace({ trace })).toEqual([ - { timestamp, width: traceSelectors.DEFAULT_TICK_WIDTH }, - { - timestamp: timestamp + 1000000, - width: traceSelectors.DEFAULT_TICK_WIDTH, - }, - { - timestamp: timestamp + 2000000, - width: traceSelectors.DEFAULT_TICK_WIDTH, - }, - { - timestamp: timestamp + 3000000, - width: traceSelectors.DEFAULT_TICK_WIDTH, - }, - { - timestamp: timestamp + 4000000, - width: traceSelectors.DEFAULT_TICK_WIDTH, - }, - ]); -}); diff --git a/packages/jaeger-ui/tsconfig.lint.json b/packages/jaeger-ui/tsconfig.lint.json index 297cc62741..5c062c439f 100644 --- a/packages/jaeger-ui/tsconfig.lint.json +++ b/packages/jaeger-ui/tsconfig.lint.json @@ -50,7 +50,6 @@ "src/reducers/services.js", "src/reducers/trace.js", "src/selectors/dependencies.js", - "src/selectors/process.js", "src/selectors/span.js", "src/selectors/trace.js", "src/utils/configure-store.js", diff --git a/yarn.lock b/yarn.lock index d9e2e70c04..d91abd7112 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6295,10 +6295,6 @@ functions-have-names@^1.2.2: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -fuzzy@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/fuzzy/-/fuzzy-0.1.3.tgz#4c76ec2ff0ac1a36a9dccf9a00df8623078d4ed8" - gauge@^4.0.3: version "4.0.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce"