[Dataset quality] Use dockerized package registry in api tests (#190688)

Closes https://github.com/elastic/kibana/issues/189802.

This PR aims to use a dockerized package registry version for testing.
In order to test it locally you have to set the value of
`FLEET_PACKAGE_REGISTRY_PORT` env var in your terminal, and you also
need to have a docker daemon running.

For example, you can open a terminal and start the server
```
  node x-pack/plugins/observability_solution/dataset_quality/scripts/api --server
```
then open a new terminal set the var value and start the runner with the
specific test using this configuration
```
  export set FLEET_PACKAGE_REGISTRY_PORT=12345
  node x-pack/plugins/observability_solution/dataset_quality/scripts/api --runner --grep-files=integrations
```
If you want to test again without the dockerized version, you should
remove the value of the var
```
  unset FLEET_PACKAGE_REGISTRY_PORT 
```
This commit is contained in:
Yngrid Coello 2024-08-22 11:06:42 +02:00 committed by GitHub
parent 2d44619f07
commit a04e5f94e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 87 additions and 79 deletions

View file

@ -50,6 +50,21 @@ node x-pack/plugins/observability_solution/dataset_quality/scripts/api --server
node x-pack/plugins/observability_solution/dataset_quality/scripts/api --runner --grep-files=data_stream_settings.spec.ts
```
### Using dockerized package registry
For tests using package registry we have enabled a configuration that uses a dockerized lite version to execute the tests in the CI, this will reduce the flakyness of them when calling the real endpoint.
To be able to run this version locally you must have a docker daemon running in your systema and set `FLEET_PACKAGE_REGISTRY_PORT` env var. In order to set this variable execute
```
export set FLEET_PACKAGE_REGISTRY_PORT=12345
```
To unset the variable, and run the tests against the real endpoint again, execute
```
unset FLEET_PACKAGE_REGISTRY_PORT
```
### Functional Tests

View file

@ -5,24 +5,26 @@
* 2.0.
*/
import {
DatasetQualityUsername,
DATASET_QUALITY_TEST_PASSWORD,
} from '@kbn/dataset-quality-plugin/server/test_helpers/create_dataset_quality_users/authentication';
import { LogLevel, LogsSynthtraceEsClient, createLogger } from '@kbn/apm-synthtrace';
import { createDatasetQualityUsers } from '@kbn/dataset-quality-plugin/server/test_helpers/create_dataset_quality_users';
import { FtrConfigProviderContext } from '@kbn/test';
import {
DATASET_QUALITY_TEST_PASSWORD,
DatasetQualityUsername,
} from '@kbn/dataset-quality-plugin/server/test_helpers/create_dataset_quality_users/authentication';
import { FtrConfigProviderContext, defineDockerServersConfig } from '@kbn/test';
import path from 'path';
import supertest from 'supertest';
import { format, UrlObject } from 'url';
import { createLogger, LogLevel, LogsSynthtraceEsClient } from '@kbn/apm-synthtrace';
import { UrlObject, format } from 'url';
import { dockerImage } from '../../fleet_api_integration/config.base';
import { DatasetQualityFtrConfigName } from '../configs';
import { createDatasetQualityApiClient } from './dataset_quality_api_supertest';
import {
FtrProviderContext,
InheritedFtrProviderContext,
InheritedServices,
} from './ftr_provider_context';
import { createDatasetQualityApiClient } from './dataset_quality_api_supertest';
import { RegistryProvider } from './registry';
import { DatasetQualityFtrConfigName } from '../configs';
import { PackageService } from './package_service';
import { RegistryProvider } from './registry';
export interface DatasetQualityFtrConfig {
name: DatasetQualityFtrConfigName;
@ -84,19 +86,41 @@ export function createTestConfig(
const { license, name, kibanaConfig } = config;
return async ({ readConfigFile }: FtrConfigProviderContext) => {
const packageRegistryConfig = path.join(__dirname, './fixtures/package_registry_config.yml');
const xPackAPITestsConfig = await readConfigFile(
require.resolve('../../api_integration/config.ts')
);
const dockerArgs: string[] = ['-v', `${packageRegistryConfig}:/package-registry/config.yml`];
const services = xPackAPITestsConfig.get('services');
const servers = xPackAPITestsConfig.get('servers');
const kibanaServer = servers.kibana as UrlObject;
const kibanaServerUrl = format(kibanaServer);
const esServer = servers.elasticsearch as UrlObject;
/**
* 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;
return {
testFiles: [require.resolve('../tests')],
servers,
dockerServers: defineDockerServersConfig({
registry: {
enabled: !!dockerRegistryPort,
image: dockerImage,
portInContainer: 8080,
port: dockerRegistryPort,
args: dockerArgs,
waitForLogLine: 'package manifests loaded',
waitForLogLineTimeoutMs: 60 * 2 * 10000, // 2 minutes
},
}),
servicesRequiredForTestAnalysis: ['datasetQualityFtrConfig', 'registry'],
services: {
...services,
@ -157,6 +181,11 @@ export function createTestConfig(
kbnTestServer: {
...xPackAPITestsConfig.get('kbnTestServer'),
serverArgs: [
`--xpack.fleet.packages.0.name=endpoint`,
`--xpack.fleet.packages.0.version=latest`,
...(dockerRegistryPort
? [`--xpack.fleet.registryUrl=http://localhost:${dockerRegistryPort}`]
: []),
...xPackAPITestsConfig.get('kbnTestServer.serverArgs'),
...(kibanaConfig
? Object.entries(kibanaConfig).map(([key, value]) =>

View file

@ -0,0 +1,2 @@
package_paths:
- /packages/package-storage

View file

@ -8,25 +8,14 @@
import expect from '@kbn/expect';
import { DatasetQualityApiClientKey } from '../../common/config';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { installPackage, IntegrationPackage, uninstallPackage } from './package_utils';
import { installPackage, uninstallPackage } from './package_utils';
export default function ApiTest({ getService }: FtrProviderContext) {
const registry = getService('registry');
const supertest = getService('supertest');
const datasetQualityApiClient = getService('datasetQualityApiClient');
const integrationPackages: IntegrationPackage[] = [
{
// with dashboards
name: 'postgresql',
version: '1.19.0',
},
{
// without dashboards
name: 'apm',
version: '8.4.2',
},
];
const integrationPackages = ['nginx', 'apm'];
async function callApiAs(integration: string) {
const user = 'datasetQualityLogsUser' as DatasetQualityApiClientKey;
@ -43,13 +32,11 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when('Integration dashboards', { config: 'basic' }, () => {
describe('gets the installed integration dashboards', () => {
before(async () => {
await Promise.all(
integrationPackages.map((pkg: IntegrationPackage) => installPackage({ supertest, pkg }))
);
await Promise.all(integrationPackages.map((pkg) => installPackage({ supertest, pkg })));
});
it('returns a non-empty body', async () => {
const resp = await callApiAs(integrationPackages[0].name);
const resp = await callApiAs(integrationPackages[0]);
expect(resp.body).not.empty();
});
@ -57,20 +44,20 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const expectedResult = {
dashboards: [
{
id: 'postgresql-158be870-87f4-11e7-ad9c-db80de0bf8d3',
title: '[Logs PostgreSQL] Overview',
id: 'nginx-023d2930-f1a5-11e7-a9ef-93c69af7b129',
title: '[Metrics Nginx] Overview',
},
{
id: 'postgresql-4288b790-b79f-11e9-a579-f5c0a5d81340',
title: '[Metrics PostgreSQL] Database Overview',
id: 'nginx-046212a0-a2a1-11e7-928f-5dbe6f6f5519',
title: '[Logs Nginx] Access and error logs',
},
{
id: 'postgresql-e4c5f230-87f3-11e7-ad9c-db80de0bf8d3',
title: '[Logs PostgreSQL] Query Duration Overview',
id: 'nginx-55a9e6e0-a29e-11e7-928f-5dbe6f6f5519',
title: '[Logs Nginx] Overview',
},
],
};
const resp = await callApiAs(integrationPackages[0].name);
const resp = await callApiAs(integrationPackages[0]);
expect(resp.body).to.eql(expectedResult);
});
@ -78,7 +65,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const expectedResult = {
dashboards: [],
};
const resp = await callApiAs(integrationPackages[1].name);
const resp = await callApiAs(integrationPackages[1]);
expect(resp.body).to.eql(expectedResult);
});
@ -92,11 +79,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
after(
async () =>
await Promise.all(
integrationPackages.map((pkg: IntegrationPackage) =>
uninstallPackage({ supertest, pkg })
)
)
await Promise.all(integrationPackages.map((pkg) => uninstallPackage({ supertest, pkg })))
);
});
});

