Skip to content

Commit

Permalink
[8.x] [Dataset quality] Integrations agnostic-deployment api tests (#…
Browse files Browse the repository at this point in the history
…193144) (#193939)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Dataset quality] Integrations agnostic-deployment api tests
(#193144)](#193144)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Yngrid
Coello","email":"yngrid.coello@elastic.co"},"sourceCommit":{"committedDate":"2024-09-17T17:52:17Z","message":"[Dataset
quality] Integrations agnostic-deployment api tests (#193144)\n\nRelates
to #191980 PR aims
to introduce deployment-agnostic configuration for dataset\r\nquality
tests, specifically targeting
`GET\r\n/internal/dataset_quality/integrations`.","sha":"45c71c5a6b8f53eeb2c82c4319dfac0205668a8c","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor","ci:project-deploy-observability","v8.16.0"],"number":193144,"url":"#193144
quality] Integrations agnostic-deployment api tests (#193144)\n\nRelates
to #191980 PR aims
to introduce deployment-agnostic configuration for dataset\r\nquality
tests, specifically targeting
`GET\r\n/internal/dataset_quality/integrations`.","sha":"45c71c5a6b8f53eeb2c82c4319dfac0205668a8c"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"#193144
quality] Integrations agnostic-deployment api tests (#193144)\n\nRelates
to #191980 PR aims
to introduce deployment-agnostic configuration for dataset\r\nquality
tests, specifically targeting
`GET\r\n/internal/dataset_quality/integrations`.","sha":"45c71c5a6b8f53eeb2c82c4319dfac0205668a8c"}},{"branch":"8.x","label":"v8.16.0","labelRegex":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
  • Loading branch information
yngrdyn committed Sep 25, 2024
1 parent 86a065d commit f1a6bd5
Show file tree
Hide file tree
Showing 13 changed files with 325 additions and 137 deletions.
26 changes: 25 additions & 1 deletion x-pack/plugins/observability_solution/dataset_quality/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
| ------------ | ----------------------------------------------- |
Expand Down
22 changes: 22 additions & 0 deletions x-pack/test/api_integration/deployment_agnostic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<solution>.stateful.config.ts

# run tests
node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/<solution>.stateful.config.ts --grep=$
```

### Serverless

```sh
# start server
node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/<solution>.serverless.config.ts

# run tests
node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/<solution>.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.

Expand Down
Original file line number Diff line number Diff line change
@@ -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'));
});
}
Original file line number Diff line number Diff line change
@@ -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<typeof endpoint>['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<any> {
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,
})
)
)
);
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package_paths:
- /packages/package-storage
Original file line number Diff line number Diff line change
Expand Up @@ -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<T extends DeploymentAgnosticCommonServices> {
Expand Down Expand Up @@ -65,6 +67,17 @@ export function createServerlessTestConfig<T extends DeploymentAgnosticCommonSer
);
}

const packageRegistryConfig = path.join(__dirname, './fixtures/package_registry_config.yml');
const dockerArgs: string[] = ['-v', `${packageRegistryConfig}:/package-registry/config.yml`];

/**
* This is used by CI to set the docker registry port
* you can also define this environment variable locally when running tests which
* will spin up a local docker package registry locally for you
* if this is defined it takes precedence over the `packageRegistryOverride` variable
*/
const dockerRegistryPort: string | undefined = process.env.FLEET_PACKAGE_REGISTRY_PORT;

const svlSharedConfig = await readConfigFile(
require.resolve('@kbn/test-suites-serverless/shared/config.base')
);
Expand All @@ -76,6 +89,17 @@ export function createServerlessTestConfig<T extends DeploymentAgnosticCommonSer
// services can be customized, but must extend DeploymentAgnosticCommonServices
...(options.services || services),
},
dockerServers: defineDockerServersConfig({
registry: {
enabled: !!dockerRegistryPort,
image: dockerImage,
portInContainer: 8080,
port: dockerRegistryPort,
args: dockerArgs,
waitForLogLine: 'package manifests loaded',
waitForLogLineTimeoutMs: 60 * 2 * 1000, // 2 minutes
},
}),
esTestCluster: {
...svlSharedConfig.get('esTestCluster'),
serverArgs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ import {
kbnTestConfig,
systemIndicesSuperuser,
FtrConfigProviderContext,
defineDockerServersConfig,
} from '@kbn/test';
import path from 'path';
import { REPO_ROOT } from '@kbn/repo-info';
import { STATEFUL_ROLES_ROOT_PATH } from '@kbn/es';
import { dockerImage } from '../../../fleet_api_integration/config.base';
import { DeploymentAgnosticCommonServices, services } from '../services';

interface CreateTestConfigOptions<T extends DeploymentAgnosticCommonServices> {
Expand All @@ -46,6 +48,17 @@ export function createStatefulTestConfig<T extends DeploymentAgnosticCommonServi
// if config is executed on CI or locally
const isRunOnCI = process.env.CI;

const packageRegistryConfig = path.join(__dirname, './fixtures/package_registry_config.yml');
const dockerArgs: string[] = ['-v', `${packageRegistryConfig}:/package-registry/config.yml`];

/**
* This is used by CI to set the docker registry port
* you can also define this environment variable locally when running tests which
* will spin up a local docker package registry locally for you
* if this is defined it takes precedence over the `packageRegistryOverride` variable
*/
const dockerRegistryPort: string | undefined = process.env.FLEET_PACKAGE_REGISTRY_PORT;

const xPackAPITestsConfig = await readConfigFile(require.resolve('../../config.ts'));

// TODO: move to kbn-es because currently metadata file has hardcoded entityID and Location
Expand All @@ -72,6 +85,17 @@ export function createStatefulTestConfig<T extends DeploymentAgnosticCommonServi

return {
servers,
dockerServers: defineDockerServersConfig({
registry: {
enabled: !!dockerRegistryPort,
image: dockerImage,
portInContainer: 8080,
port: dockerRegistryPort,
args: dockerArgs,
waitForLogLine: 'package manifests loaded',
waitForLogLineTimeoutMs: 60 * 2 * 1000, // 2 minutes
},
}),
testFiles: options.testFiles,
security: { disableTestUser: true },
// services can be customized, but must extend DeploymentAgnosticCommonServices
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
*/

import { commonFunctionalServices } from '@kbn/ftr-common-functional-services';
import { deploymentAgnosticServices } from './deployment_agnostic_services';
import { DataViewApiProvider } from './data_view_api';
import { SloApiProvider } from './slo_api';
import { AlertingApiProvider } from './alerting_api';
import { DataViewApiProvider } from './data_view_api';
import { deploymentAgnosticServices } from './deployment_agnostic_services';
import { PackageApiProvider } from './package_api';
import { RoleScopedSupertestProvider, SupertestWithRoleScope } from './role_scoped_supertest';
import { SloApiProvider } from './slo_api';

export type {
InternalRequestHeader,
Expand All @@ -24,6 +25,7 @@ export const services = {
samlAuth: commonFunctionalServices.samlAuth,
alertingApi: AlertingApiProvider,
dataViewApi: DataViewApiProvider,
packageApi: PackageApiProvider,
sloApi: SloApiProvider,
roleScopedSupertest: RoleScopedSupertestProvider,
// create a new deployment-agnostic service and load here
Expand Down
Loading

0 comments on commit f1a6bd5

Please sign in to comment.