diff --git a/x-pack/plugins/observability_solution/dataset_quality/README.md b/x-pack/plugins/observability_solution/dataset_quality/README.md index 32218e9982b6e..8aaba88966d0c 100755 --- a/x-pack/plugins/observability_solution/dataset_quality/README.md +++ b/x-pack/plugins/observability_solution/dataset_quality/README.md @@ -18,7 +18,31 @@ You can also run a specific test by passing the filepath as an argument, e.g.: yarn jest --config x-pack/plugins/observability_solution/dataset_quality/jest.config.js x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_streams/get_data_streams.test.ts ``` -#### API integration tests +### Deployment-agnostic API tests + +The deployment-agnostic API tests are located in [`x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality`](/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/). + +#### Start server and run test (stateful) + +```sh +# start server +node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts + +# run tests +node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts --grep=$ +``` + +#### Start server and run test (serverless) + +```sh +# start server +node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts + +# run tests +node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts --grep=$ +``` + +### API integration tests | Option | Description | | ------------ | ----------------------------------------------- | diff --git a/x-pack/test/api_integration/deployment_agnostic/README.md b/x-pack/test/api_integration/deployment_agnostic/README.md index d855b0d403f59..b029d0d167002 100644 --- a/x-pack/test/api_integration/deployment_agnostic/README.md +++ b/x-pack/test/api_integration/deployment_agnostic/README.md @@ -206,6 +206,28 @@ We do not recommend use of custom server arguments because it may lead to unexpe 6. Add FTR Configs Path to FTR Manifest Files Located in `.buildkite/` +## Running the tests + +### Stateful + +```sh +# start server +node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/.stateful.config.ts + +# run tests +node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/.stateful.config.ts --grep=$ +``` + +### Serverless + +```sh +# start server +node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/.serverless.config.ts + +# run tests +node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/.serverless.config.ts --grep=$ +``` + ## Tagging and Skipping the Tests Since deployment-agnostic tests are designed to run both locally and on MKI/Cloud, we believe no extra tagging is required. If a test is not working on MKI/Cloud or both, there is most likely an issue with the FTR service or the configuration file it uses. diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/index.ts new file mode 100644 index 0000000000000..73c58952b490b --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/index.ts @@ -0,0 +1,14 @@ +/* + * 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 { DeploymentAgnosticFtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ loadTestFile }: DeploymentAgnosticFtrProviderContext) { + describe('Dataset quality', () => { + loadTestFile(require.resolve('./integrations/integrations')); + }); +} diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/integrations/integrations.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/integrations/integrations.ts new file mode 100644 index 0000000000000..0e6d319cc0ff6 --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/dataset_quality/integrations/integrations.ts @@ -0,0 +1,137 @@ +/* + * 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 { RoleCredentials, InternalRequestHeader } from '@kbn/ftr-common-functional-services'; +import expect from '@kbn/expect'; +import { APIReturnType } from '@kbn/dataset-quality-plugin/common/rest'; +import { CustomIntegration } from '../../../../services/package_api'; +import { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ getService }: DeploymentAgnosticFtrProviderContext) { + const samlAuth = getService('samlAuth'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const packageApi = getService('packageApi'); + + const endpoint = 'GET /internal/dataset_quality/integrations'; + type Integration = APIReturnType['integrations'][0]; + + const integrationPackages = ['system', 'synthetics']; + const customIntegrations: CustomIntegration[] = [ + { + integrationName: 'my.custom.integration', + datasets: [ + { + name: 'my.custom.integration', + type: 'logs', + }, + ], + }, + ]; + + async function callApiAs({ + roleAuthc, + headers, + }: { + roleAuthc: RoleCredentials; + headers: InternalRequestHeader; + }): Promise { + const { body } = await supertestWithoutAuth + .get('/internal/dataset_quality/integrations') + .set(roleAuthc.apiKeyHeader) + .set(headers); + + return body; + } + + describe('Integrations', () => { + let adminRoleAuthc: RoleCredentials; + let internalHeaders: InternalRequestHeader; + + before(async () => { + adminRoleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('admin'); + internalHeaders = samlAuth.getInternalRequestHeader(); + }); + + after(async () => { + await samlAuth.invalidateM2mApiKeyWithRoleScope(adminRoleAuthc); + }); + + describe('gets the installed integrations', () => { + before(async () => { + await Promise.all( + integrationPackages.map((pkg) => + packageApi.installPackage({ + roleAuthc: adminRoleAuthc, + pkg, + }) + ) + ); + }); + + it('returns all installed integrations and its datasets map', async () => { + const body = await callApiAs({ + roleAuthc: adminRoleAuthc, + headers: internalHeaders, + }); + + expect(body.integrations.map((integration: Integration) => integration.name)).to.eql([ + 'synthetics', + 'system', + ]); + + expect(body.integrations[0].datasets).not.empty(); + expect(body.integrations[1].datasets).not.empty(); + }); + + after( + async () => + await Promise.all( + integrationPackages.map((pkg) => + packageApi.uninstallPackage({ roleAuthc: adminRoleAuthc, pkg }) + ) + ) + ); + }); + + describe('gets the custom installed integrations', () => { + before(async () => { + await Promise.all( + customIntegrations.map((customIntegration: CustomIntegration) => + packageApi.installCustomIntegration({ roleAuthc: adminRoleAuthc, customIntegration }) + ) + ); + }); + + it('returns custom integrations and its datasets map', async () => { + const body = await callApiAs({ + roleAuthc: adminRoleAuthc, + headers: internalHeaders, + }); + + expect(body.integrations.map((integration: Integration) => integration.name)).to.eql([ + 'my.custom.integration', + ]); + + expect(body.integrations[0].datasets).to.eql({ + 'my.custom.integration': 'My.custom.integration', + }); + }); + + after( + async () => + await Promise.all( + customIntegrations.map((customIntegration: CustomIntegration) => + packageApi.uninstallPackage({ + roleAuthc: adminRoleAuthc, + pkg: customIntegration.integrationName, + }) + ) + ) + ); + }); + }); +} diff --git a/x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.index.ts b/x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.index.ts index a58afc6349637..f734f0b805d85 100644 --- a/x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.index.ts +++ b/x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.index.ts @@ -12,8 +12,9 @@ export default function ({ loadTestFile }: DeploymentAgnosticFtrProviderContext) loadTestFile(require.resolve('../../apis/console')); loadTestFile(require.resolve('../../apis/core')); loadTestFile(require.resolve('../../apis/management')); + loadTestFile(require.resolve('../../apis/observability/alerting')); + loadTestFile(require.resolve('../../apis/observability/dataset_quality')); loadTestFile(require.resolve('../../apis/painless_lab')); loadTestFile(require.resolve('../../apis/saved_objects_management')); - loadTestFile(require.resolve('../../apis/observability/alerting')); }); } diff --git a/x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.index.ts b/x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.index.ts index b4b28a10a40d7..cb51d672ab972 100644 --- a/x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.index.ts +++ b/x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.index.ts @@ -11,5 +11,6 @@ export default function ({ loadTestFile }: DeploymentAgnosticFtrProviderContext) describe('apis', () => { // load new oblt deployment-agnostic test here loadTestFile(require.resolve('../../apis/observability/alerting')); + loadTestFile(require.resolve('../../apis/observability/dataset_quality')); }); } diff --git a/x-pack/test/api_integration/deployment_agnostic/default_configs/fixtures/package_registry_config.yml b/x-pack/test/api_integration/deployment_agnostic/default_configs/fixtures/package_registry_config.yml new file mode 100644 index 0000000000000..1885fa5c2ebe5 --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/default_configs/fixtures/package_registry_config.yml @@ -0,0 +1,2 @@ +package_paths: + - /packages/package-storage diff --git a/x-pack/test/api_integration/deployment_agnostic/default_configs/serverless.config.base.ts b/x-pack/test/api_integration/deployment_agnostic/default_configs/serverless.config.base.ts index 11f5a116e0a49..73506a5d5b684 100644 --- a/x-pack/test/api_integration/deployment_agnostic/default_configs/serverless.config.base.ts +++ b/x-pack/test/api_integration/deployment_agnostic/default_configs/serverless.config.base.ts @@ -4,9 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { FtrConfigProviderContext, Config } from '@kbn/test'; +import { FtrConfigProviderContext, Config, defineDockerServersConfig } from '@kbn/test'; import { ServerlessProjectType } from '@kbn/es'; +import path from 'path'; +import { dockerImage } from '../../../fleet_api_integration/config.base'; import { DeploymentAgnosticCommonServices, services } from '../services'; interface CreateTestConfigOptions { @@ -65,6 +67,17 @@ export function createServerlessTestConfig { @@ -46,6 +48,17 @@ export function createStatefulTestConfig { - describe('gets the installed integrations', () => { - before(async () => { - await Promise.all(integrationPackages.map((pkg) => installPackage({ supertest, pkg }))); - }); - - it('returns all installed integrations and its datasets map', async () => { - const resp = await callApiAs(); - - expect(resp.body.integrations.map((integration) => integration.name)).to.eql([ - 'apm', - 'endpoint', - 'synthetics', - 'system', - ]); - - expect(resp.body.integrations[0].datasets).not.empty(); - expect(resp.body.integrations[1].datasets).not.empty(); - expect(resp.body.integrations[2].datasets).not.empty(); - }); - - after( - async () => - await Promise.all(integrationPackages.map((pkg) => uninstallPackage({ supertest, pkg }))) - ); - }); - - describe('gets the custom installed integrations', () => { - before(async () => { - await Promise.all( - customIntegrations.map((customIntegration: CustomIntegration) => - installCustomIntegration({ supertest, customIntegration }) - ) - ); - }); - - it('returns custom integrations and its datasets map', async () => { - const resp = await callApiAs(); - - expect(resp.body.integrations.map((integration) => integration.name)).to.eql([ - 'my.custom.integration', - ]); - - expect(resp.body.integrations[0].datasets).to.eql({ - 'my.custom.integration': 'My.custom.integration', - }); - }); - - after( - async () => - await Promise.all( - customIntegrations.map((customIntegration: CustomIntegration) => - uninstallPackage({ - supertest, - pkg: customIntegration.integrationName, - }) - ) - ) - ); - }); - }); -} diff --git a/x-pack/test/dataset_quality_api_integration/tests/integrations/package_utils.ts b/x-pack/test/dataset_quality_api_integration/tests/integrations/package_utils.ts index 8d9dd9d1b051d..728d9e0b81e2e 100644 --- a/x-pack/test/dataset_quality_api_integration/tests/integrations/package_utils.ts +++ b/x-pack/test/dataset_quality_api_integration/tests/integrations/package_utils.ts @@ -7,31 +7,6 @@ import { Agent as SuperTestAgent } from 'supertest'; -export interface CustomIntegration { - integrationName: string; - datasets: IntegrationDataset[]; -} - -export interface IntegrationDataset { - name: string; - type: 'logs' | 'metrics' | 'synthetics'; -} - -export async function installCustomIntegration({ - supertest, - customIntegration, -}: { - supertest: SuperTestAgent; - customIntegration: CustomIntegration; -}) { - const { integrationName, datasets } = customIntegration; - - return supertest - .post(`/api/fleet/epm/custom_integrations`) - .set('kbn-xsrf', 'xxxx') - .send({ integrationName, datasets }); -} - export async function installPackage({ supertest, pkg,