View file

@ -12,7 +12,6 @@ import {
CustomIntegration,
installCustomIntegration,
installPackage,
IntegrationPackage,
uninstallPackage,
} from './package_utils';
@ -21,23 +20,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const datasetQualityApiClient = getService('datasetQualityApiClient');
const integrationPackages: IntegrationPackage[] = [
{
// logs based integration
name: 'system',
version: '1.0.0',
},
{
// logs based integration
name: 'apm',
version: '8.0.0',
},
{
// non-logs based integration
name: 'synthetics',
version: '1.0.0',
},
];
const integrationPackages = ['system', 'apm', 'endpoint', 'synthetics'];
const customIntegrations: CustomIntegration[] = [
{
@ -67,9 +50,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
registry.when('Integration', { config: 'basic' }, () => {
describe('gets the installed integrations', () => {
before(async () => {
await Promise.all(
integrationPackages.map((pkg: IntegrationPackage) => installPackage({ supertest, pkg }))
);
await Promise.all(integrationPackages.map((pkg) => installPackage({ supertest, pkg })));
});
it('returns only log based integrations and its datasets map', async () => {
@ -77,20 +58,18 @@ export default function ApiTest({ getService }: FtrProviderContext) {
expect(resp.body.integrations.map((integration) => integration.name)).to.eql([
'apm',
'endpoint',
'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: IntegrationPackage) =>
uninstallPackage({ supertest, pkg })
)
)
await Promise.all(integrationPackages.map((pkg) => uninstallPackage({ supertest, pkg })))
);
});
@ -121,7 +100,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
customIntegrations.map((customIntegration: CustomIntegration) =>
uninstallPackage({
supertest,
pkg: { name: customIntegration.integrationName, version: '1.0.0' },
pkg: customIntegration.integrationName,
})
)
)

View file

@ -7,11 +7,6 @@
import { Agent as SuperTestAgent } from 'supertest';
export interface IntegrationPackage {
name: string;
version: string;
}
export interface CustomIntegration {
integrationName: string;
datasets: IntegrationDataset[];
@ -42,12 +37,19 @@ export async function installPackage({
pkg,
}: {
supertest: SuperTestAgent;
pkg: IntegrationPackage;
pkg: string;
}) {
const { name, version } = pkg;
const {
body: {
item: { latestVersion: version },
},
} = await supertest
.get(`/api/fleet/epm/packages/${pkg}`)
.set('kbn-xsrf', 'xxxx')
.send({ force: true });
return supertest
.post(`/api/fleet/epm/packages/${name}/${version}`)
.post(`/api/fleet/epm/packages/${pkg}/${version}`)
.set('kbn-xsrf', 'xxxx')
.send({ force: true });
}
@ -57,9 +59,7 @@ export async function uninstallPackage({
pkg,
}: {
supertest: SuperTestAgent;
pkg: IntegrationPackage;
pkg: string;
}) {
const { name, version } = pkg;
return supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx');
return supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx');
}