Skip to content

Commit e44800b

Browse files
jennypavlovakibanamachinedmlemeshko
authored andcommitted
[Profiling] Migrate cypress tests to scout (elastic#239964)
Closes elastic#210183 ## Summary This PR creates the initial setup for the e2e Profiling tests in Scout, migrating from Cypress. ⚠️ The Cypress tests will be fully migrated and removed in follow-up PRs, including the removal of the data fixture from Cypress (currently duplicated here) --------- Co-authored-by: kibanamachine <[email protected]> Co-authored-by: Dzmitry Lemechko <[email protected]>
1 parent 9761f87 commit e44800b

File tree

31 files changed

+27842
-26
lines changed

31 files changed

+27842
-26
lines changed

.buildkite/scout_ci_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ plugins:
77
- observability
88
- observability_onboarding
99
- painless_lab
10+
- profiling
1011
- security_solution
1112
- streams_app
1213
- slo

src/platform/packages/shared/kbn-scout/src/config/stateful/base.config.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010
import { join, resolve } from 'path';
1111
import { format as formatUrl } from 'url';
1212

13+
import { STATEFUL_ROLES_ROOT_PATH } from '@kbn/es';
1314
import {
14-
MOCK_IDP_ENTITY_ID,
15-
MOCK_IDP_ATTRIBUTE_PRINCIPAL,
16-
MOCK_IDP_ATTRIBUTE_ROLES,
1715
MOCK_IDP_ATTRIBUTE_EMAIL,
1816
MOCK_IDP_ATTRIBUTE_NAME,
17+
MOCK_IDP_ATTRIBUTE_PRINCIPAL,
18+
MOCK_IDP_ATTRIBUTE_ROLES,
19+
MOCK_IDP_ENTITY_ID,
20+
MOCK_IDP_REALM_NAME,
1921
} from '@kbn/mock-idp-utils';
20-
import { fleetPackageRegistryDockerImage, defineDockerServersConfig } from '@kbn/test';
21-
import { MOCK_IDP_REALM_NAME } from '@kbn/mock-idp-utils';
2222
import { REPO_ROOT } from '@kbn/repo-info';
23-
import { STATEFUL_ROLES_ROOT_PATH } from '@kbn/es';
23+
import { defineDockerServersConfig, fleetPackageRegistryDockerImage } from '@kbn/test';
2424
import type { ScoutServerConfig } from '../../types';
2525
import { SAML_IDP_PLUGIN_PATH, STATEFUL_IDP_METADATA_PATH } from '../constants';
2626

@@ -178,6 +178,27 @@ export const defaultConfig: ScoutServerConfig = {
178178
'--xpack.ruleRegistry.write.enabled=true',
179179
'--xpack.ruleRegistry.write.cache.enabled=false',
180180
'--monitoring_collection.opentelemetry.metrics.prometheus.enabled=true',
181+
'--xpack.profiling.enabled=true',
182+
// Fleet configuration
183+
`--xpack.fleet.fleetServerHosts=${JSON.stringify([
184+
{
185+
id: 'default-fleet-server',
186+
name: 'Default Fleet Server',
187+
is_default: true,
188+
host_urls: ['https://localhost:8220'],
189+
},
190+
])}`,
191+
`--xpack.fleet.outputs=${JSON.stringify([
192+
{
193+
id: 'es-default-output',
194+
name: 'Default Output',
195+
type: 'elasticsearch',
196+
is_default: true,
197+
is_default_monitoring: true,
198+
hosts: ['https://localhost:9200'],
199+
},
200+
])}`,
201+
// Agent policies are now created via Fleet API using the helper function from @kbn-scout
181202
// SAML configuration
182203
...(isRunOnCI ? [] : ['--mockIdpPlugin.enabled=true']),
183204
// This ensures that we register the Security SAML API endpoints.

src/platform/packages/shared/kbn-scout/src/playwright/fixtures/scope/worker/apis/fleet/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import type {
1818
} from './types';
1919

2020
export interface FleetApiService {
21+
internal: {
22+
setup: () => Promise<any>;
23+
};
2124
integration: {
2225
install: (name: string) => Promise<any>;
2326
delete: (name: string) => Promise<any>;
@@ -73,6 +76,16 @@ export interface FleetApiService {
7376

7477
export const getFleetApiHelper = (log: ScoutLogger, kbnClient: KbnClient): FleetApiService => {
7578
return {
79+
internal: {
80+
setup: async () => {
81+
return await measurePerformanceAsync(log, `fleetApi.internal.setup`, async () => {
82+
return await kbnClient.request({
83+
method: 'POST',
84+
path: '/api/fleet/setup',
85+
});
86+
});
87+
},
88+
},
7689
integration: {
7790
install: async (name: string) => {
7891
return await measurePerformanceAsync(

x-pack/solutions/observability/packages/kbn-scout-oblt/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
export { test, spaceTest } from './src/playwright';
1010

1111
// re-exported test framework from @kbn/scout
12-
export { expect, lighthouseTest, apiTest, globalSetupHook, tags } from '@kbn/scout';
12+
export { expect, lighthouseTest, apiTest, tags } from '@kbn/scout';
13+
14+
// Custom global setup hook with profiling support
15+
export { globalSetupHook } from './src/playwright/global_hooks/profiling_setup';
1316

1417
// re-exported fixtures & configuration from @kbn/scout
1518
export {

x-pack/solutions/observability/packages/kbn-scout-oblt/src/playwright/fixtures/parallel_run_fixtures.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,18 @@
55
* 2.0.
66
*/
77

8-
import { spaceTest as spaceBase } from '@kbn/scout';
8+
import { spaceTest as spaceBase, mergeTests } from '@kbn/scout';
99
import type { ApiServicesFixture, KbnClient } from '@kbn/scout';
1010
import { extendPageObjects } from '../page_objects';
11+
import { profilingSetupFixture } from './worker';
1112

1213
import type {
1314
ObltApiServicesFixture,
1415
ObltParallelTestFixtures,
1516
ObltParallelWorkerFixtures,
1617
} from './types';
1718

18-
/**
19-
* Should be used test spec files, running in parallel in isolated spaces against the same Kibana instance.
20-
*/
21-
export const spaceTest = spaceBase.extend<ObltParallelTestFixtures, ObltParallelWorkerFixtures>({
19+
const baseFixture = spaceBase.extend<ObltParallelTestFixtures, ObltParallelWorkerFixtures>({
2220
pageObjects: async (
2321
{
2422
pageObjects,
@@ -46,3 +44,8 @@ export const spaceTest = spaceBase.extend<ObltParallelTestFixtures, ObltParallel
4644
{ scope: 'worker' },
4745
],
4846
});
47+
48+
/**
49+
* Should be used test spec files, running in parallel in isolated spaces against the same Kibana instance.
50+
*/
51+
export const spaceTest = mergeTests(baseFixture, profilingSetupFixture);

x-pack/solutions/observability/packages/kbn-scout-oblt/src/playwright/fixtures/single_thread_fixtures.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type { ApiServicesFixture, KbnClient } from '@kbn/scout';
1010

1111
import { extendPageObjects } from '../page_objects';
1212
import type { ObltApiServicesFixture, ObltTestFixtures, ObltWorkerFixtures } from './types';
13-
import { sloDataFixture } from './worker';
13+
import { sloDataFixture, profilingSetupFixture } from './worker';
1414

1515
const baseFixture = base.extend<ObltTestFixtures, ObltWorkerFixtures>({
1616
pageObjects: async (
@@ -43,4 +43,4 @@ const baseFixture = base.extend<ObltTestFixtures, ObltWorkerFixtures>({
4343
/**
4444
* Should be used for the test spec files executed sequentially.
4545
*/
46-
export const test = mergeTests(baseFixture, sloDataFixture);
46+
export const test = mergeTests(baseFixture, sloDataFixture, profilingSetupFixture);

x-pack/solutions/observability/packages/kbn-scout-oblt/src/playwright/fixtures/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import type {
1313
ScoutWorkerFixtures,
1414
} from '@kbn/scout';
1515
import type { ObltPageObjects } from '../page_objects';
16-
import type { SloDataFixture } from './worker';
16+
import type { SloDataFixture, ProfilingSetupFixture } from './worker';
1717

1818
export interface ObltTestFixtures extends ScoutTestFixtures {
1919
pageObjects: ObltPageObjects;
@@ -24,6 +24,7 @@ export type ObltApiServicesFixture = ApiServicesFixture;
2424
export interface ObltWorkerFixtures extends ScoutWorkerFixtures {
2525
apiServices: ObltApiServicesFixture;
2626
sloData: SloDataFixture;
27+
profilingSetup: ProfilingSetupFixture;
2728
}
2829

2930
export interface ObltParallelTestFixtures extends ScoutParallelTestFixtures {
@@ -32,4 +33,5 @@ export interface ObltParallelTestFixtures extends ScoutParallelTestFixtures {
3233

3334
export interface ObltParallelWorkerFixtures extends ScoutParallelWorkerFixtures {
3435
apiServices: ObltApiServicesFixture;
36+
profilingSetup: ProfilingSetupFixture;
3537
}

x-pack/solutions/observability/packages/kbn-scout-oblt/src/playwright/fixtures/worker/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@
77

88
export { sloDataFixture } from './slo_data';
99
export type { SloDataFixture } from './slo_data';
10+
11+
export { profilingSetupFixture } from './profiling';
12+
export type { ProfilingSetupFixture } from './profiling';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
export { profilingSetupFixture } from './profiling_setup_fixture';
9+
export type { ProfilingSetupFixture } from './profiling_setup_fixture';
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import { test as base } from '@kbn/scout';
9+
import path from 'path';
10+
import fs from 'fs';
11+
12+
export interface ProfilingSetupFixture {
13+
checkStatus: () => Promise<{ has_setup: boolean; has_data: boolean }>;
14+
setupResources: () => Promise<void>;
15+
loadData: () => Promise<void>;
16+
}
17+
18+
// This fixture should be used only in the global setup hook
19+
// because it needs to be run before any other test
20+
// and it needs to be run only once
21+
export const profilingSetupFixture = base.extend<{}, { profilingSetup: ProfilingSetupFixture }>({
22+
profilingSetup: [
23+
async ({ kbnClient, esClient, log }, use) => {
24+
const checkStatus = async (): Promise<{ has_setup: boolean; has_data: boolean }> => {
25+
try {
26+
const response = await kbnClient.request({
27+
description: 'Check profiling status',
28+
path: '/api/profiling/setup/es_resources',
29+
method: 'GET',
30+
});
31+
return response.data as { has_setup: boolean; has_data: boolean };
32+
} catch (error: any) {
33+
log.error(`Error checking profiling status: ${error}`);
34+
return { has_setup: false, has_data: false };
35+
}
36+
};
37+
38+
const setupResources = async (): Promise<void> => {
39+
try {
40+
log.info('Setting up profiling resources');
41+
await kbnClient.request({
42+
description: 'Setup profiling resources',
43+
path: '/api/profiling/setup/es_resources',
44+
method: 'POST',
45+
body: {},
46+
});
47+
log.info('Profiling resources set up successfully');
48+
} catch (error) {
49+
log.error(`Error setting up profiling resources: ${error}`);
50+
throw error;
51+
}
52+
};
53+
54+
const loadData = async (): Promise<void> => {
55+
try {
56+
log.info('Loading profiling data');
57+
58+
const PROFILING_DATA_PATH = path.join(
59+
__dirname,
60+
'./test_data/profiling_data_anonymized.json'
61+
);
62+
63+
if (!fs.existsSync(PROFILING_DATA_PATH)) {
64+
log.info('Profiling data file not found, skipping data loading');
65+
return;
66+
}
67+
68+
const profilingData = fs.readFileSync(PROFILING_DATA_PATH, 'utf8');
69+
const operations = profilingData.split('\n').filter((line: string) => line.trim());
70+
71+
// Use esClient for bulk operations
72+
const response = await esClient.bulk({
73+
body: operations.join('\n') + '\n',
74+
refresh: 'wait_for',
75+
timeout: '1m',
76+
});
77+
78+
if (response.errors) {
79+
const erroredItems = response.items?.filter((item: any) => item?.index?.error);
80+
log.error(
81+
`Some errors occurred during bulk indexing: ${JSON.stringify(erroredItems, null, 2)}`
82+
);
83+
} else {
84+
log.info(`Successfully indexed ${response.items?.length || 0} profiling documents`);
85+
}
86+
} catch (error) {
87+
log.error(`Error loading profiling data: ${error}`);
88+
throw error;
89+
}
90+
};
91+
92+
await use({
93+
checkStatus,
94+
setupResources,
95+
loadData,
96+
});
97+
},
98+
{ scope: 'worker' },
99+
],
100+
});

0 commit comments

Comments
 (0)