mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[APM] Use Synthtrace in Cypress tests (#116948)
Co-authored-by: Søren Louv-Jansen <sorenlouv@gmail.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
0593c614a9
commit
6d5ba9be5e
25 changed files with 363 additions and 83 deletions
|
@ -7,10 +7,12 @@
|
|||
*/
|
||||
|
||||
export { service } from './lib/service';
|
||||
export { browser } from './lib/browser';
|
||||
export { timerange } from './lib/timerange';
|
||||
export { getTransactionMetrics } from './lib/utils/get_transaction_metrics';
|
||||
export { getSpanDestinationMetrics } from './lib/utils/get_span_destination_metrics';
|
||||
export { getObserverDefaults } from './lib/defaults/get_observer_defaults';
|
||||
export { getChromeUserAgentDefaults } from './lib/defaults/get_chrome_user_agent_defaults';
|
||||
export { toElasticsearchOutput } from './lib/output/to_elasticsearch_output';
|
||||
export { getBreakdownMetrics } from './lib/utils/get_breakdown_metrics';
|
||||
export { cleanWriteTargets } from './lib/utils/clean_write_targets';
|
||||
|
|
39
packages/elastic-apm-synthtrace/src/lib/browser.ts
Normal file
39
packages/elastic-apm-synthtrace/src/lib/browser.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { Entity, UserAgentFields } from './entity';
|
||||
import { RumSpan } from './rum_span';
|
||||
import { RumTransaction } from './rum_transaction';
|
||||
|
||||
export class Browser extends Entity {
|
||||
transaction(transactionName: string, transactionType: string = 'page-load') {
|
||||
return new RumTransaction({
|
||||
...this.fields,
|
||||
'transaction.name': transactionName,
|
||||
'transaction.type': transactionType,
|
||||
});
|
||||
}
|
||||
|
||||
span(spanName: string, spanType: string, spanSubtype: string) {
|
||||
return new RumSpan({
|
||||
...this.fields,
|
||||
'span.name': spanName,
|
||||
'span.type': spanType,
|
||||
'span.subtype': spanSubtype,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function browser(serviceName: string, production: string, userAgent: UserAgentFields) {
|
||||
return new Browser({
|
||||
'agent.name': 'rum-js',
|
||||
'service.name': serviceName,
|
||||
'service.environment': production,
|
||||
...userAgent,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { UserAgentFields } from '../entity';
|
||||
|
||||
export function getChromeUserAgentDefaults(): UserAgentFields {
|
||||
return {
|
||||
'user_agent.original':
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36',
|
||||
'user_agent.device.name': 'MacBook',
|
||||
'user_agent.name': 'Chrome',
|
||||
'user_agent.version': 95,
|
||||
'user_agent.os.name': 'MacOS',
|
||||
};
|
||||
}
|
|
@ -15,6 +15,14 @@ export type ApplicationMetricFields = Partial<{
|
|||
'system.process.cpu.total.norm.pct': number;
|
||||
}>;
|
||||
|
||||
export type UserAgentFields = Partial<{
|
||||
'user_agent.original': string;
|
||||
'user_agent.os.name': string;
|
||||
'user_agent.name': string;
|
||||
'user_agent.device.name': string;
|
||||
'user_agent.version': number;
|
||||
}>;
|
||||
|
||||
export interface Exception {
|
||||
message: string;
|
||||
}
|
||||
|
@ -32,6 +40,7 @@ export type Fields = Partial<{
|
|||
'error.grouping_name': string;
|
||||
'error.grouping_key': string;
|
||||
'host.name': string;
|
||||
'kubernetes.pod.uid': string;
|
||||
'metricset.name': string;
|
||||
'observer.version': string;
|
||||
'observer.version_major': number;
|
||||
|
|
|
@ -38,6 +38,11 @@ export class Instance extends Entity {
|
|||
});
|
||||
}
|
||||
|
||||
podId(podId: string) {
|
||||
this.fields['kubernetes.pod.uid'] = podId;
|
||||
return this;
|
||||
}
|
||||
|
||||
appMetrics(metrics: ApplicationMetricFields) {
|
||||
return new Metricset({
|
||||
...this.fields,
|
||||
|
|
11
packages/elastic-apm-synthtrace/src/lib/rum_span.ts
Normal file
11
packages/elastic-apm-synthtrace/src/lib/rum_span.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { Span } from './span';
|
||||
|
||||
export class RumSpan extends Span {}
|
11
packages/elastic-apm-synthtrace/src/lib/rum_transaction.ts
Normal file
11
packages/elastic-apm-synthtrace/src/lib/rum_transaction.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { Transaction } from './transaction';
|
||||
|
||||
export class RumTransaction extends Transaction {}
|
|
@ -6,7 +6,9 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { isPromise } from 'util/types';
|
||||
function isPromise(val: any): val is Promise<any> {
|
||||
return val && typeof val === 'object' && 'then' in val && typeof val.then === 'function';
|
||||
}
|
||||
|
||||
export enum LogLevel {
|
||||
trace = 0,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"fileServerFolder": "./cypress",
|
||||
"fixturesFolder": "./cypress/fixtures",
|
||||
"integrationFolder": "./cypress/integration",
|
||||
"pluginsFile": "./cypress/plugins/index.js",
|
||||
"pluginsFile": "./cypress/plugins/index.ts",
|
||||
"screenshotsFolder": "./cypress/screenshots",
|
||||
"supportFile": "./cypress/support/index.ts",
|
||||
"videosFolder": "./cypress/videos",
|
||||
|
@ -13,4 +13,4 @@
|
|||
"viewportWidth": 1440,
|
||||
"video": false,
|
||||
"screenshotOnRunFailure": false
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -4,19 +4,30 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { service, timerange } from '@elastic/apm-synthtrace';
|
||||
import {
|
||||
service,
|
||||
browser,
|
||||
timerange,
|
||||
getChromeUserAgentDefaults,
|
||||
} from '@elastic/apm-synthtrace';
|
||||
|
||||
export function opbeans({ from, to }: { from: number; to: number }) {
|
||||
const range = timerange(from, to);
|
||||
|
||||
const opbeansJava = service('opbeans-java', 'production', 'java').instance(
|
||||
'opbeans-java-prod-1'
|
||||
);
|
||||
const opbeansJava = service('opbeans-java', 'production', 'java')
|
||||
.instance('opbeans-java-prod-1')
|
||||
.podId('opbeans-java-prod-1-pod');
|
||||
|
||||
const opbeansNode = service('opbeans-node', 'production', 'nodejs').instance(
|
||||
'opbeans-node-prod-1'
|
||||
);
|
||||
|
||||
const opbeansRum = browser(
|
||||
'opbeans-rum',
|
||||
'production',
|
||||
getChromeUserAgentDefaults()
|
||||
);
|
||||
|
||||
return [
|
||||
...range
|
||||
.interval('1s')
|
||||
|
@ -27,6 +38,15 @@ export function opbeans({ from, to }: { from: number; to: number }) {
|
|||
.timestamp(timestamp)
|
||||
.duration(1000)
|
||||
.success()
|
||||
.errors(opbeansJava.error('[MockError] Foo').timestamp(timestamp))
|
||||
.children(
|
||||
opbeansJava
|
||||
.span('SELECT * FROM product', 'db', 'postgresql')
|
||||
.timestamp(timestamp)
|
||||
.duration(50)
|
||||
.success()
|
||||
.destination('postgresql')
|
||||
)
|
||||
.serialize(),
|
||||
...opbeansNode
|
||||
.transaction('GET /api/product/:id')
|
||||
|
@ -34,6 +54,17 @@ export function opbeans({ from, to }: { from: number; to: number }) {
|
|||
.duration(500)
|
||||
.success()
|
||||
.serialize(),
|
||||
...opbeansNode
|
||||
.transaction('Worker job', 'Worker')
|
||||
.timestamp(timestamp)
|
||||
.duration(1000)
|
||||
.success()
|
||||
.serialize(),
|
||||
...opbeansRum
|
||||
.transaction('/')
|
||||
.timestamp(timestamp)
|
||||
.duration(1000)
|
||||
.serialize(),
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,13 +4,31 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { synthtrace } from '../../../synthtrace';
|
||||
import { opbeans } from '../../fixtures/synthtrace/opbeans';
|
||||
|
||||
const start = '2021-10-10T00:00:00.000Z';
|
||||
const end = '2021-10-10T00:15:00.000Z';
|
||||
|
||||
const timeRange = {
|
||||
rangeFrom: Cypress.env('START_DATE'),
|
||||
rangeTo: Cypress.env('END_DATE'),
|
||||
rangeFrom: start,
|
||||
rangeTo: end,
|
||||
};
|
||||
|
||||
describe('Dependencies', () => {
|
||||
before(async () => {
|
||||
await synthtrace.index(
|
||||
opbeans({
|
||||
from: new Date(start).getTime(),
|
||||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await synthtrace.clean();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.loginAsReadOnlyUser();
|
||||
});
|
||||
|
@ -40,21 +58,21 @@ describe('Dependencies', () => {
|
|||
cy.get('[data-test-subj="throughputChart"]');
|
||||
cy.get('[data-test-subj="errorRateChart"]');
|
||||
|
||||
cy.contains('opbeans-python').click({ force: true });
|
||||
cy.contains('opbeans-java').click({ force: true });
|
||||
|
||||
cy.contains('h1', 'opbeans-python');
|
||||
cy.contains('h1', 'opbeans-java');
|
||||
});
|
||||
});
|
||||
|
||||
describe('service overview page', () => {
|
||||
it('shows dependency information and you can navigate to a page for a dependency', () => {
|
||||
cy.visit(
|
||||
`/app/apm/services/opbeans-python/overview?${new URLSearchParams(
|
||||
`/app/apm/services/opbeans-java/overview?${new URLSearchParams(
|
||||
timeRange
|
||||
)}`
|
||||
);
|
||||
|
||||
cy.contains('postgresql').click({ force: true });
|
||||
cy.contains('a', 'postgresql').click({ force: true });
|
||||
|
||||
cy.contains('h1', 'postgresql');
|
||||
});
|
||||
|
@ -63,7 +81,7 @@ describe('Dependencies', () => {
|
|||
describe('service dependencies tab', () => {
|
||||
it('shows dependency information and you can navigate to a page for a dependency', () => {
|
||||
cy.visit(
|
||||
`/app/apm/services/opbeans-python/overview?${new URLSearchParams(
|
||||
`/app/apm/services/opbeans-java/overview?${new URLSearchParams(
|
||||
timeRange
|
||||
)}`
|
||||
);
|
||||
|
@ -72,7 +90,7 @@ describe('Dependencies', () => {
|
|||
|
||||
cy.contains('Time spent by dependency');
|
||||
|
||||
cy.contains('postgresql').click({ force: true });
|
||||
cy.contains('a', 'postgresql').click({ force: true });
|
||||
|
||||
cy.contains('h1', 'postgresql');
|
||||
});
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
*/
|
||||
|
||||
import url from 'url';
|
||||
import archives_metadata from '../../fixtures/es_archiver/archives_metadata';
|
||||
import { synthtrace } from '../../../synthtrace';
|
||||
import { opbeans } from '../../fixtures/synthtrace/opbeans';
|
||||
|
||||
const { start, end } = archives_metadata['apm_8.0.0'];
|
||||
const start = '2021-10-10T00:00:00.000Z';
|
||||
const end = '2021-10-10T00:15:00.000Z';
|
||||
|
||||
const serviceInventoryHref = url.format({
|
||||
pathname: '/app/apm/services',
|
||||
|
@ -27,6 +29,19 @@ const apisToIntercept = [
|
|||
];
|
||||
|
||||
describe('Home page', () => {
|
||||
before(async () => {
|
||||
await synthtrace.index(
|
||||
opbeans({
|
||||
from: new Date(start).getTime(),
|
||||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await synthtrace.clean();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.loginAsReadOnlyUser();
|
||||
});
|
||||
|
@ -44,7 +59,6 @@ describe('Home page', () => {
|
|||
cy.visit(
|
||||
`${serviceInventoryHref}&kuery=not%20(processor.event%3A%22transaction%22)`
|
||||
);
|
||||
cy.contains('opbeans-python');
|
||||
cy.contains('opbeans-java');
|
||||
cy.contains('opbeans-node');
|
||||
});
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import url from 'url';
|
||||
import archives_metadata from '../../../fixtures/es_archiver/archives_metadata';
|
||||
import { synthtrace } from '../../../../synthtrace';
|
||||
import { opbeans } from '../../../fixtures/synthtrace/opbeans';
|
||||
|
||||
const { start, end } = archives_metadata['apm_8.0.0'];
|
||||
const start = '2021-10-10T00:00:00.000Z';
|
||||
const end = '2021-10-10T00:15:00.000Z';
|
||||
|
||||
const serviceOverviewHref = url.format({
|
||||
pathname: '/app/apm/services/opbeans-node/overview',
|
||||
|
@ -62,6 +64,16 @@ const apisToIntercept = [
|
|||
];
|
||||
|
||||
describe('Service overview - header filters', () => {
|
||||
before(async () => {
|
||||
await synthtrace.index(
|
||||
opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime() })
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await synthtrace.clean();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.loginAsReadOnlyUser();
|
||||
});
|
||||
|
|
|
@ -6,15 +6,19 @@
|
|||
*/
|
||||
|
||||
import url from 'url';
|
||||
import archives_metadata from '../../../fixtures/es_archiver/archives_metadata';
|
||||
import { synthtrace } from '../../../../synthtrace';
|
||||
import { opbeans } from '../../../fixtures/synthtrace/opbeans';
|
||||
|
||||
const { start, end } = archives_metadata['apm_8.0.0'];
|
||||
const start = '2021-10-10T00:00:00.000Z';
|
||||
const end = '2021-10-10T00:15:00.000Z';
|
||||
|
||||
const serviceOverviewHref = url.format({
|
||||
pathname: '/app/apm/services/opbeans-java/overview',
|
||||
query: { rangeFrom: start, rangeTo: end },
|
||||
});
|
||||
|
||||
const serviceNodeName = 'opbeans-java-prod-1';
|
||||
|
||||
const apisToIntercept = [
|
||||
{
|
||||
endpoint:
|
||||
|
@ -27,8 +31,7 @@ const apisToIntercept = [
|
|||
name: 'instancesDetailsRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-java/service_overview_instances/details/31651f3c624b81c55dd4633df0b5b9f9ab06b151121b0404ae796632cd1f87ad?*',
|
||||
endpoint: `/internal/apm/services/opbeans-java/service_overview_instances/details/${serviceNodeName}?*`,
|
||||
name: 'instanceDetailsRequest',
|
||||
},
|
||||
];
|
||||
|
@ -49,8 +52,18 @@ describe('Instances table', () => {
|
|||
// });
|
||||
|
||||
describe('when data is loaded', () => {
|
||||
const serviceNodeName =
|
||||
'31651f3c624b81c55dd4633df0b5b9f9ab06b151121b0404ae796632cd1f87ad';
|
||||
before(async () => {
|
||||
await synthtrace.index(
|
||||
opbeans({
|
||||
from: new Date(start).getTime(),
|
||||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await synthtrace.clean();
|
||||
});
|
||||
|
||||
it('has data in the table', () => {
|
||||
cy.visit(serviceOverviewHref);
|
||||
|
@ -91,7 +104,7 @@ describe('Instances table', () => {
|
|||
cy.wait('@instancesDetailsRequest');
|
||||
cy.get(
|
||||
`[data-test-subj="instanceActionsButton_${serviceNodeName}"]`
|
||||
).realClick();
|
||||
).click();
|
||||
cy.contains('Pod logs');
|
||||
cy.contains('Pod metrics');
|
||||
cy.contains('Container logs');
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
*/
|
||||
|
||||
import url from 'url';
|
||||
import archives_metadata from '../../../fixtures/es_archiver/archives_metadata';
|
||||
import { synthtrace } from '../../../../synthtrace';
|
||||
import { opbeans } from '../../../fixtures/synthtrace/opbeans';
|
||||
|
||||
const { start, end } = archives_metadata['apm_8.0.0'];
|
||||
const start = '2021-10-10T00:00:00.000Z';
|
||||
const end = '2021-10-10T00:15:00.000Z';
|
||||
|
||||
const serviceOverviewPath = '/app/apm/services/opbeans-node/overview';
|
||||
const baseUrl = url.format({
|
||||
|
@ -17,6 +19,19 @@ const baseUrl = url.format({
|
|||
});
|
||||
|
||||
describe('Service Overview', () => {
|
||||
before(async () => {
|
||||
await synthtrace.index(
|
||||
opbeans({
|
||||
from: new Date(start).getTime(),
|
||||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await synthtrace.clean();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.loginAsReadOnlyUser();
|
||||
});
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
*/
|
||||
import url from 'url';
|
||||
import moment from 'moment';
|
||||
import archives_metadata from '../../../fixtures/es_archiver/archives_metadata';
|
||||
import { synthtrace } from '../../../../synthtrace';
|
||||
import { opbeans } from '../../../fixtures/synthtrace/opbeans';
|
||||
|
||||
const { start, end } = archives_metadata['apm_8.0.0'];
|
||||
const start = '2021-10-10T00:00:00.000Z';
|
||||
const end = '2021-10-10T00:15:00.000Z';
|
||||
|
||||
const serviceOverviewPath = '/app/apm/services/opbeans-java/overview';
|
||||
const serviceOverviewHref = url.format({
|
||||
|
@ -49,6 +51,19 @@ const apisToIntercept = [
|
|||
];
|
||||
|
||||
describe('Service overview: Time Comparison', () => {
|
||||
before(async () => {
|
||||
await synthtrace.index(
|
||||
opbeans({
|
||||
from: new Date(start).getTime(),
|
||||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await synthtrace.clean();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.loginAsReadOnlyUser();
|
||||
});
|
||||
|
@ -79,8 +94,12 @@ describe('Service overview: Time Comparison', () => {
|
|||
cy.contains('opbeans-java');
|
||||
|
||||
cy.get('[data-test-subj="comparisonSelect"]').should('be.enabled');
|
||||
const comparisonStartEnd =
|
||||
'comparisonStart=2021-08-02T06%3A50%3A00.000Z&comparisonEnd=2021-08-02T07%3A20%3A15.910Z';
|
||||
const comparisonStartEnd = `comparisonStart=${encodeURIComponent(
|
||||
moment(start).subtract(1, 'day').toISOString()
|
||||
)}&comparisonEnd=${encodeURIComponent(
|
||||
moment(end).subtract(1, 'day').toISOString()
|
||||
)}`;
|
||||
|
||||
// When the page loads it fetches all APIs with comparison time range
|
||||
cy.wait(apisToIntercept.map(({ name }) => `@${name}`)).then(
|
||||
(interceptions) => {
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
*/
|
||||
|
||||
import url from 'url';
|
||||
import archives_metadata from '../../../fixtures/es_archiver/archives_metadata';
|
||||
import { synthtrace } from '../../../../synthtrace';
|
||||
import { opbeans } from '../../../fixtures/synthtrace/opbeans';
|
||||
|
||||
const { start, end } = archives_metadata['apm_8.0.0'];
|
||||
const start = '2021-10-10T00:00:00.000Z';
|
||||
const end = '2021-10-10T00:15:00.000Z';
|
||||
|
||||
const serviceOverviewHref = url.format({
|
||||
pathname: '/app/apm/services/opbeans-node/transactions',
|
||||
|
@ -16,6 +18,19 @@ const serviceOverviewHref = url.format({
|
|||
});
|
||||
|
||||
describe('Transactions Overview', () => {
|
||||
before(async () => {
|
||||
await synthtrace.index(
|
||||
opbeans({
|
||||
from: new Date(start).getTime(),
|
||||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await synthtrace.clean();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.loginAsReadOnlyUser();
|
||||
});
|
||||
|
|
|
@ -1,28 +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.
|
||||
*/
|
||||
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = () => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
};
|
61
x-pack/plugins/apm/ftr_e2e/cypress/plugins/index.ts
Normal file
61
x-pack/plugins/apm/ftr_e2e/cypress/plugins/index.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 Fs from 'fs';
|
||||
import { Client, HttpConnection } from '@elastic/elasticsearch';
|
||||
import { SynthtraceEsClient } from '@elastic/apm-synthtrace';
|
||||
import { createLogger, LogLevel } from '@elastic/apm-synthtrace';
|
||||
import { CA_CERT_PATH } from '@kbn/dev-utils';
|
||||
|
||||
// ***********************************************************
|
||||
// This example plugins/index.ts can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
const plugin: Cypress.PluginConfig = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
|
||||
const node = config.env.ES_NODE;
|
||||
const requestTimeout = config.env.ES_REQUEST_TIMEOUT;
|
||||
const isCloud = config.env.TEST_CLOUD;
|
||||
|
||||
const client = new Client({
|
||||
node,
|
||||
requestTimeout,
|
||||
Connection: HttpConnection,
|
||||
...(isCloud ? { tls: { ca: Fs.readFileSync(CA_CERT_PATH, 'utf-8') } } : {}),
|
||||
});
|
||||
|
||||
const synthtraceEsClient = new SynthtraceEsClient(
|
||||
client,
|
||||
createLogger(LogLevel.info)
|
||||
);
|
||||
|
||||
on('task', {
|
||||
'synthtrace:index': async (events) => {
|
||||
await synthtraceEsClient.index(events);
|
||||
return null;
|
||||
},
|
||||
'synthtrace:clean': async () => {
|
||||
await synthtraceEsClient.clean();
|
||||
return null;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = plugin;
|
|
@ -10,7 +10,6 @@
|
|||
import Url from 'url';
|
||||
import cypress from 'cypress';
|
||||
import { FtrProviderContext } from './ftr_provider_context';
|
||||
import archives_metadata from './cypress/fixtures/es_archiver/archives_metadata';
|
||||
import { createApmUsersAndRoles } from '../scripts/create-apm-users-and-roles/create_apm_users_and_roles';
|
||||
import { esArchiverLoad, esArchiverUnload } from './cypress/tasks/es_archiver';
|
||||
|
||||
|
@ -35,8 +34,7 @@ async function cypressStart(
|
|||
) {
|
||||
const config = getService('config');
|
||||
|
||||
const archiveName = 'apm_8.0.0';
|
||||
const { start, end } = archives_metadata[archiveName];
|
||||
const archiveName = 'apm_mappings_only_8.0.0';
|
||||
|
||||
const kibanaUrl = Url.format({
|
||||
protocol: config.get('servers.kibana.protocol'),
|
||||
|
@ -56,21 +54,33 @@ async function cypressStart(
|
|||
},
|
||||
});
|
||||
|
||||
console.log('Loading esArchiver...');
|
||||
await esArchiverLoad('apm_8.0.0');
|
||||
const esNode = Url.format({
|
||||
protocol: config.get('servers.elasticsearch.protocol'),
|
||||
port: config.get('servers.elasticsearch.port'),
|
||||
hostname: config.get('servers.elasticsearch.hostname'),
|
||||
auth: `${config.get('servers.elasticsearch.username')}:${config.get(
|
||||
'servers.elasticsearch.password'
|
||||
)}`,
|
||||
});
|
||||
|
||||
const esRequestTimeout = config.get('timeouts.esRequestTimeout');
|
||||
|
||||
console.log(`Loading ES archive "${archiveName}"`);
|
||||
await esArchiverLoad(archiveName);
|
||||
|
||||
const res = await cypressExecution({
|
||||
...(spec !== undefined ? { spec } : {}),
|
||||
config: { baseUrl: kibanaUrl },
|
||||
env: {
|
||||
START_DATE: start,
|
||||
END_DATE: end,
|
||||
KIBANA_URL: kibanaUrl,
|
||||
ES_NODE: esNode,
|
||||
ES_REQUEST_TIMEOUT: esRequestTimeout,
|
||||
TEST_CLOUD: process.env.TEST_CLOUD,
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Removing esArchiver...');
|
||||
await esArchiverUnload('apm_8.0.0');
|
||||
console.log('Unloading ES archives...');
|
||||
await esArchiverUnload(archiveName);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
/* eslint-disable-next-line*/
|
||||
export default {
|
||||
'apm_8.0.0': {
|
||||
start: '2021-08-03T06:50:15.910Z',
|
||||
end: '2021-08-03T07:20:15.910Z',
|
||||
},
|
||||
export const synthtrace = {
|
||||
index: (events: any[]) =>
|
||||
new Promise((resolve) => {
|
||||
cy.task('synthtrace:index', events).then(resolve);
|
||||
}),
|
||||
clean: () =>
|
||||
new Promise((resolve) => {
|
||||
cy.task('synthtrace:clean').then(resolve);
|
||||
}),
|
||||
};
|
|
@ -16,7 +16,5 @@ export function cancelEsRequestOnAbort<T extends Promise<any>>(
|
|||
controller.abort();
|
||||
});
|
||||
|
||||
promise.finally(() => subscription.unsubscribe());
|
||||
|
||||
return promise;
|
||||
return promise.finally(() => subscription.unsubscribe());
|
||||
}
|
||||
|
|
|
@ -55,12 +55,12 @@ export function getStoredAnnotations({
|
|||
|
||||
try {
|
||||
const response: ESSearchResponse<ESAnnotation, { body: typeof body }> =
|
||||
await (unwrapEsResponse(
|
||||
(await unwrapEsResponse(
|
||||
client.search({
|
||||
index: annotationsClient.index,
|
||||
body,
|
||||
})
|
||||
) as any);
|
||||
)) as any;
|
||||
|
||||
return response.hits.hits.map((hit) => {
|
||||
return {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue