Skip to content

Commit

Permalink
add execution context tests for alerts and tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
mshustov committed Sep 3, 2021
1 parent c5a76d7 commit 35c9272
Show file tree
Hide file tree
Showing 10 changed files with 712 additions and 376 deletions.
22 changes: 21 additions & 1 deletion x-pack/test/functional_execution_context/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,46 @@
* 2.0.
*/
import Path from 'path';
import { CA_CERT_PATH } from '@kbn/dev-utils';
import { FtrConfigProviderContext } from '@kbn/test';
import { logFilePath } from './test_utils';

const alertTestPlugin = Path.resolve(__dirname, './fixtures/plugins/alerts');

export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const functionalConfig = await readConfigFile(require.resolve('../../test/functional/config'));

const servers = {
...functionalConfig.get('servers'),
elasticsearch: {
...functionalConfig.get('servers.elasticsearch'),
protocol: 'https',
},
};

return {
...functionalConfig.getAll(),
rootTags: ['skipCloud'],
testFiles: [require.resolve('./tests/')],
junit: {
reportName: 'Execution Context Functional Tests',
},
servers,
esTestCluster: {
...functionalConfig.get('esTestCluster'),
ssl: true,
},
kbnTestServer: {
...functionalConfig.get('kbnTestServer'),
serverArgs: [
...functionalConfig.get('kbnTestServer.serverArgs'),
`--plugin-path=${alertTestPlugin}`,
`--elasticsearch.hosts=${servers.elasticsearch.protocol}://${servers.elasticsearch.hostname}:${servers.elasticsearch.port}`,
`--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`,

'--execution_context.enabled=true',
'--logging.appenders.file.type=file',
`--logging.appenders.file.fileName=${Path.resolve(__dirname, './kibana.log')}`,
`--logging.appenders.file.fileName=${logFilePath}`,
'--logging.appenders.file.layout.type=json',

'--logging.loggers[0].name=elasticsearch.query',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "alertsFixtures",
"owner": {
"name": "Core team",
"githubTeam": "kibana-core"
},
"version": "1.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack"],
"requiredPlugins": ["taskManager", "features", "actions", "alerting"],
"optionalPlugins": ["security", "spaces"],
"server": true,
"ui": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "alerts-fixtures",
"version": "1.0.0",
"kibana": {
"version": "kibana",
"templateVersion": "1.0.0"
},
"scripts": {
"kbn": "node ../../../../../../scripts/kbn.js",
"build": "rm -rf './target' && ../../../../../../node_modules/.bin/tsc"
},
"license": "Elastic License 2.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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 { FixturePlugin } from './plugin';

export const plugin = () => new FixturePlugin();
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* 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 { Plugin, CoreSetup } from 'kibana/server';
import { PluginSetupContract as AlertingPluginSetup } from '../../../../../../plugins/alerting/server/plugin';
import { EncryptedSavedObjectsPluginStart } from '../../../../../../plugins/encrypted_saved_objects/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../../../../../plugins/features/server';
import { SpacesPluginStart } from '../../../../../../plugins/spaces/server';
import { SecurityPluginStart } from '../../../../../../plugins/security/server';

export interface FixtureSetupDeps {
features: FeaturesPluginSetup;
alerting: AlertingPluginSetup;
}

export interface FixtureStartDeps {
encryptedSavedObjects: EncryptedSavedObjectsPluginStart;
security?: SecurityPluginStart;
spaces?: SpacesPluginStart;
}

export class FixturePlugin implements Plugin<void, void, FixtureSetupDeps, FixtureStartDeps> {
constructor() {}

public setup(core: CoreSetup<FixtureStartDeps>, { features, alerting }: FixtureSetupDeps) {
features.registerKibanaFeature({
id: 'alertsFixture',
name: 'Alerts',
app: ['alerts', 'kibana'],
category: { id: 'foo', label: 'foo' },
alerting: ['test.longRunning'],
privileges: {
all: {
app: ['alerts', 'kibana'],
savedObject: {
all: ['alert'],
read: [],
},
alerting: {
rule: {
all: ['test.longRunning'],
},
},
ui: [],
},
read: {
app: ['alerts', 'kibana'],
savedObject: {
all: [],
read: ['alert'],
},
alerting: {
rule: {
read: ['test.longRunning'],
},
},
ui: [],
},
},
});

alerting.registerType({
id: 'test.longRunning',
name: 'Test: Query Elasticsearch server',
actionGroups: [
{
id: 'default',
name: 'Default',
},
],
producer: 'alertsFixture',
defaultActionGroupId: 'default',
minimumLicenseRequired: 'basic',
isExportable: true,
async executor() {
const [coreStart] = await core.getStartServices();
await coreStart.elasticsearch.client.asInternalUser.ping();
},
});
}

public start() {}
public stop() {}
}
53 changes: 53 additions & 0 deletions x-pack/test/functional_execution_context/test_utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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/promises';
import Path from 'path';
import { isEqualWith } from 'lodash';
import type { Ecs, KibanaExecutionContext } from 'kibana/server';
import type { RetryService } from '../../../test/common/services/retry';

export const logFilePath = Path.resolve(__dirname, './kibana.log');
export const ANY = Symbol('any');
export function isExecutionContextLog(
record: string | undefined,
executionContext: KibanaExecutionContext
) {
if (!record) return false;
try {
const object = JSON.parse(record);
return isEqualWith(object, executionContext, function customizer(obj1: any, obj2: any) {
if (obj2 === ANY) return true;
});
} catch (e) {
return false;
}
}

// to avoid splitting log record containing \n symbol
const endOfLine = /(?<=})\s*\n/;
export async function assertLogContains({
description,
predicate,
retry,
path,
}: {
description: string;
predicate: (record: Ecs) => boolean;
path: string;
retry: RetryService;
}): Promise<void> {
// logs are written to disk asynchronously. I sacrificed performance to reduce flakiness.
await retry.waitFor(description, async () => {
const logsStr = await Fs.readFile(path, 'utf-8');
const normalizedRecords = logsStr
.split(endOfLine)
.filter(Boolean)
.map((s) => JSON.parse(s));

return normalizedRecords.some(predicate);
});
}
Loading

0 comments on commit 35c9272

Please sign in to comment.