Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lens] Enabled tsdb counter fields for last_value #156183

Merged
merged 4 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { createMockedIndexPattern } from '../../mocks';
import { LastValueIndexPatternColumn } from './last_value';
import { lastValueOperation } from '.';
import type { FormBasedLayer } from '../../types';
import type { IndexPattern } from '../../../../types';
import { TermsIndexPatternColumn } from './terms';
import { EuiSwitch, EuiSwitchEvent } from '@elastic/eui';
import { buildExpression, parseExpression } from '@kbn/expressions-plugin/common';
Expand All @@ -35,10 +34,9 @@ const defaultProps = {
dataViews: dataViewPluginMocks.createStartContract(),
data: dataPluginMock.createStartContract(),
http: {} as HttpSetup,
indexPattern: {
...createMockedIndexPattern(),
indexPattern: createMockedIndexPattern({
hasRestrictions: false,
} as IndexPattern,
}),
operationDefinitionMap: {},
isFullscreen: false,
toggleFullscreen: jest.fn(),
Expand Down Expand Up @@ -87,7 +85,7 @@ describe('last_value', () => {
const esAggsFn = lastValueOperation.toEsAggsFn(
{ ...lastValueColumn, params: { ...lastValueColumn.params } },
'col1',
{} as IndexPattern,
createMockedIndexPattern(),
layer,
uiSettingsMock,
[]
Expand All @@ -110,7 +108,7 @@ describe('last_value', () => {
const esAggsFn = lastValueOperation.toEsAggsFn(
{ ...lastValueColumn, params: { ...lastValueColumn.params, showArrayValues: true } },
'col1',
{} as IndexPattern,
createMockedIndexPattern(),
layer,
uiSettingsMock,
[]
Expand Down Expand Up @@ -398,6 +396,23 @@ describe('last_value', () => {
})
).toEqual({ dataType: 'string', isBucketed: false, scale: 'ordinal' });
});

it('should return operation with the right type also for tsdb counter types', () => {
expect(
lastValueOperation.getPossibleOperationForField({
aggregatable: true,
searchable: true,
name: 'test',
displayName: 'test',
type: 'number',
timeSeriesMetric: 'counter',
})
).toEqual({
dataType: 'number',
isBucketed: false,
scale: 'ratio',
});
});
});

describe('buildColumn', () => {
Expand Down Expand Up @@ -882,10 +897,8 @@ describe('last_value', () => {
});

describe('getErrorMessage', () => {
let indexPattern: IndexPattern;
let errorLayer: FormBasedLayer;
beforeEach(() => {
indexPattern = createMockedIndexPattern();
errorLayer = {
columns: {
col1: {
Expand All @@ -903,9 +916,9 @@ describe('last_value', () => {
};
});
it('returns undefined if sourceField exists and sortField is of type date ', () => {
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', indexPattern)).toEqual(
undefined
);
expect(
lastValueOperation.getErrorMessage!(errorLayer, 'col1', createMockedIndexPattern())
).toEqual(undefined);
});
it('shows error message if the sourceField does not exist in index pattern', () => {
errorLayer = {
Expand All @@ -917,7 +930,7 @@ describe('last_value', () => {
} as LastValueIndexPatternColumn,
},
};
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', indexPattern))
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', createMockedIndexPattern()))
.toMatchInlineSnapshot(`
Array [
Object {
Expand Down Expand Up @@ -968,7 +981,7 @@ describe('last_value', () => {
} as LastValueIndexPatternColumn,
},
};
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', indexPattern))
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', createMockedIndexPattern()))
.toMatchInlineSnapshot(`
Array [
Object {
Expand Down Expand Up @@ -1014,10 +1027,13 @@ describe('last_value', () => {
} as LastValueIndexPatternColumn,
},
};
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', indexPattern)).toHaveLength(2);
expect(
lastValueOperation.getErrorMessage!(errorLayer, 'col1', createMockedIndexPattern())
).toHaveLength(2);
});

it('shows error message if the sourceField is of unsupported type', () => {
const indexPattern = createMockedIndexPattern();
indexPattern.getFieldByName('start_date')!.type = 'unsupported_type';
errorLayer = {
...errorLayer,
Expand Down Expand Up @@ -1045,9 +1061,9 @@ describe('last_value', () => {
} as LastValueIndexPatternColumn,
},
};
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', indexPattern)).toEqual([
'Field bytes is not a date field and cannot be used for sorting',
]);
expect(
lastValueOperation.getErrorMessage!(errorLayer, 'col1', createMockedIndexPattern())
).toEqual(['Field bytes is not a date field and cannot be used for sorting']);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ export const lastValueOperation: OperationDefinition<
: oldColumn.filter,
};
},
getPossibleOperationForField: ({ aggregationRestrictions, type, timeSeriesMetric }) => {
if (supportedTypes.has(type) && !aggregationRestrictions && timeSeriesMetric !== 'counter') {
getPossibleOperationForField: ({ aggregationRestrictions, type }) => {
if (supportedTypes.has(type) && !aggregationRestrictions) {
return {
dataType: type as DataType,
isBucketed: false,
Expand Down Expand Up @@ -285,9 +285,12 @@ export const lastValueOperation: OperationDefinition<
// time shift is added to wrapping aggFilteredMetric if filter is set
timeShift: column.filter ? undefined : column.timeShift,
} as const;
// do not use unsupported top hits when using a counter field type
const isCounterMetricFieldUsed =
indexPattern.getFieldByName(column.sourceField)?.timeSeriesMetric === 'counter';

return (
column.params.showArrayValues
column.params.showArrayValues && !isCounterMetricFieldUsed
? buildExpressionFunction<AggFunctionsMapping['aggTopHit']>('aggTopHit', {
...initialArgs,
aggregate: 'concat',
Expand Down
13 changes: 9 additions & 4 deletions x-pack/test/functional/apps/lens/group4/tsdb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {

// skip count for now as it's a special function and will
// change automatically the unsupported field to Records when detected
const operationsByFieldSupport = [
const allOperations = [
'average',
'max',
'last_value',
Expand All @@ -181,11 +181,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'standard_deviation',
'sum',
'unique_count',
].map((name) => ({
];
const counterFieldsSupportedOps = ['min', 'max', 'counter_rate', 'last_value'];
const gaugeFieldsSupportedOps = allOperations;

const operationsByFieldSupport = allOperations.map((name) => ({
name,
// Quick way to make it match the UI name
label: `${name[0].toUpperCase()}${name.slice(1).replace('_', ' ')}`,
counter: ['max', 'counter_rate'].includes(name),
gauge: true,
counter: counterFieldsSupportedOps.includes(name),
gauge: gaugeFieldsSupportedOps.includes(name),
}));

for (const fieldType of ['counter', 'gauge'] as const) {
Expand Down