Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into guardrails-cases-api
Browse files Browse the repository at this point in the history
  • Loading branch information
js-jankisalvi committed Jun 30, 2023
2 parents 484a84b + a8e07e8 commit 719d163
Show file tree
Hide file tree
Showing 19 changed files with 188 additions and 47 deletions.
1 change: 1 addition & 0 deletions .buildkite/ftr_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ enabled:
- x-pack/performance/journeys/flight_dashboard.ts
- x-pack/performance/journeys/login.ts
- x-pack/performance/journeys/many_fields_discover.ts
- x-pack/performance/journeys/many_fields_transform.ts
- x-pack/performance/journeys/promotion_tracking_dashboard.ts
- x-pack/performance/journeys/web_logs_dashboard.ts
- x-pack/performance/journeys/data_stress_test_lens.ts
Expand Down
4 changes: 2 additions & 2 deletions dev_docs/tutorials/performance/adding_performance_journey.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ In order to achieve our goal of creating best user experience in Kibana, it is i
To make things easier, we introduced performance journeys, that mimics end-user experience with Kibana.

Journey runs a flow of user interactions with Kibana in a browser and collects APM metrics for both server and client-side.
It is possible to instrument Kibana with [custom performance metrics](https://docs.elastic.dev/kibana-dev-docs/tutorials/performance/adding_custom_performance_metrics),
It is possible to instrument Kibana with [custom performance metrics](https://docs.elastic.dev/kibana-dev-docs/tutorial/performance/adding_custom_performance_metrics),
that will provide more detailed information about feature performance.

Journeys core is [kbn-journeys](packages/kbn-journeys/README.mdx) package. It is a function test by design and is powered
Expand Down Expand Up @@ -61,7 +61,7 @@ Scripts steps include:

You can skip warmup phase for debug purpose by using `--skip-warmup` flag

Since the tests are run on a local machine, there is also realistic throttling applied to the network to
Since the tests are run on a local machine, there is also realistic throttling applied to the network to
simulate real life internet connection. This means that all requests have a fixed latency and limited bandwidth.

### Benchmarking performance on CI
Expand Down
5 changes: 2 additions & 3 deletions packages/kbn-journeys/journey/journey_ftr_harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,8 @@ export class JourneyFtrHarness {
return await block();
}

const span = this.apm?.startSpan(name, type ?? null, {
childOf: this.currentTransaction,
});
const span = this.currentTransaction.startSpan(name, type ?? null);

if (!span) {
return await block();
}
Expand Down
32 changes: 32 additions & 0 deletions x-pack/performance/journeys/many_fields_transform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { Journey } from '@kbn/journeys';
import { subj } from '@kbn/test-subj-selector';
import { waitForChrome } from '../utils';

export const journey = new Journey({
kbnArchives: ['test/functional/fixtures/kbn_archiver/many_fields_data_view'],
esArchives: ['test/functional/fixtures/es_archiver/many_fields'],
})
.step('Go to Transforms', async ({ page, kbnUrl }) => {
await page.goto(kbnUrl.get(`app/management/data/transform`));
await waitForChrome(page);
await page.waitForSelector(subj('transformCreateFirstButton'));
await page.waitForSelector(subj('globalLoadingIndicator-hidden'));
})
.step('Go to data view selection', async ({ page }) => {
const createButtons = page.locator(subj('transformCreateFirstButton'));
await createButtons.first().click();
await page.waitForSelector(subj('savedObjectsFinderTable'));
})
.step('Go to Transform Wizard', async ({ page }) => {
await page.click(subj('savedObjectTitleindices-stats*'));
// Extended the timeout, this one tracks a known issue with slow data grid performance with many fields
await page.waitForSelector(subj('transformIndexPreview loaded'), { timeout: 120000 });
await page.waitForSelector(subj('globalLoadingIndicator-hidden'), { timeout: 120000 });
});
15 changes: 12 additions & 3 deletions x-pack/plugins/cases/common/api/cases/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import {
MAX_LENGTH_PER_TAG,
MAX_CATEGORY_LENGTH,
MAX_TAGS_PER_CASE,
MAX_ASSIGNEES_FILTER_LENGTH,
MAX_REPORTERS_FILTER_LENGTH,
MAX_TAGS_FILTER_LENGTH,
} from '../../constants';

export const AttachmentTotalsRt = rt.strict({
Expand Down Expand Up @@ -220,7 +223,7 @@ export const CasesFindRequestRt = rt.exact(
/**
* Tags to filter by
*/
tags: rt.union([rt.array(rt.string), rt.string]),
tags: rt.union([limitedArraySchema(rt.string, 0, MAX_TAGS_FILTER_LENGTH, 'tags'), rt.string]),
/**
* The status of the case (open, closed, in-progress)
*/
Expand All @@ -232,11 +235,17 @@ export const CasesFindRequestRt = rt.exact(
/**
* The uids of the user profiles to filter by
*/
assignees: rt.union([rt.array(rt.string), rt.string]),
assignees: rt.union([
limitedArraySchema(rt.string, 0, MAX_ASSIGNEES_FILTER_LENGTH, 'assignees'),
rt.string,
]),
/**
* The reporters to filter by
*/
reporters: rt.union([rt.array(rt.string), rt.string]),
reporters: rt.union([
limitedArraySchema(rt.string, 0, MAX_REPORTERS_FILTER_LENGTH, 'reporters'),
rt.string,
]),
/**
* Operator to use for the `search` field
*/
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/cases/common/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ export const MAX_CONCURRENT_SEARCHES = 10 as const;
export const MAX_BULK_GET_CASES = 1000 as const;
export const MAX_COMMENTS_PER_PAGE = 100 as const;
export const MAX_CATEGORY_FILTER_LENGTH = 100 as const;
export const MAX_TAGS_FILTER_LENGTH = 100 as const;
export const MAX_ASSIGNEES_FILTER_LENGTH = 100 as const;
export const MAX_REPORTERS_FILTER_LENGTH = 100 as const;

/**
* Validation
Expand Down
9 changes: 6 additions & 3 deletions x-pack/plugins/cases/docs/openapi/bundled.json
Original file line number Diff line number Diff line change
Expand Up @@ -3834,7 +3834,8 @@
"type": "array",
"items": {
"type": "string"
}
},
"maxItems": 100
}
]
}
Expand Down Expand Up @@ -3930,7 +3931,8 @@
"type": "array",
"items": {
"type": "string"
}
},
"maxItems": 100
}
]
},
Expand Down Expand Up @@ -4031,7 +4033,8 @@
"type": "array",
"items": {
"type": "string"
}
},
"maxItems": 100
}
]
},
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/cases/docs/openapi/bundled.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2326,6 +2326,7 @@ components:
- type: array
items:
type: string
maxItems: 100
category:
in: query
name: category
Expand Down Expand Up @@ -2392,6 +2393,7 @@ components:
- type: array
items:
type: string
maxItems: 100
example: elastic
search:
in: query
Expand Down Expand Up @@ -2463,6 +2465,7 @@ components:
- type: array
items:
type: string
maxItems: 100
example: tag-1
to:
in: query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ schema:
- type: string
- type: array
items:
type: string
type: string
maxItems: 100
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ schema:
- type: array
items:
type: string
example: elastic
maxItems: 100
example: elastic
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ schema:
- type: array
items:
type: string
example: tag-1
maxItems: 100
example: tag-1
37 changes: 36 additions & 1 deletion x-pack/plugins/cases/server/client/cases/find.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import { v1 as uuidv1 } from 'uuid';

import type { Case } from '../../../common/api';

import { MAX_CATEGORY_FILTER_LENGTH } from '../../../common/constants';
import {
MAX_ASSIGNEES_FILTER_LENGTH,
MAX_CATEGORY_FILTER_LENGTH,
MAX_REPORTERS_FILTER_LENGTH,
MAX_TAGS_FILTER_LENGTH,
} from '../../../common/constants';
import { flattenCaseSavedObject } from '../../common/utils';
import { mockCases } from '../../mocks';
import { createCasesClientMockArgs, createCasesClientMockFindRequest } from '../mocks';
Expand Down Expand Up @@ -114,5 +119,35 @@ describe('find', () => {
`Error: Too many categories provided. The maximum allowed is ${MAX_CATEGORY_FILTER_LENGTH}`
);
});

it(`throws an error when the tags array has ${MAX_TAGS_FILTER_LENGTH} items`, async () => {
const tags = Array(MAX_TAGS_FILTER_LENGTH + 1).fill('foobar');

const findRequest = createCasesClientMockFindRequest({ tags });

await expect(find(findRequest, clientArgs)).rejects.toThrowError(
`Error: The length of the field tags is too long. Array must be of length <= ${MAX_TAGS_FILTER_LENGTH}`
);
});

it(`throws an error when the assignees array has ${MAX_ASSIGNEES_FILTER_LENGTH} items`, async () => {
const assignees = Array(MAX_ASSIGNEES_FILTER_LENGTH + 1).fill('foobar');

const findRequest = createCasesClientMockFindRequest({ assignees });

await expect(find(findRequest, clientArgs)).rejects.toThrowError(
`Error: The length of the field assignees is too long. Array must be of length <= ${MAX_ASSIGNEES_FILTER_LENGTH}`
);
});

it(`throws an error when the reporters array has ${MAX_REPORTERS_FILTER_LENGTH} items`, async () => {
const reporters = Array(MAX_REPORTERS_FILTER_LENGTH + 1).fill('foobar');

const findRequest = createCasesClientMockFindRequest({ reporters });

await expect(find(findRequest, clientArgs)).rejects.toThrowError(
`Error: The length of the field reporters is too long. Array must be of length <= ${MAX_REPORTERS_FILTER_LENGTH}.`
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ dataStart.search.search = jest.fn(({ params }: IKibanaSearchRequest) => {
}) as ISearchGeneric;

const appDependencies: AppDependencies = {
analytics: coreStart.analytics,
application: coreStart.application,
charts: chartPluginMock.createStartContract(),
chrome: coreStart.chrome,
Expand Down
4 changes: 3 additions & 1 deletion x-pack/plugins/transform/public/app/app_dependencies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import type {
AnalyticsServiceStart,
ApplicationStart,
ChromeStart,
DocLinksStart,
Expand All @@ -15,12 +16,12 @@ import type {
NotificationsStart,
OverlayStart,
SavedObjectsStart,
ScopedHistory,
ThemeServiceStart,
} from '@kbn/core/public';
import type { SavedObjectsStart as SavedObjectsPluginStart } from '@kbn/saved-objects-plugin/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import type { ScopedHistory } from '@kbn/core/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { SpacesPluginStart } from '@kbn/spaces-plugin/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
Expand All @@ -38,6 +39,7 @@ import type { SettingsStart } from '@kbn/core-ui-settings-browser';
import type { GetMlSharedImportsReturnType } from '../shared_imports';

export interface AppDependencies {
analytics: AnalyticsServiceStart;
application: ApplicationStart;
charts: ChartsPluginStart;
chrome: ChromeStart;
Expand Down
27 changes: 25 additions & 2 deletions x-pack/plugins/transform/public/app/hooks/use_index_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
* 2.0.
*/

import { useEffect, useMemo, useState } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';

import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import type { EuiDataGridColumn } from '@elastic/eui';

import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
import { isRuntimeMappings } from '@kbn/ml-runtime-field-utils';
import { buildBaseFilterCriteria } from '@kbn/ml-query-utils';
import {
Expand Down Expand Up @@ -39,7 +40,7 @@ import {
import { getErrorMessage } from '../../../common/utils/errors';

import { isDefaultQuery, matchAllQuery, TransformConfigQuery } from '../common';
import { useToastNotifications } from '../app_dependencies';
import { useToastNotifications, useAppDependencies } from '../app_dependencies';
import type { StepDefineExposedState } from '../sections/create_transform/components/step_define/common';

import { SearchItems } from './use_search_items';
Expand All @@ -52,6 +53,12 @@ export const useIndexData = (
combinedRuntimeMappings?: StepDefineExposedState['runtimeMappings'],
timeRangeMs?: TimeRangeMs
): UseIndexDataReturnType => {
const { analytics } = useAppDependencies();

// Store the performance metric's start time using a ref
// to be able to track it across rerenders.
const loadIndexDataStartTime = useRef<number | undefined>(window.performance.now());

const indexPattern = useMemo(() => dataView.getIndexPattern(), [dataView]);

const api = useApi();
Expand Down Expand Up @@ -315,6 +322,22 @@ export const useIndexData = (

const renderCellValue = useRenderCellValue(dataView, pagination, tableItems);

if (
dataGrid.status === INDEX_STATUS.LOADED &&
dataViewFields !== undefined &&
loadIndexDataStartTime.current !== undefined
) {
const loadIndexDataDuration = window.performance.now() - loadIndexDataStartTime.current;

// Set this to undefined so reporting the metric gets triggered only once.
loadIndexDataStartTime.current = undefined;

reportPerformanceMetricEvent(analytics, {
eventName: 'transformLoadIndexPreview',
duration: loadIndexDataDuration,
});
}

return {
...dataGrid,
renderCellValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export async function mountManagementSection(
const startServices = await getStartServices();
const [core, plugins] = startServices;
const {
analytics,
application,
chrome,
docLinks,
Expand Down Expand Up @@ -61,6 +62,7 @@ export async function mountManagementSection(

// AppCore/AppPlugins to be passed on as React context
const appDependencies: AppDependencies = {
analytics,
application,
chrome,
data,
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/transform/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
"@kbn/ml-runtime-field-utils",
"@kbn/ml-date-utils",
"@kbn/saved-search-plugin",
"@kbn/unified-field-list"
"@kbn/unified-field-list",
"@kbn/ebt-tools"
],
"exclude": [
"target/**/*",
Expand Down
Loading

0 comments on commit 719d163

Please sign in to comment.