From b4b3b9a9410c2486a329372beec7375923d62032 Mon Sep 17 00:00:00 2001 From: Sergi Romeu Date: Tue, 12 Nov 2024 17:18:02 +0100 Subject: [PATCH] [APM] Migrate `/environment` to deployment agnostic test (#199582) ## Summary Closes https://github.com/elastic/kibana/issues/198969 Part of https://github.com/elastic/kibana/issues/193245 This PR contains the changes to migrate `environment` test folder to Deployment-agnostic testing strategy. ### How to test - Serverless ``` node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts --grep="APM" ``` It's recommended to be run against [MKI](https://github.com/crespocarlos/kibana/blob/main/x-pack/test_serverless/README.md#run-tests-on-mki) - Stateful ``` node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts --grep="APM" ``` ## Checks - [ ] (OPTIONAL, only if a test has been unskipped) Run flaky test suite - [x] local run for serverless - [x] local run for stateful - [x] MKI run for serverless --- .../apm/environment/get_environment.spec.ts | 155 ++++++++++++++++++ .../observability/apm/environment/index.ts | 14 ++ .../apis/observability/apm/index.ts | 1 + .../tests/environment/generate_data.ts | 67 -------- .../tests/environment/get_environment.spec.ts | 94 ----------- 5 files changed, 170 insertions(+), 161 deletions(-) create mode 100644 x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/environment/get_environment.spec.ts create mode 100644 x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/environment/index.ts delete mode 100644 x-pack/test/apm_api_integration/tests/environment/generate_data.ts delete mode 100644 x-pack/test/apm_api_integration/tests/environment/get_environment.spec.ts diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/environment/get_environment.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/environment/get_environment.spec.ts new file mode 100644 index 0000000000000..ba6f0df98e3a1 --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/environment/get_environment.spec.ts @@ -0,0 +1,155 @@ +/* + * 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 expect from '@kbn/expect'; +import { apm, timerange } from '@kbn/apm-synthtrace-client'; +import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; +import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; + +async function generateData({ + apmSynthtraceEsClient, + start, + end, +}: { + apmSynthtraceEsClient: ApmSynthtraceEsClient; + start: number; + end: number; +}) { + const environmentNames = ['production', 'development', 'staging']; + const serviceNames = ['go', 'java', 'node']; + + const services = environmentNames.flatMap((environment) => { + return serviceNames.flatMap((serviceName) => { + return apm + .service({ + name: serviceName, + environment, + agentName: serviceName, + }) + .instance('instance-a'); + }); + }); + + const goServiceWithAdditionalEnvironment = apm + .service({ + name: 'go', + environment: 'custom-go-environment', + agentName: 'go', + }) + .instance('instance-a'); + + // Generate a transaction for each service + const docs = timerange(start, end) + .ratePerMinute(1) + .generator((timestamp) => { + const loopGeneratedDocs = services.flatMap((service) => { + return service + .transaction({ transactionName: 'GET /api/product/:id' }) + .timestamp(timestamp) + .duration(1000); + }); + + const customDoc = goServiceWithAdditionalEnvironment + .transaction({ + transactionName: 'GET /api/go/memory', + transactionType: 'custom-go-type', + }) + .timestamp(timestamp) + .duration(1000); + + return [...loopGeneratedDocs, customDoc]; + }); + + return apmSynthtraceEsClient.index(docs); +} + +const startNumber = new Date('2021-01-01T00:00:00.000Z').getTime(); +const endNumber = new Date('2021-01-01T00:05:00.000Z').getTime() - 1; + +const start = new Date(startNumber).toISOString(); +const end = new Date(endNumber).toISOString(); + +export default function environmentsAPITests({ getService }: DeploymentAgnosticFtrProviderContext) { + const apmApiClient = getService('apmApi'); + const synthtrace = getService('synthtrace'); + + describe('get environments', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + + before(async () => { + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); + await generateData({ + apmSynthtraceEsClient, + start: startNumber, + end: endNumber, + }); + }); + + after(async () => { + await apmSynthtraceEsClient.clean(); + }); + + describe('when service name is not specified', () => { + it('returns all environments', async () => { + const { body } = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/environments', + params: { + query: { start, end }, + }, + }); + + expect(body.environments.length).to.be.equal(4); + expectSnapshot(body.environments).toMatchInline(` + Array [ + "development", + "production", + "staging", + "custom-go-environment", + ] + `); + }); + }); + + describe('when service name is specified', () => { + it('returns service specific environments for go', async () => { + const { body } = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/environments', + params: { + query: { start, end, serviceName: 'go' }, + }, + }); + + expect(body.environments.length).to.be.equal(4); + expectSnapshot(body.environments).toMatchInline(` + Array [ + "custom-go-environment", + "development", + "production", + "staging", + ] + `); + }); + + it('returns service specific environments for java', async () => { + const { body } = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/environments', + params: { + query: { start, end, serviceName: 'java' }, + }, + }); + + expect(body.environments.length).to.be.equal(3); + expectSnapshot(body.environments).toMatchInline(` + Array [ + "development", + "production", + "staging", + ] + `); + }); + }); + }); +} diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/environment/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/environment/index.ts new file mode 100644 index 0000000000000..4a77e610d5000 --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/environment/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('environment', () => { + loadTestFile(require.resolve('./get_environment.spec.ts')); + }); +} diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts index a62386b536ea8..6c1bd3633c4cc 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts @@ -16,6 +16,7 @@ export default function apmApiIntegrationTests({ loadTestFile(require.resolve('./mobile')); loadTestFile(require.resolve('./custom_dashboards')); loadTestFile(require.resolve('./dependencies')); + loadTestFile(require.resolve('./environment')); loadTestFile(require.resolve('./error_rate')); loadTestFile(require.resolve('./data_view')); loadTestFile(require.resolve('./correlations')); diff --git a/x-pack/test/apm_api_integration/tests/environment/generate_data.ts b/x-pack/test/apm_api_integration/tests/environment/generate_data.ts deleted file mode 100644 index 3cfd5d92e00f1..0000000000000 --- a/x-pack/test/apm_api_integration/tests/environment/generate_data.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 { apm, timerange } from '@kbn/apm-synthtrace-client'; -import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; - -// Generate synthetic data for the environment test suite -export async function generateData({ - apmSynthtraceEsClient, - start, - end, -}: { - apmSynthtraceEsClient: ApmSynthtraceEsClient; - start: number; - end: number; -}) { - const environmentNames = ['production', 'development', 'staging']; - const serviceNames = ['go', 'java', 'node']; - - const services = environmentNames.flatMap((environment) => { - return serviceNames.flatMap((serviceName) => { - return apm - .service({ - name: serviceName, - environment, - agentName: serviceName, - }) - .instance('instance-a'); - }); - }); - - const goServiceWithAdditionalEnvironment = apm - .service({ - name: 'go', - environment: 'custom-go-environment', - agentName: 'go', - }) - .instance('instance-a'); - - // Generate a transaction for each service - const docs = timerange(start, end) - .ratePerMinute(1) - .generator((timestamp) => { - const loopGeneratedDocs = services.flatMap((service) => { - return service - .transaction({ transactionName: 'GET /api/product/:id' }) - .timestamp(timestamp) - .duration(1000); - }); - - const customDoc = goServiceWithAdditionalEnvironment - .transaction({ - transactionName: 'GET /api/go/memory', - transactionType: 'custom-go-type', - }) - .timestamp(timestamp) - .duration(1000); - - return [...loopGeneratedDocs, customDoc]; - }); - - return apmSynthtraceEsClient.index(docs); -} diff --git a/x-pack/test/apm_api_integration/tests/environment/get_environment.spec.ts b/x-pack/test/apm_api_integration/tests/environment/get_environment.spec.ts deleted file mode 100644 index e67c601e7713c..0000000000000 --- a/x-pack/test/apm_api_integration/tests/environment/get_environment.spec.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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 expect from '@kbn/expect'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { generateData } from './generate_data'; - -const startNumber = new Date('2021-01-01T00:00:00.000Z').getTime(); -const endNumber = new Date('2021-01-01T00:05:00.000Z').getTime() - 1; - -const start = new Date(startNumber).toISOString(); -const end = new Date(endNumber).toISOString(); - -export default function environmentsAPITests({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const apmApiClient = getService('apmApiClient'); - const apmSynthtraceEsClient = getService('apmSynthtraceEsClient'); - - registry.when('environments when data is loaded', { config: 'basic', archives: [] }, async () => { - before(async () => - generateData({ - apmSynthtraceEsClient, - start: startNumber, - end: endNumber, - }) - ); - - after(() => apmSynthtraceEsClient.clean()); - - describe('get environments', () => { - describe('when service name is not specified', () => { - it('returns all environments', async () => { - const { body } = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/environments', - params: { - query: { start, end }, - }, - }); - expect(body.environments.length).to.be.equal(4); - expectSnapshot(body.environments).toMatchInline(` - Array [ - "development", - "production", - "staging", - "custom-go-environment", - ] - `); - }); - }); - - describe('when service name is specified', () => { - it('returns service specific environments for go', async () => { - const { body } = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/environments', - params: { - query: { start, end, serviceName: 'go' }, - }, - }); - - expect(body.environments.length).to.be.equal(4); - expectSnapshot(body.environments).toMatchInline(` - Array [ - "custom-go-environment", - "development", - "production", - "staging", - ] - `); - }); - - it('returns service specific environments for java', async () => { - const { body } = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/environments', - params: { - query: { start, end, serviceName: 'java' }, - }, - }); - - expect(body.environments.length).to.be.equal(3); - expectSnapshot(body.environments).toMatchInline(` - Array [ - "development", - "production", - "staging", - ] - `); - }); - }); - }); - }); -}