-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[APM] Foundation for migrating APM tests to deployment agnostic appro…
…ach (#198775) part of #193245 closes #198958 ## Summary This PR lays the foundation to start migrating APM API integration tests to the deployment agnostic approach. ### 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 API tests" ``` 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 API tests" ``` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
- Loading branch information
1 parent
3e0ec51
commit 926861b
Showing
21 changed files
with
246 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
...k/test/api_integration/deployment_agnostic/apis/observability/apm/agent_explorer/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* 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('agent_explorer', () => { | ||
loadTestFile(require.resolve('./agent_explorer.spec.ts')); | ||
loadTestFile(require.resolve('./latest_agent_versions.spec.ts')); | ||
}); | ||
} |
44 changes: 44 additions & 0 deletions
44
...n/deployment_agnostic/apis/observability/apm/agent_explorer/latest_agent_versions.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* 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 { ElasticApmAgentLatestVersion } from '@kbn/apm-plugin/common/agent_explorer'; | ||
import expect from '@kbn/expect'; | ||
import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; | ||
|
||
export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { | ||
const apmApiClient = getService('apmApi'); | ||
const nodeAgentName = 'nodejs'; | ||
const unlistedAgentName = 'unlistedAgent'; | ||
|
||
async function callApi() { | ||
return await apmApiClient.readUser({ | ||
endpoint: 'GET /internal/apm/get_latest_agent_versions', | ||
}); | ||
} | ||
|
||
describe('Agent latest versions when configuration is defined', () => { | ||
it('returns a version when agent is listed in the file', async () => { | ||
const { status, body } = await callApi(); | ||
expect(status).to.be(200); | ||
|
||
const agents = body.data; | ||
|
||
const nodeAgent = agents[nodeAgentName] as ElasticApmAgentLatestVersion; | ||
expect(nodeAgent?.latest_version).not.to.be(undefined); | ||
}); | ||
|
||
it('returns undefined when agent is not listed in the file', async () => { | ||
const { status, body } = await callApi(); | ||
expect(status).to.be(200); | ||
|
||
const agents = body.data; | ||
|
||
// @ts-ignore | ||
const unlistedAgent = agents[unlistedAgentName] as ElasticApmAgentLatestVersion; | ||
expect(unlistedAgent?.latest_version).to.be(undefined); | ||
}); | ||
}); | ||
} |
16 changes: 16 additions & 0 deletions
16
x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* 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 apmApiIntegrationTests({ | ||
loadTestFile, | ||
}: DeploymentAgnosticFtrProviderContext) { | ||
describe('APM', function () { | ||
loadTestFile(require.resolve('./agent_explorer')); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
x-pack/test/api_integration/deployment_agnostic/services/apm_api.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { format } from 'url'; | ||
import request from 'superagent'; | ||
import type { | ||
APIReturnType, | ||
APIClientRequestParamsOf, | ||
} from '@kbn/apm-plugin/public/services/rest/create_call_apm_api'; | ||
import { APIEndpoint } from '@kbn/apm-plugin/server'; | ||
import { formatRequest } from '@kbn/server-route-repository'; | ||
import { RoleCredentials } from '@kbn/ftr-common-functional-services'; | ||
import type { DeploymentAgnosticFtrProviderContext } from '../ftr_provider_context'; | ||
|
||
const INTERNAL_API_REGEX = /^\S+\s(\/)?internal\/[^\s]*$/; | ||
|
||
type InternalApi = `${string} /internal/${string}`; | ||
interface ExternalEndpointParams { | ||
roleAuthc: RoleCredentials; | ||
} | ||
|
||
type Options<TEndpoint extends APIEndpoint> = (TEndpoint extends InternalApi | ||
? {} | ||
: ExternalEndpointParams) & { | ||
type?: 'form-data'; | ||
endpoint: TEndpoint; | ||
spaceId?: string; | ||
} & APIClientRequestParamsOf<TEndpoint> & { | ||
params?: { query?: { _inspect?: boolean } }; | ||
}; | ||
|
||
function isPublicApi<TEndpoint extends APIEndpoint>( | ||
options: Options<TEndpoint> | ||
): options is Options<TEndpoint> & ExternalEndpointParams { | ||
return !INTERNAL_API_REGEX.test(options.endpoint); | ||
} | ||
|
||
function createApmApiClient({ getService }: DeploymentAgnosticFtrProviderContext, role: string) { | ||
const supertestWithoutAuth = getService('supertestWithoutAuth'); | ||
const samlAuth = getService('samlAuth'); | ||
const logger = getService('log'); | ||
|
||
return async <TEndpoint extends APIEndpoint>( | ||
options: Options<TEndpoint> | ||
): Promise<SupertestReturnType<TEndpoint>> => { | ||
const { endpoint, type } = options; | ||
|
||
const params = 'params' in options ? (options.params as Record<string, any>) : {}; | ||
|
||
const credentials = isPublicApi(options) | ||
? options.roleAuthc.apiKeyHeader | ||
: await samlAuth.getM2MApiCookieCredentialsWithRoleScope(role); | ||
|
||
const headers: Record<string, string> = { | ||
...samlAuth.getInternalRequestHeader(), | ||
...credentials, | ||
}; | ||
|
||
const { method, pathname, version } = formatRequest(endpoint, params.path); | ||
const pathnameWithSpaceId = options.spaceId ? `/s/${options.spaceId}${pathname}` : pathname; | ||
const url = format({ pathname: pathnameWithSpaceId, query: params?.query }); | ||
|
||
logger.debug(`Calling APM API: ${method.toUpperCase()} ${url}`); | ||
|
||
if (version) { | ||
headers['Elastic-Api-Version'] = version; | ||
} | ||
|
||
let res: request.Response; | ||
if (type === 'form-data') { | ||
const fields: Array<[string, any]> = Object.entries(params.body); | ||
const formDataRequest = supertestWithoutAuth[method](url) | ||
.set(headers) | ||
.set('Content-type', 'multipart/form-data'); | ||
|
||
for (const field of fields) { | ||
void formDataRequest.field(field[0], field[1]); | ||
} | ||
|
||
res = await formDataRequest; | ||
} else if (params.body) { | ||
res = await supertestWithoutAuth[method](url).send(params.body).set(headers); | ||
} else { | ||
res = await supertestWithoutAuth[method](url).set(headers); | ||
} | ||
|
||
// supertest doesn't throw on http errors | ||
if (res?.status !== 200) { | ||
throw new ApmApiError(res, endpoint); | ||
} | ||
|
||
return res; | ||
}; | ||
} | ||
|
||
type ApiErrorResponse = Omit<request.Response, 'body'> & { | ||
body: { | ||
statusCode: number; | ||
error: string; | ||
message: string; | ||
attributes: object; | ||
}; | ||
}; | ||
|
||
export type ApmApiSupertest = ReturnType<typeof createApmApiClient>; | ||
|
||
export class ApmApiError extends Error { | ||
res: ApiErrorResponse; | ||
|
||
constructor(res: request.Response, endpoint: string) { | ||
super( | ||
`Unhandled ApmApiError. | ||
Status: "${res.status}" | ||
Endpoint: "${endpoint}" | ||
Body: ${JSON.stringify(res.body)}` | ||
); | ||
|
||
this.res = res; | ||
} | ||
} | ||
|
||
export interface SupertestReturnType<TEndpoint extends APIEndpoint> { | ||
status: number; | ||
body: APIReturnType<TEndpoint>; | ||
} | ||
|
||
export function ApmApiProvider(context: DeploymentAgnosticFtrProviderContext) { | ||
return { | ||
readUser: createApmApiClient(context, 'viewer'), | ||
adminUser: createApmApiClient(context, 'admin'), | ||
writeUser: createApmApiClient(context, 'editor'), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.