kibana/packages/kbn-test/src/functional_tests/tasks.ts
Spencer 542b381fa5
[ftr] automatically determine config run order (#130983)
* [ftr] automatically determine config run order

* split lens config into two groups

* support ftr configs always running against CI

* Split detection_engine_api_integration rule exception list tests

* Add configs from previous commit

* [ftr] remove testMetadata and maintain a unique lifecycle instance per run

* Revert "[ftr] remove testMetadata and maintain a unique lifecycle instance per run"

This reverts commit d2b4fdb824.

* Split alerting_api_integration/security_and_spaces tests

* Add groups to yaml

* Revert "Revert "[ftr] remove testMetadata and maintain a unique lifecycle instance per run""

This reverts commit 56232eea68.

* stop ES more forcefully and fix timeout

* only cleanup lifecycle phases when the cleanup is totally complete

* only use kill when cleaning up an esTestInstance

* fix broken import

* fix runOptions.alwaysUseSource implementation

* fix config access

* fix x-pack/ccs config

* fix ml import file paths

* update kibana build id

* revert array.concat() change

* fix baseConfig usage

* fix pie chart data

* split up maps tests

* pull in all of group5 so that es archives are loaded correctly

* add to ftr configs.yml

* fix pie chart data without breaking legacy version

* fix more pie_chart stuff in new vis lib

* restore normal PR tasks

* bump kibana-buildkite-library

* remove ciGroup validation

* remove the script which is no longer called from checks.sh

* [CI] Auto-commit changed files from 'yarn kbn run build -i @kbn/pm'

* adapt flaky test runner scripts to handle ftrConfig paths

* fix types in alerting_api_integration

* improve flaky config parsing and use non-local var name for passing explicit configs to ftr_configs.sh

* Split xpack dashboard tests

* Add configs

* [flaky] remove key from ftr-config steps

* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'

* restore cypress builds

* remove ciGroups from FTR config files

* fixup some docs

* add temporary script to hunt for FTR config files

* use config.base.js naming for clarity

* use script to power ftr_configs.yml

* remove usage of removed x-pack/scripts/functional_tests

* fix test names in dashboard snapshots

* bump kibana-buildkite-library

* Try retrying only failed configs

* be a little quieter about trying to get testStats from configs with testRunners defined

* Remove test code

* bump kibana-buildkite-library

* update es_snapshot and on_merge jobs too

* track duration and exit code for each config and print it at the end of the script

* store results in order, rather than by key, in case there are duplicates in $config

* bash is hard

* fix env source and use +e rather than disabling e for whole file

* bash sucks

* print config summary in jest jobs too

* define results in jest_parallel.sh

* simplify config summary print, format times a little better

* fix reference to unbound time variable, use better variable name

* skip the newline between each result

* finish with the nitpicking

* sync changes with ftr_configs.sh

* refuse to execute config files which aren't listed in the .buildkite/ftr_configs.yml

* fix config.edge.js base config import paths

* fix some readmes

* resolve paths from ftr_configs manifest

* fix readConfigFile tests

* just allow __fixtures__ configs

* list a few more cypress config files

* install the main branch of kibana-buildkite-library

* split up lens group1

* move ml data_visualizer tests to their own config

* fix import paths

* fix more imports

* install specific commit of buildkite-pipeline-library

* sort configs in ftr_configs.yml

* bump kibana-buildkite-library

* remove temporary script

* fix env var for limiting config types

* Update docs/developer/contributing/development-functional-tests.asciidoc

Co-authored-by: Christiane (Tina) Heiligers <christiane.heiligers@elastic.co>

* produce a JUnit report for saved objects field count

* apply standard concurrency limits from flaky test runner

* support customizing FTR concurrency via the env

Co-authored-by: Brian Seeders <brian.seeders@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Christiane (Tina) Heiligers <christiane.heiligers@elastic.co>
2022-05-04 17:05:58 -05:00

206 lines
6.1 KiB
TypeScript

/*
* 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 { relative } from 'path';
import * as Rx from 'rxjs';
import { setTimeout } from 'timers/promises';
import { startWith, switchMap, take } from 'rxjs/operators';
import { withProcRunner } from '@kbn/dev-utils';
import { ToolingLog } from '@kbn/tooling-log';
import { getTimeReporter } from '@kbn/ci-stats-reporter';
import { REPO_ROOT } from '@kbn/utils';
import dedent from 'dedent';
import {
runElasticsearch,
runKibanaServer,
runFtr,
assertNoneExcluded,
hasTests,
KIBANA_FTR_SCRIPT,
CreateFtrOptions,
} from './lib';
import { readConfigFile, EsVersion } from '../functional_test_runner/lib';
const makeSuccessMessage = (options: StartServerOptions) => {
const installDirFlag = options.installDir ? ` --kibana-install-dir=${options.installDir}` : '';
const configPaths: string[] = Array.isArray(options.config) ? options.config : [options.config];
const pathsMessage = options.useDefaultConfig
? ''
: configPaths
.map((path) => relative(process.cwd(), path))
.map((path) => ` --config ${path}`)
.join('');
return (
'\n\n' +
dedent`
Elasticsearch and Kibana are ready for functional testing. Start the functional tests
in another terminal session by running this command from this directory:
node ${relative(process.cwd(), KIBANA_FTR_SCRIPT)}${installDirFlag}${pathsMessage}
` +
'\n\n'
);
};
/**
* Run servers and tests for each config
*/
interface RunTestsParams extends CreateFtrOptions {
/** Array of paths to configs */
configs: string[];
/** run from source instead of snapshot */
esFrom?: string;
esVersion: EsVersion;
createLogger: () => ToolingLog;
extraKbnOpts: string[];
assertNoneExcluded: boolean;
}
export async function runTests(options: RunTestsParams) {
if (!process.env.CI && !options.assertNoneExcluded) {
const log = options.createLogger();
log.warning('❗️❗️❗️');
log.warning('❗️❗️❗️');
log.warning('❗️❗️❗️');
log.warning(
" Don't forget to use `node scripts/build_kibana_platform_plugins` to build plugins you plan on testing"
);
log.warning('❗️❗️❗️');
log.warning('❗️❗️❗️');
log.warning('❗️❗️❗️');
}
const log = options.createLogger();
if (options.assertNoneExcluded) {
log.write('--- asserting that all tests belong to a ciGroup');
for (const configPath of options.configs) {
log.info('loading', configPath);
await log.indent(4, async () => {
await assertNoneExcluded({ configPath, options: { ...options, log } });
});
continue;
}
return;
}
for (const [i, configPath] of options.configs.entries()) {
await log.indent(0, async () => {
if (options.configs.length > 1) {
const progress = `${i + 1}/${options.configs.length}`;
log.write(`--- [${progress}] Running ${relative(REPO_ROOT, configPath)}`);
}
if (!(await hasTests({ configPath, options: { ...options, log } }))) {
// just run the FTR, no Kibana or ES, which will quickly report a skipped test group to ci-stats and continue
await runFtr({ configPath, options: { ...options, log } });
return;
}
await withProcRunner(log, async (procs) => {
const config = await readConfigFile(log, options.esVersion, configPath);
let shutdownEs;
try {
if (process.env.TEST_ES_DISABLE_STARTUP !== 'true') {
shutdownEs = await runElasticsearch({ ...options, log, config });
}
await runKibanaServer({ procs, config, options });
await runFtr({ configPath, options: { ...options, log } });
} finally {
try {
const delay = config.get('kbnTestServer.delayShutdown');
if (typeof delay === 'number') {
log.info('Delaying shutdown of Kibana for', delay, 'ms');
await setTimeout(delay);
}
await procs.stop('kibana');
} finally {
if (shutdownEs) {
await shutdownEs();
}
}
}
});
});
}
}
interface StartServerOptions {
/** Path to a config file */
config: string;
log: ToolingLog;
/** installation dir from which to run Kibana */
installDir?: string;
/** run from source instead of snapshot */
esFrom?: string;
createLogger: () => ToolingLog;
extraKbnOpts: string[];
useDefaultConfig?: boolean;
esVersion: EsVersion;
}
export async function startServers({ ...options }: StartServerOptions) {
const runStartTime = Date.now();
const toolingLog = new ToolingLog({
level: 'info',
writeTo: process.stdout,
});
const reportTime = getTimeReporter(toolingLog, 'scripts/functional_tests_server');
const log = options.createLogger();
const opts = {
...options,
log,
};
await withProcRunner(log, async (procs) => {
const config = await readConfigFile(log, options.esVersion, options.config);
const shutdownEs = await runElasticsearch({ ...opts, config });
await runKibanaServer({
procs,
config,
options: {
...opts,
extraKbnOpts: [
...options.extraKbnOpts,
...(options.installDir ? [] : ['--dev', '--no-dev-config', '--no-dev-credentials']),
],
},
});
reportTime(runStartTime, 'ready', {
success: true,
...options,
});
// wait for 5 seconds of silence before logging the
// success message so that it doesn't get buried
await silence(log, 5000);
log.success(makeSuccessMessage(options));
await procs.waitForAllToStop();
await shutdownEs();
});
}
async function silence(log: ToolingLog, milliseconds: number) {
await log
.getWritten$()
.pipe(
startWith(null),
switchMap(() => Rx.timer(milliseconds)),
take(1)
)
.toPromise();
}