mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [[APM][Otel] Add service view e2e tests using otel service (#196542)](https://github.com/elastic/kibana/pull/196542) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"jennypavlova","email":"dzheni.pavlova@elastic.co"},"sourceCommit":{"committedDate":"2024-10-17T11:14:54Z","message":"[APM][Otel] Add service view e2e tests using otel service (#196542)\n\nCloses #193206\r\n\r\n## Summary\r\n\r\nThis PR adds service view e2e tests using otel service. \r\n\r\nTo run the tests:\r\n- Start server\r\n`node x-pack/plugins/observability_solution/apm/scripts/test/e2e\r\n--server`\r\n- Open Cypress \r\n`node x-pack/plugins/observability_solution/apm/scripts/test/e2e\r\n--runner --open`\r\n- Select `otel_service_overview_and_transactions`","sha":"98ebd0921d4ec2a4f1ee5c076ce9888c75addd5d","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:skip","v9.0.0","ci:project-deploy-observability","Team:obs-ux-infra_services"],"title":"[APM][Otel] Add service view e2e tests using otel service","number":196542,"url":"https://github.com/elastic/kibana/pull/196542","mergeCommit":{"message":"[APM][Otel] Add service view e2e tests using otel service (#196542)\n\nCloses #193206\r\n\r\n## Summary\r\n\r\nThis PR adds service view e2e tests using otel service. \r\n\r\nTo run the tests:\r\n- Start server\r\n`node x-pack/plugins/observability_solution/apm/scripts/test/e2e\r\n--server`\r\n- Open Cypress \r\n`node x-pack/plugins/observability_solution/apm/scripts/test/e2e\r\n--runner --open`\r\n- Select `otel_service_overview_and_transactions`","sha":"98ebd0921d4ec2a4f1ee5c076ce9888c75addd5d"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/196542","number":196542,"mergeCommit":{"message":"[APM][Otel] Add service view e2e tests using otel service (#196542)\n\nCloses #193206\r\n\r\n## Summary\r\n\r\nThis PR adds service view e2e tests using otel service. \r\n\r\nTo run the tests:\r\n- Start server\r\n`node x-pack/plugins/observability_solution/apm/scripts/test/e2e\r\n--server`\r\n- Open Cypress \r\n`node x-pack/plugins/observability_solution/apm/scripts/test/e2e\r\n--runner --open`\r\n- Select `otel_service_overview_and_transactions`","sha":"98ebd0921d4ec2a4f1ee5c076ce9888c75addd5d"}}]}] BACKPORT--> Co-authored-by: jennypavlova <dzheni.pavlova@elastic.co>
This commit is contained in:
parent
52d5725aa2
commit
41a2c68d38
6 changed files with 207 additions and 1 deletions
|
@ -21,6 +21,7 @@ export interface OtelErrorDocument extends OtelDocument {
|
|||
'timestamp.us'?: number;
|
||||
'event.name'?: string;
|
||||
'error.id'?: string;
|
||||
'error.grouping_key'?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ class Otel extends Serializable<OtelDocument> {
|
|||
'timestamp.us': 1726580752010657,
|
||||
'event.name': 'exception',
|
||||
'error.id': `error-${spanId}`,
|
||||
'error.grouping_key': `errorGroup-${spanId}`,
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'generic.otel',
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* 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 url from 'url';
|
||||
import { synthtraceOtel } from '../../../synthtrace';
|
||||
import { sendotlp } from '../../fixtures/synthtrace/sendotlp';
|
||||
import { checkA11y } from '../../support/commands';
|
||||
|
||||
const start = '2021-10-10T00:00:00.000Z';
|
||||
const end = '2021-10-10T00:15:00.000Z';
|
||||
const serviceInstanceId = '89117ac1-0dbf-4488-9e17-4c2c3b76943a';
|
||||
|
||||
const serviceOverviewPath = '/app/apm/services/sendotlp-synth/overview';
|
||||
const baseUrl = url.format({
|
||||
pathname: serviceOverviewPath,
|
||||
query: { rangeFrom: start, rangeTo: end },
|
||||
});
|
||||
|
||||
describe('Service Overview', () => {
|
||||
before(() => {
|
||||
synthtraceOtel.index(
|
||||
sendotlp({
|
||||
from: new Date(start).getTime(),
|
||||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
synthtraceOtel.clean();
|
||||
});
|
||||
|
||||
describe('renders', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
cy.visitKibana(baseUrl);
|
||||
});
|
||||
|
||||
it('renders all components on the page', () => {
|
||||
cy.contains('sendotlp-synth');
|
||||
// set skipFailures to true to not fail the test when there are accessibility failures
|
||||
checkA11y({ skipFailures: true });
|
||||
cy.getByTestSubj('latencyChart');
|
||||
cy.getByTestSubj('throughput');
|
||||
cy.getByTestSubj('transactionsGroupTable');
|
||||
cy.getByTestSubj('serviceOverviewErrorsTable');
|
||||
cy.getByTestSubj('dependenciesTable');
|
||||
cy.getByTestSubj('instancesLatencyDistribution');
|
||||
cy.getByTestSubj('serviceOverviewInstancesTable');
|
||||
});
|
||||
});
|
||||
|
||||
describe('service icons', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
});
|
||||
|
||||
it('show information on click', () => {
|
||||
cy.intercept('GET', '/internal/apm/services/sendotlp-synth/metadata/details?*').as(
|
||||
'metadataDetailsRequest'
|
||||
);
|
||||
|
||||
cy.visitKibana(baseUrl);
|
||||
|
||||
cy.getByTestSubj('service').click();
|
||||
cy.wait('@metadataDetailsRequest');
|
||||
cy.contains('dt', 'Framework name');
|
||||
cy.contains('dd', 'sendotlp-synth');
|
||||
|
||||
cy.getByTestSubj('opentelemetry').click();
|
||||
cy.contains('dt', 'Language');
|
||||
cy.contains('dd', 'go');
|
||||
});
|
||||
});
|
||||
|
||||
describe('instances table', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
});
|
||||
|
||||
it('has data in the table', () => {
|
||||
cy.visitKibana(baseUrl);
|
||||
cy.contains('sendotlp-synth');
|
||||
cy.getByTestSubj('serviceInstancesTableContainer');
|
||||
cy.contains(serviceInstanceId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('transactions', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
});
|
||||
|
||||
it('persists transaction type selected when clicking on Transactions tab', () => {
|
||||
cy.intercept('GET', '/internal/apm/services/sendotlp-synth/transaction_types?*').as(
|
||||
'transactionTypesRequest'
|
||||
);
|
||||
|
||||
cy.visitKibana(baseUrl);
|
||||
|
||||
cy.wait('@transactionTypesRequest');
|
||||
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'unknown');
|
||||
cy.contains('Transactions').click();
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'unknown');
|
||||
cy.contains('parent-synth');
|
||||
});
|
||||
|
||||
it('navigates to transaction detail page', () => {
|
||||
cy.visitKibana(baseUrl);
|
||||
cy.contains('Transactions').click();
|
||||
|
||||
cy.contains('a', 'parent-synth').click();
|
||||
cy.contains('h5', 'parent-synth');
|
||||
});
|
||||
});
|
||||
|
||||
describe('errors', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
cy.visitKibana(baseUrl);
|
||||
});
|
||||
it('errors table is populated', () => {
|
||||
cy.contains('sendotlp-synth');
|
||||
cy.contains('*errors.errorString');
|
||||
});
|
||||
|
||||
it('navigates to the errors page', () => {
|
||||
cy.contains('sendotlp-synth');
|
||||
cy.contains('a', 'View errors').click();
|
||||
cy.url().should('include', '/sendotlp-synth/errors');
|
||||
});
|
||||
|
||||
it('navigates to error detail page', () => {
|
||||
cy.contains('a', '*errors.errorString').click();
|
||||
cy.contains('div', 'boom');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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 { generateShortId, otel, timerange } from '@kbn/apm-synthtrace-client';
|
||||
import { times } from 'lodash';
|
||||
|
||||
export function sendotlp({ from, to }: { from: number; to: number }) {
|
||||
const range = timerange(from, to);
|
||||
const traceId = generateShortId();
|
||||
const spanId = generateShortId();
|
||||
|
||||
const otelSendotlp = times(2).map((index) => otel.create(traceId));
|
||||
|
||||
return range
|
||||
.interval('1s')
|
||||
.rate(1)
|
||||
.generator((timestamp) =>
|
||||
otelSendotlp.flatMap((otelDoc) => {
|
||||
return [
|
||||
otelDoc.metric().timestamp(timestamp),
|
||||
otelDoc.transaction(spanId).timestamp(timestamp),
|
||||
otelDoc.error(spanId).timestamp(timestamp),
|
||||
];
|
||||
})
|
||||
);
|
||||
}
|
|
@ -4,7 +4,12 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { ApmSynthtraceEsClient, createLogger, LogLevel } from '@kbn/apm-synthtrace';
|
||||
import {
|
||||
ApmSynthtraceEsClient,
|
||||
OtelSynthtraceEsClient,
|
||||
createLogger,
|
||||
LogLevel,
|
||||
} from '@kbn/apm-synthtrace';
|
||||
import { createEsClientForTesting } from '@kbn/test';
|
||||
// eslint-disable-next-line @kbn/imports/no_unresolvable_imports
|
||||
import { initPlugin } from '@frsource/cypress-plugin-visual-regression-diff/plugins';
|
||||
|
@ -26,10 +31,20 @@ export function setupNodeEvents(on: Cypress.PluginEvents, config: Cypress.Plugin
|
|||
version: config.env.APM_PACKAGE_VERSION,
|
||||
});
|
||||
|
||||
const synthtraceOtelEsClient = new OtelSynthtraceEsClient({
|
||||
client,
|
||||
logger,
|
||||
refreshAfterIndex: true,
|
||||
});
|
||||
|
||||
synthtraceEsClient.pipeline(
|
||||
synthtraceEsClient.getDefaultPipeline({ includeSerialization: false })
|
||||
);
|
||||
|
||||
synthtraceOtelEsClient.pipeline(
|
||||
synthtraceOtelEsClient.getDefaultPipeline({ includeSerialization: false })
|
||||
);
|
||||
|
||||
initPlugin(on, config);
|
||||
|
||||
on('task', {
|
||||
|
@ -48,6 +63,14 @@ export function setupNodeEvents(on: Cypress.PluginEvents, config: Cypress.Plugin
|
|||
await synthtraceEsClient.clean();
|
||||
return null;
|
||||
},
|
||||
async 'synthtraceOtel:index'(events: Array<Record<string, any>>) {
|
||||
await synthtraceOtelEsClient.index(Readable.from(events));
|
||||
return null;
|
||||
},
|
||||
async 'synthtraceOtel:clean'() {
|
||||
await synthtraceOtelEsClient.clean();
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
on('before:browser:launch', (browser, launchOptions) => {
|
||||
|
|
|
@ -14,3 +14,12 @@ export const synthtrace = {
|
|||
),
|
||||
clean: () => cy.task('synthtrace:clean'),
|
||||
};
|
||||
|
||||
export const synthtraceOtel = {
|
||||
index: (events: SynthtraceGenerator<ApmFields> | Array<Serializable<ApmFields>>) =>
|
||||
cy.task(
|
||||
'synthtraceOtel:index',
|
||||
Array.from(events).flatMap((event) => event.serialize())
|
||||
),
|
||||
clean: () => cy.task('synthtraceOtel:clean'),
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue