[8.6] Unskip Execution Context FTRs (#149070) (#149373)

# Backport

This will backport the following commits from `main` to `8.6`:
- [Unskip Execution Context FTRs
(#149070)](https://github.com/elastic/kibana/pull/149070)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Alejandro Fernández
Haro","email":"alejandro.haro@elastic.co"},"sourceCommit":{"committedDate":"2023-01-24T01:33:53Z","message":"Unskip
Execution Context FTRs (#149070)\n\nResolves
https://github.com/elastic/kibana/issues/112102","sha":"4c626f16c0bfc333bf0591f586b082f6c09dd3b1","branchLabelMapping":{"^v8.7.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Core","release_note:skip","backport:all-open","v8.7.0"],"number":149070,"url":"https://github.com/elastic/kibana/pull/149070","mergeCommit":{"message":"Unskip
Execution Context FTRs (#149070)\n\nResolves
https://github.com/elastic/kibana/issues/112102","sha":"4c626f16c0bfc333bf0591f586b082f6c09dd3b1"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.7.0","labelRegex":"^v8.7.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/149070","number":149070,"mergeCommit":{"message":"Unskip
Execution Context FTRs (#149070)\n\nResolves
https://github.com/elastic/kibana/issues/112102","sha":"4c626f16c0bfc333bf0591f586b082f6c09dd3b1"}}]}]
BACKPORT-->

Co-authored-by: Alejandro Fernández Haro <alejandro.haro@elastic.co>
This commit is contained in:
Kibana Machine 2023-01-24 10:53:33 -05:00 committed by GitHub
parent 3b020352a5
commit b76e760c95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 341 additions and 155 deletions

View file

@ -87,6 +87,7 @@ describe('ExecutionContextService', () => {
`
Object {
"name": "app2",
"type": "application",
"url": "/",
}
`
@ -244,6 +245,7 @@ describe('ExecutionContextService', () => {
execContext.clear();
expect(sub).toHaveBeenCalledWith({
name: 'app1',
type: 'application',
url: '/',
});

View file

@ -98,6 +98,7 @@ export class ExecutionContextService
private getDefaultContext() {
return {
type: 'application',
name: this.appId,
url: window.location.pathname,
};

View file

@ -9,17 +9,26 @@ import Path from 'path';
import { isEqualWith } from 'lodash';
import type { Ecs, KibanaExecutionContext } from '@kbn/core/server';
import type { RetryService } from '@kbn/ftr-common-functional-services';
import { concatMap, defer, filter, firstValueFrom, ReplaySubject, scan, timeout } from 'rxjs';
export const logFilePath = Path.resolve(__dirname, './kibana.log');
export const ANY = Symbol('any');
let logstream$: ReplaySubject<Ecs> | undefined;
export function getExecutionContextFromLogRecord(record: Ecs | undefined): KibanaExecutionContext {
if (record?.log?.logger !== 'execution_context' || !record?.message) {
throw new Error(`The record is not an entry of execution context`);
}
return JSON.parse(record.message);
}
export function isExecutionContextLog(
record: string | undefined,
record: Ecs | undefined,
executionContext: KibanaExecutionContext
) {
if (!record) return false;
try {
const object = JSON.parse(record);
const object = getExecutionContextFromLogRecord(record);
return isEqualWith(object, executionContext, function customizer(obj1: any, obj2: any) {
if (obj2 === ANY) return true;
});
@ -41,12 +50,89 @@ export async function assertLogContains({
}): Promise<void> {
// logs are written to disk asynchronously. I sacrificed performance to reduce flakiness.
await retry.waitFor(description, async () => {
const logsStr = await Fs.readFile(logFilePath, 'utf-8');
const normalizedRecords = logsStr
.split(endOfLine)
.filter(Boolean)
.map((s) => JSON.parse(s));
return normalizedRecords.some(predicate);
if (!logstream$) {
logstream$ = getLogstream$();
}
try {
await firstValueFrom(logstream$.pipe(filter(predicate), timeout(5_000)));
return true;
} catch (err) {
return false;
}
});
}
/**
* Creates an observable that continuously tails the log file.
*/
function getLogstream$(): ReplaySubject<Ecs> {
const stream$ = new ReplaySubject<Ecs>();
defer(async function* () {
const fd = await Fs.open(logFilePath, 'rs');
while (!stream$.isStopped) {
const { bytesRead, buffer } = await fd.read();
if (bytesRead) {
yield buffer.toString('utf8', 0, bytesRead);
}
}
await fd.close();
})
.pipe(
scan<string, { buffer: string; records: Ecs[] }>(
({ buffer }, chunk) => {
const logString = buffer.concat(chunk);
const lines = logString.split(endOfLine);
const lastLine = lines.pop();
const records = lines.map((s) => JSON.parse(s));
let leftover = '';
if (lastLine) {
try {
const validRecord = JSON.parse(lastLine);
records.push(validRecord);
} catch (err) {
leftover = lastLine;
}
}
return { buffer: leftover, records };
},
{
records: [], // The ECS entries in the logs
buffer: '', // Accumulated leftovers from the previous operation
}
),
concatMap(({ records }) => records)
)
.subscribe(stream$);
// let the content start flowing
stream$.subscribe();
return stream$;
}
export function closeLogstream() {
logstream$?.complete();
logstream$ = undefined;
}
/**
* Truncates the log file to avoid tests looking at the logs from previous executions.
*/
export async function clearLogFile() {
closeLogstream();
await Fs.writeFile(logFilePath, '', 'utf8');
await forceSyncLogFile();
logstream$ = getLogstream$();
}
/**
* Force the completion of all the pending I/O operations in the OS related to the log file.
*/
export async function forceSyncLogFile() {
const fileDescriptor = await Fs.open(logFilePath);
await fileDescriptor.datasync();
await fileDescriptor.close();
}

View file

@ -5,15 +5,15 @@
* 2.0.
*/
import type { Ecs, KibanaExecutionContext } from '@kbn/core/server';
import type { FtrProviderContext } from '../ftr_provider_context';
import { assertLogContains, isExecutionContextLog } from '../test_utils';
import { assertLogContains, forceSyncLogFile, isExecutionContextLog } from '../test_utils';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'home']);
const retry = getService('retry');
// FLAKY: https://github.com/elastic/kibana/issues/125743
describe.skip('Browser apps', () => {
describe('Browser apps', () => {
before(async () => {
await PageObjects.common.navigateToUrl('home', '/tutorial_directory/sampleData', {
useActualUrl: true,
@ -34,8 +34,20 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
before(async () => {
await PageObjects.common.navigateToApp('discover');
await PageObjects.header.waitUntilLoadingHasFinished();
await forceSyncLogFile();
});
function checkExecutionContextEntry(expectedExecutionContext: KibanaExecutionContext) {
return (record: Ecs) =>
isExecutionContextLog(record, expectedExecutionContext) ||
isExecutionContextLog(record, {
...expectedExecutionContext,
// There is a race condition that makes these 2 fields to show up some times
page: 'app',
id: 'new',
});
}
it('propagates context for Discover', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
@ -45,31 +57,50 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
description: 'fetch documents',
id: '',
description: 'execution context propagates to Kibana logs (fetch documents)',
predicate: checkExecutionContextEntry({
type: 'application',
name: 'discover',
url: '/app/discover',
child: {
name: 'discover',
type: 'application',
// discovery doesn't have an URL since one of from the example dataset is not saved separately
url: '/app/discover',
}),
type: 'application',
page: 'app',
id: 'new',
description: 'fetch documents',
},
}),
retry,
});
/*
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
description: 'fetch chart data and total hits',
id: '',
description:
'execution context propagates to Kibana logs (fetch chart data and total hits)',
predicate: checkExecutionContextEntry({
type: 'application',
name: 'discover',
url: '/app/discover',
child: {
name: 'discover',
type: 'application',
url: '/app/discover',
}),
type: 'application',
page: 'app',
id: 'new',
description: 'fetch chart data and total hits',
child: {
type: 'lens',
name: 'lnsXY',
id: 'unifiedHistogramLensComponent',
description: 'Edit visualization',
url: '/app/lens#/edit_by_value',
},
},
}),
retry,
});
*/
});
});
@ -79,30 +110,76 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.loadSavedDashboard('[Flights] Global Flight Dashboard');
await PageObjects.dashboard.waitForRenderComplete();
await PageObjects.header.waitUntilLoadingHasFinished();
await forceSyncLogFile();
});
function checkHttpRequestId(suffix: string) {
return (record: Ecs): boolean =>
Boolean(
[
'kibana:application:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;',
// Race conditions may miss the dashboard ID at the top level
'kibana:application:dashboards:;',
// Race conditions may assign the dashboard type to the top level
'kibana:dashboard:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;',
].some((prefix) => record.http?.request?.id?.includes(`${prefix}${suffix}`))
);
}
function checkExecutionContextEntry(expectedExecutionContext: KibanaExecutionContext) {
return (record: Ecs) =>
isExecutionContextLog(record, expectedExecutionContext) ||
isExecutionContextLog(record, { ...expectedExecutionContext, page: 'list' }) ||
isExecutionContextLog(record, { ...expectedExecutionContext, page: 'app' }) ||
isExecutionContextLog(record, {
...expectedExecutionContext,
// There is a race condition that makes this field to be missed sometimes
page: 'app',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
}) ||
isExecutionContextLog(record, {
...expectedExecutionContext,
// There is a race condition that makes the top context to match the child one
page: 'app',
type: 'dashboard',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
}) ||
isExecutionContextLog(record, {
...expectedExecutionContext,
// There is a race condition that makes the top context to match the child one
page: 'app',
type: 'dashboard',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
}) ||
// Some race conditions misses one nested step
(!!expectedExecutionContext.child &&
isExecutionContextLog(record, expectedExecutionContext.child));
}
describe('propagates context for Lens visualizations', () => {
it('lnsXY', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
predicate: (record) =>
Boolean(
record.http?.request?.id?.includes(
'kibana:application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;lens:lnsXY:086ac2e9-dd16-4b45-92b8-1e43ff7e3f65'
)
),
predicate: checkHttpRequestId(
'dashboard:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;lens:lnsXY:086ac2e9-dd16-4b45-92b8-1e43ff7e3f65'
),
retry,
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
type: 'application',
name: 'dashboard',
predicate: checkExecutionContextEntry({
type: 'application',
name: 'dashboards',
url: '/app/dashboards',
child: {
name: 'dashboards',
url: '/app/dashboards',
type: 'dashboard',
page: 'app',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d',
child: {
type: 'lens',
name: 'lnsXY',
@ -110,7 +187,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
description: '[Flights] Flight count',
url: '/app/lens#/edit_by_value',
},
}),
},
}),
retry,
});
});
@ -118,32 +196,34 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('lnsMetric', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
predicate: (record) =>
Boolean(
record.http?.request?.id?.includes(
'kibana:application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;lens:lnsMetric:b766e3b8-4544-46ed-99e6-9ecc4847e2a2'
)
),
predicate: checkHttpRequestId(
'dashboard:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;lens:lnsLegacyMetric:b766e3b8-4544-46ed-99e6-9ecc4847e2a2'
),
retry,
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
type: 'application',
name: 'dashboard',
predicate: checkExecutionContextEntry({
name: 'dashboards',
url: '/app/dashboards',
type: 'application',
child: {
name: 'dashboards',
url: '/app/dashboards',
type: 'dashboard',
page: 'app',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d',
child: {
type: 'lens',
name: 'lnsMetric',
id: '2e33ade5-96e5-40b4-b460-493e5d4fa834',
name: 'lnsLegacyMetric',
id: 'b766e3b8-4544-46ed-99e6-9ecc4847e2a2',
description: '',
url: '/app/lens#/edit_by_value',
},
}),
},
}),
retry,
});
});
@ -151,24 +231,25 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('lnsDatatable', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
predicate: (record) =>
Boolean(
record.http?.request?.id?.includes(
'kibana:application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;lens:lnsDatatable:fb86b32f-fb7a-45cf-9511-f366fef51bbd'
)
),
predicate: checkHttpRequestId(
'dashboard:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;lens:lnsDatatable:fb86b32f-fb7a-45cf-9511-f366fef51bbd'
),
retry,
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
type: 'application',
name: 'dashboard',
predicate: checkExecutionContextEntry({
name: 'dashboards',
url: '/app/dashboards',
type: 'application',
child: {
name: 'dashboards',
url: '/app/dashboards',
type: 'dashboard',
page: 'app',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d',
child: {
type: 'lens',
name: 'lnsDatatable',
@ -176,7 +257,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
description: 'Cities by delay, cancellation',
url: '/app/lens#/edit_by_value',
},
}),
},
}),
retry,
});
});
@ -184,23 +266,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('lnsPie', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
predicate: (record) =>
Boolean(
record.http?.request?.id?.includes(
'kibana:application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;lens:lnsPie:5d53db36-2d5a-4adc-af7b-cec4c1a294e0'
)
),
predicate: checkHttpRequestId(
'dashboard:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;lens:lnsPie:5d53db36-2d5a-4adc-af7b-cec4c1a294e0'
),
retry,
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
type: 'application',
name: 'dashboard',
predicate: checkExecutionContextEntry({
name: 'dashboards',
url: '/app/dashboards',
type: 'application',
child: {
name: 'dashboards',
url: '/app/dashboards',
type: 'dashboard',
page: 'app',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d',
child: {
type: 'lens',
name: 'lnsPie',
@ -208,7 +291,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
description: '[Flights] Delay Type',
url: '/app/lens#/edit_by_value',
},
}),
},
}),
retry,
});
});
@ -217,23 +301,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('propagates context for built-in Discover', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
predicate: (record) =>
Boolean(
record.http?.request?.id?.includes(
'application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;search:discover:571aaf70-4c88-11e8-b3d7-01146121b73d'
)
),
predicate: checkHttpRequestId(
'dashboard:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;search:discover:571aaf70-4c88-11e8-b3d7-01146121b73d'
),
retry,
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
type: 'application',
name: 'dashboard',
predicate: checkExecutionContextEntry({
type: 'application',
name: 'dashboards',
url: '/app/dashboards',
child: {
type: 'dashboard',
name: 'dashboards',
url: '/app/dashboards',
page: 'app',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d',
child: {
type: 'search',
name: 'discover',
@ -241,7 +326,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
description: '[Flights] Flight Log',
url: '/app/discover#/view/571aaf70-4c88-11e8-b3d7-01146121b73d',
},
}),
},
}),
retry,
});
});
@ -249,66 +335,61 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('propagates context for TSVB visualizations', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
predicate: (record) =>
Boolean(
record.http?.request?.id?.includes(
'kibana:application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;visualization:metrics:bcb63b50-4c89-11e8-b3d7-01146121b73d'
)
),
predicate: checkHttpRequestId('agg_based:metrics:bcb63b50-4c89-11e8-b3d7-01146121b73d'),
retry,
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
type: 'application',
name: 'dashboard',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d',
child: {
type: 'visualization',
name: 'metrics',
id: 'bcb63b50-4c89-11e8-b3d7-01146121b73d',
description: '[Flights] Delays & Cancellations',
url: '/app/visualize#/edit/bcb63b50-4c89-11e8-b3d7-01146121b73d',
},
}),
predicate: checkExecutionContextEntry({
name: 'dashboards',
url: '/app/dashboards',
type: 'application',
page: 'app',
description: '[Flights] Global Flight Dashboard',
child: {
type: 'agg_based',
name: 'metrics',
id: 'bcb63b50-4c89-11e8-b3d7-01146121b73d',
description: '[Flights] Delays & Cancellations',
url: '/app/visualize#/edit/bcb63b50-4c89-11e8-b3d7-01146121b73d',
},
}),
retry,
});
});
// application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;visualization:vega:ed78a660-53a0-11e8-acbd-0be0ad9d822b
it('propagates context for Vega visualizations', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
predicate: (record) =>
Boolean(
record.http?.request?.id?.includes(
'kibana:application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;visualization:vega:ed78a660-53a0-11e8-acbd-0be0ad9d822b'
)
),
predicate: checkHttpRequestId(
'dashboard:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;agg_based:vega:ed78a660-53a0-11e8-acbd-0be0ad9d822b'
),
retry,
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
type: 'application',
name: 'dashboard',
predicate: checkExecutionContextEntry({
name: 'dashboards',
url: '/app/dashboards',
type: 'application',
child: {
name: 'dashboards',
url: '/app/dashboards',
type: 'dashboard',
page: 'app',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d',
child: {
type: 'visualization',
type: 'agg_based',
name: 'vega',
id: 'ed78a660-53a0-11e8-acbd-0be0ad9d822b',
description: '[Flights] Airport Connections (Hover Over Airport)',
url: '/app/visualize#/edit/ed78a660-53a0-11e8-acbd-0be0ad9d822b',
},
}),
},
}),
retry,
});
});
@ -316,32 +397,34 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('propagates context for Tag Cloud visualization', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
predicate: (record) =>
Boolean(
record.http?.request?.id?.includes(
'kibana:application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;visualization:tagcloud:293b5a30-4c8f-11e8-b3d7-01146121b73d'
)
),
predicate: checkHttpRequestId(
'dashboard:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;agg_based:tagcloud:293b5a30-4c8f-11e8-b3d7-01146121b73d'
),
retry,
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
type: 'application',
name: 'dashboard',
predicate: checkExecutionContextEntry({
name: 'dashboards',
url: '/app/dashboards',
type: 'application',
child: {
name: 'dashboards',
url: '/app/dashboards',
type: 'dashboard',
page: 'app',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d',
child: {
type: 'visualization',
type: 'agg_based',
name: 'tagcloud',
id: '293b5a30-4c8f-11e8-b3d7-01146121b73d',
description: '[Flights] Destination Weather',
url: '/app/visualize#/edit/293b5a30-4c8f-11e8-b3d7-01146121b73d',
},
}),
},
}),
retry,
});
});
@ -349,32 +432,34 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('propagates context for Vertical bar visualization', async () => {
await assertLogContains({
description: 'execution context propagates to Elasticsearch via "x-opaque-id" header',
predicate: (record) =>
Boolean(
record.http?.request?.id?.includes(
'kibana:application:dashboard:7adfa750-4c81-11e8-b3d7-01146121b73d;visualization:histogram:9886b410-4c8b-11e8-b3d7-01146121b73d'
)
),
predicate: checkHttpRequestId(
'dashboard:dashboards:7adfa750-4c81-11e8-b3d7-01146121b73d;agg_based:histogram:9886b410-4c8b-11e8-b3d7-01146121b73d'
),
retry,
});
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
type: 'application',
name: 'dashboard',
predicate: checkExecutionContextEntry({
type: 'application',
name: 'dashboards',
url: '/app/dashboards',
child: {
type: 'dashboard',
name: 'dashboards',
url: '/app/dashboards',
page: 'app',
id: '7adfa750-4c81-11e8-b3d7-01146121b73d',
description: '[Flights] Global Flight Dashboard',
url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d',
child: {
type: 'visualization',
type: 'agg_based',
name: 'histogram',
id: '9886b410-4c8b-11e8-b3d7-01146121b73d',
description: '[Flights] Delay Buckets',
url: '/app/visualize#/edit/9886b410-4c8b-11e8-b3d7-01146121b73d',
},
}),
},
}),
retry,
});
});

View file

@ -6,9 +6,19 @@
*/
import { FtrProviderContext } from '../ftr_provider_context';
import { clearLogFile, closeLogstream } from '../test_utils';
export default function ({ loadTestFile }: FtrProviderContext) {
describe('Execution context', function () {
before(async () => {
// Cleaning the log file used for the tests to avoid false positives caused by previous runs.
// If any of the tests rely on logs generating during bootstrap, we might need to change this.
await clearLogFile();
});
after(() => {
closeLogstream();
});
loadTestFile(require.resolve('./browser'));
loadTestFile(require.resolve('./server'));
loadTestFile(require.resolve('./log_correlation'));

View file

@ -6,7 +6,7 @@
*/
import expect from '@kbn/expect';
import type { FtrProviderContext } from '../ftr_provider_context';
import { assertLogContains } from '../test_utils';
import { assertLogContains, forceSyncLogFile } from '../test_utils';
export default function ({ getService }: FtrProviderContext) {
const retry = getService('retry');
@ -24,12 +24,14 @@ export default function ({ getService }: FtrProviderContext) {
expect(response2.body.traceId).not.to.be(response1.body.traceId);
await forceSyncLogFile();
let responseTraceId: string | undefined;
await assertLogContains({
description: 'traceId included in the http logs',
predicate: (record) => {
// we don't check trace.id value since trace.id in the test plugin and Kibana are different on CI.
// because different 'elastic-apm-node' instaces are imported
// because different 'elastic-apm-node' instances are imported
if (
record.log?.logger === 'http.server.response' &&
record.url?.path === '/emit_log_with_trace_id'

View file

@ -92,7 +92,7 @@ export default function ({ getService }: FtrProviderContext) {
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
isExecutionContextLog(record, {
type: 'task manager',
name: 'run alerting:test.executionContext',
// @ts-expect-error. it accepts strings only
@ -132,7 +132,7 @@ export default function ({ getService }: FtrProviderContext) {
await assertLogContains({
description: 'execution context propagates to Kibana logs',
predicate: (record) =>
isExecutionContextLog(record?.message, {
isExecutionContextLog(record, {
type: 'usage_collection',
name: 'collector.fetch',
id: 'application_usage',