Skip to content
Snippets Groups Projects
Commit ffe25f9b authored by Tomas Bulva's avatar Tomas Bulva
Browse files

Merge branch 'drosse/tracing-improvements-filters-dependencies' into 'master'

Implement filters restrictions to improve query performance

See merge request !146244



Merged-by: default avatarTomas Bulva <tbulva@gitlab.com>
Approved-by: Doug Stull's avatarDoug Stull <dstull@gitlab.com>
Approved-by: default avatarTomas Bulva <tbulva@gitlab.com>
Co-authored-by: default avatarDaniele Rossetti <drossetti@gitlab.com>
parents 6dafd0cd 6c017905
No related branches found
No related tags found
1 merge request!146244Implement filters restrictions to improve query performance
Pipeline #1200188125 passed
<script>
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
import { s__ } from '~/locale';
import BaseSearchToken from './tracing_base_search_token.vue';
export default {
components: {
BaseToken,
BaseSearchToken,
},
i18n: {
placeholderName: s__('Tracing|name'),
......@@ -30,21 +30,15 @@ export default {
placeholder: `${this.$options.i18n.placeholderName}=${this.$options.i18n.placeholderValue}`,
};
},
tokenConfig() {
return {
...this.config,
suggestionsDisabled: true,
};
},
},
};
</script>
<template>
<base-token
<base-search-token
v-bind="$attrs"
:active="active"
:config="tokenConfig"
:config="config"
:value="value"
:data-segment-input-attributes="inputAttributes"
v-on="$listeners"
......
<script>
import { GlDropdownText, GlFilteredSearchToken } from '@gitlab/ui';
import { s__ } from '~/locale';
import { SERVICE_NAME_FILTER_TOKEN_TYPE, OPERATION_FILTER_TOKEN_TYPE } from './filters';
export default {
components: {
GlFilteredSearchToken,
GlDropdownText,
},
i18n: {
disabledText: s__('Tracing|You must select a Service and Operation first.'),
},
props: {
active: {
type: Boolean,
required: true,
},
config: {
type: Object,
required: true,
},
value: {
type: Object,
required: true,
},
currentValue: {
type: Array,
required: true,
},
},
computed: {
isEnabled() {
const requiredFilters = [SERVICE_NAME_FILTER_TOKEN_TYPE, OPERATION_FILTER_TOKEN_TYPE];
return requiredFilters.every((filter) =>
this.currentValue.find(({ type }) => type === filter),
);
},
},
};
</script>
<template>
<gl-filtered-search-token
v-bind="{ ...$props, ...$attrs }"
:config="config"
:value="value"
:active="active"
:view-only="!isEnabled"
v-on="$listeners"
>
<template #suggestions>
<gl-dropdown-text v-if="!isEnabled">{{ $options.i18n.disabledText }}</gl-dropdown-text>
</template>
</gl-filtered-search-token>
</template>
<script>
import { GlFilteredSearchToken } from '@gitlab/ui';
import { s__ } from '~/locale';
import {
OPERATORS_IS,
OPERATORS_IS_NOT,
} from '~/vue_shared/components/filtered_search_bar/constants';
import { OPERATORS_IS } from '~/vue_shared/components/filtered_search_bar/constants';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import DateRangeToken from '~/vue_shared/components/filtered_search_bar/tokens/daterange_token.vue';
import { SORTING_OPTIONS, TIME_RANGE_OPTIONS } from '~/observability/constants';
......@@ -20,6 +16,7 @@ import {
import ServiceToken from './service_search_token.vue';
import OperationToken from './operation_search_token.vue';
import AttributeSearchToken from './attribute_search_token.vue';
import BaseSearchToken from './tracing_base_search_token.vue';
export default {
components: {
......@@ -79,26 +76,26 @@ export default {
title: s__('Tracing|Service'),
type: SERVICE_NAME_FILTER_TOKEN_TYPE,
token: ServiceToken,
operators: OPERATORS_IS_NOT,
operators: OPERATORS_IS,
fetchServices: this.observabilityClient.fetchServices,
},
{
title: s__('Tracing|Operation'),
type: OPERATION_FILTER_TOKEN_TYPE,
token: OperationToken,
operators: OPERATORS_IS_NOT,
operators: OPERATORS_IS,
fetchOperations: this.observabilityClient.fetchOperations,
},
{
title: s__('Tracing|Trace ID'),
type: TRACE_ID_FILTER_TOKEN_TYPE,
token: GlFilteredSearchToken,
operators: OPERATORS_IS_NOT,
token: BaseSearchToken,
operators: OPERATORS_IS,
},
{
title: s__('Tracing|Duration (ms)'),
type: DURATION_MS_FILTER_TOKEN_TYPE,
token: GlFilteredSearchToken,
token: BaseSearchToken,
operators: [
{ value: '>', description: s__('Tracing|longer than') },
{ value: '<', description: s__('Tracing|shorter than') },
......@@ -113,8 +110,8 @@ export default {
{
title: s__('Tracing|Status'),
type: STATUS_FILTER_TOKEN_TYPE,
token: GlFilteredSearchToken,
operators: OPERATORS_IS_NOT,
token: BaseSearchToken,
operators: OPERATORS_IS,
options: [
{ value: 'ok', title: s__('Tracing|Ok') },
{ value: 'error', title: s__('Tracing|Error') },
......
import AttributeSearchToken from 'ee/tracing/list/filter_bar/attribute_search_token.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
import TracingBaseSearchToken from 'ee/tracing/list/filter_bar/tracing_base_search_token.vue';
describe('AttributeSearchToken', () => {
let wrapper;
const findBaseToken = () => wrapper.findComponent(BaseToken);
const findBaseToken = () => wrapper.findComponent(TracingBaseSearchToken);
beforeEach(() => {
wrapper = shallowMountExtended(AttributeSearchToken, {
......@@ -15,6 +15,7 @@ describe('AttributeSearchToken', () => {
title: 'test-title',
},
value: { data: '' },
currentValue: [],
},
});
});
......@@ -22,12 +23,8 @@ describe('AttributeSearchToken', () => {
it('renders a BaseToken', () => {
const base = findBaseToken();
expect(base.exists()).toBe(true);
expect(base.props('active')).toBe(wrapper.props('active'));
expect(base.props('value')).toBe(wrapper.props('value'));
});
it('sets suggestionsDisabled in the config', () => {
const base = findBaseToken();
expect(base.props('config')).toEqual({ ...wrapper.props('config'), suggestionsDisabled: true });
expect(base.props('active')).toEqual(wrapper.props('active'));
expect(base.props('value')).toEqual(wrapper.props('value'));
expect(base.props('config')).toEqual(wrapper.props('config'));
});
});
import { GlFilteredSearchToken } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import TracingBaseSearchToken from 'ee/tracing/list/filter_bar/tracing_base_search_token.vue';
describe('AttributeSearchToken', () => {
let wrapper;
const findBaseToken = () => wrapper.findComponent(GlFilteredSearchToken);
const defaultProps = {
active: true,
config: {
title: 'test-title',
},
value: { data: '' },
currentValue: [],
};
const mount = (propsData = defaultProps) => {
wrapper = shallowMountExtended(TracingBaseSearchToken, {
propsData,
});
};
beforeEach(() => {
mount();
});
it('renders a BaseToken', () => {
const base = findBaseToken();
expect(base.exists()).toBe(true);
expect(base.props('active')).toEqual(wrapper.props('active'));
expect(base.props('value')).toEqual(wrapper.props('value'));
expect(base.props('config')).toEqual(wrapper.props('config'));
expect(findBaseToken().props('viewOnly')).toBe(true);
});
it('sets the token to view-only if the operation service token are not set', () => {
mount({ ...defaultProps, currentValue: [{ type: 'operation' }] });
expect(findBaseToken().props('viewOnly')).toBe(true);
});
it('sets the token to view-only if the service service token are not set', () => {
mount({ ...defaultProps, currentValue: [{ type: 'service' }] });
expect(findBaseToken().props('viewOnly')).toBe(true);
});
it('does not set the token to view-only if the service service and operation tokens are set', () => {
mount({ ...defaultProps, currentValue: [{ type: 'service' }, { type: 'operation' }] });
expect(findBaseToken().props('viewOnly')).toBe(true);
});
});
......@@ -5,6 +5,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ServiceToken from 'ee/tracing/list/filter_bar/service_search_token.vue';
import AttributeSearchToken from 'ee/tracing/list/filter_bar/attribute_search_token.vue';
import TracingListFilteredSearch from 'ee/tracing/list/filter_bar/tracing_filtered_search.vue';
import TracingBaseSearchToken from 'ee/tracing/list/filter_bar/tracing_base_search_token.vue';
import { createMockClient } from 'helpers/mock_observability_client';
describe('TracingListFilteredSearch', () => {
......@@ -29,6 +30,7 @@ describe('TracingListFilteredSearch', () => {
});
const findFilteredSearch = () => wrapper.findComponent(FilteredSearch);
const getTokens = () => findFilteredSearch().props('tokens');
it('renders the component', () => {
expect(wrapper.exists()).toBe(true);
......@@ -62,37 +64,46 @@ describe('TracingListFilteredSearch', () => {
});
});
describe('date range token', () => {
describe('tokens', () => {
it('configure the date range token', () => {
const tokens = findFilteredSearch().props('tokens');
const tokens = getTokens();
const token = tokens.find((t) => t.type === 'period');
expect(token.token).toBe(DateRangeToken);
});
});
describe('attribute token', () => {
it('configure the attribute token', () => {
const tokens = findFilteredSearch().props('tokens');
const tokens = getTokens();
const attributeToken = tokens.find((t) => t.type === 'attribute');
expect(attributeToken.token).toBe(AttributeSearchToken);
});
});
describe('service token', () => {
it('configure the service token', () => {
const tokens = findFilteredSearch().props('tokens');
const tokens = getTokens();
const serviceToken = tokens.find((t) => t.type === 'service-name');
expect(serviceToken.token).toBe(ServiceToken);
expect(serviceToken.fetchServices).toBe(observabilityClientMock.fetchServices);
});
});
describe('operations token', () => {
it('configure the service token', () => {
const tokens = findFilteredSearch().props('tokens');
it('configure the operation token', () => {
const tokens = getTokens();
const operationToken = tokens.find((t) => t.type === 'operation');
expect(operationToken.token).toBe(OperationToken);
expect(operationToken.fetchOperations).toBe(observabilityClientMock.fetchOperations);
});
it('configure the trace-id token', () => {
const tokens = getTokens();
expect(tokens.find((t) => t.type === 'trace-id').token).toBe(TracingBaseSearchToken);
});
it('configure the status token', () => {
const tokens = getTokens();
expect(tokens.find((t) => t.type === 'status').token).toBe(TracingBaseSearchToken);
});
it('configure the duration token', () => {
const tokens = getTokens();
expect(tokens.find((t) => t.type === 'duration-ms').token).toBe(TracingBaseSearchToken);
});
});
});
......@@ -52773,6 +52773,9 @@ msgstr ""
msgid "Tracing|Traces"
msgstr ""
 
msgid "Tracing|You must select a Service and Operation first."
msgstr ""
msgid "Tracing|longer than"
msgstr ""
 
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment