Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code coverage setup on CI #49003

Merged
merged 15 commits into from
Jan 8, 2020
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions .ci/Jenkinsfile_coverage
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/bin/groovy

library 'kibana-pipeline-library'
kibanaLibrary.load() // load from the Jenkins instance

stage("Kibana Pipeline") { // This stage is just here to help the BlueOcean UI a little bit
timeout(time: 180, unit: 'MINUTES') {
timestamps {
ansiColor('xterm') {
catchError {
withEnv([
'CODE_COVERAGE=1', // Needed for multiple ci scripts, such as remote.ts, test/scripts/*.sh, schema.js, etc.
]) {
parallel([
'kibana-intake-agent': {
withEnv([
'NODE_ENV=test' // Needed for jest tests only
]) {
kibanaPipeline.legacyJobRunner('kibana-intake')()
}
},
'x-pack-intake-agent': {
withEnv([
'NODE_ENV=test' // Needed for jest tests only
]) {
kibanaPipeline.legacyJobRunner('x-pack-intake')()
}
},
'kibana-oss-agent': kibanaPipeline.withWorkers('kibana-oss-tests', { kibanaPipeline.buildOss() }, [
'oss-ciGroup1': kibanaPipeline.getOssCiGroupWorker(1),
'oss-ciGroup2': kibanaPipeline.getOssCiGroupWorker(2),
'oss-ciGroup3': kibanaPipeline.getOssCiGroupWorker(3),
'oss-ciGroup4': kibanaPipeline.getOssCiGroupWorker(4),
'oss-ciGroup5': kibanaPipeline.getOssCiGroupWorker(5),
'oss-ciGroup6': kibanaPipeline.getOssCiGroupWorker(6),
'oss-ciGroup7': kibanaPipeline.getOssCiGroupWorker(7),
'oss-ciGroup8': kibanaPipeline.getOssCiGroupWorker(8),
'oss-ciGroup9': kibanaPipeline.getOssCiGroupWorker(9),
'oss-ciGroup10': kibanaPipeline.getOssCiGroupWorker(10),
'oss-ciGroup11': kibanaPipeline.getOssCiGroupWorker(11),
'oss-ciGroup12': kibanaPipeline.getOssCiGroupWorker(12),
]),
'kibana-xpack-agent-1': kibanaPipeline.withWorkers('kibana-xpack-tests-1', { kibanaPipeline.buildXpack() }, [
'xpack-ciGroup1': kibanaPipeline.getXpackCiGroupWorker(1),
'xpack-ciGroup2': kibanaPipeline.getXpackCiGroupWorker(2),
]),
'kibana-xpack-agent-2': kibanaPipeline.withWorkers('kibana-xpack-tests-2', { kibanaPipeline.buildXpack() }, [
'xpack-ciGroup3': kibanaPipeline.getXpackCiGroupWorker(3),
'xpack-ciGroup4': kibanaPipeline.getXpackCiGroupWorker(4),
]),

'kibana-xpack-agent-3': kibanaPipeline.withWorkers('kibana-xpack-tests-3', { kibanaPipeline.buildXpack() }, [
'xpack-ciGroup5': kibanaPipeline.getXpackCiGroupWorker(5),
'xpack-ciGroup6': kibanaPipeline.getXpackCiGroupWorker(6),
'xpack-ciGroup7': kibanaPipeline.getXpackCiGroupWorker(7),
'xpack-ciGroup8': kibanaPipeline.getXpackCiGroupWorker(8),
'xpack-ciGroup9': kibanaPipeline.getXpackCiGroupWorker(9),
'xpack-ciGroup10': kibanaPipeline.getXpackCiGroupWorker(10),
]),
])
kibanaPipeline.jobRunner('tests-l', false) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmlemeshko 'tests-l' ==== some large instance for testing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the default one (PRs) has not enough space for coverage processing (25+ GB)

kibanaPipeline.downloadCoverageArtifacts()
kibanaPipeline.bash(
'''
# bootstrap from x-pack folder
source src/dev/ci_setup/setup_env.sh
cd x-pack
yarn kbn bootstrap --prefer-offline
cd ..
# extract archives
mkdir -p /tmp/extracted_coverage
echo extracting intakes
tar -xzf /tmp/downloaded_coverage/coverage/kibana-intake/kibana-coverage.tar.gz -C /tmp/extracted_coverage
tar -xzf /tmp/downloaded_coverage/coverage/x-pack-intake/kibana-coverage.tar.gz -C /tmp/extracted_coverage
echo extracting kibana-oss-tests
tar -xzf /tmp/downloaded_coverage/coverage/kibana-oss-tests/kibana-coverage.tar.gz -C /tmp/extracted_coverage
echo extracting kibana-xpack-tests
for i in {1..3}; do
tar -xzf /tmp/downloaded_coverage/coverage/kibana-xpack-tests-${i}/kibana-coverage.tar.gz -C /tmp/extracted_coverage
done
# replace path in json files to have valid html report
pwd=$(pwd)
du -sh /tmp/extracted_coverage/target/kibana-coverage/
echo replacing path in json files
for i in {1..9}; do
sed -i "s|/dev/shm/workspace/kibana|$pwd|g" /tmp/extracted_coverage/target/kibana-coverage/functional/${i}*.json &
done
wait
# merge oss & x-pack reports
echo merging coverage reports
yarn nyc report --temp-dir /tmp/extracted_coverage/target/kibana-coverage/jest --report-dir target/kibana-coverage/jest-combined --reporter=html --reporter=json-summary
yarn nyc report --temp-dir /tmp/extracted_coverage/target/kibana-coverage/functional --report-dir target/kibana-coverage/functional-combined --reporter=html --reporter=json-summary
echo copy mocha reports
mkdir -p target/kibana-coverage/mocha-combined
cp -r /tmp/extracted_coverage/target/kibana-coverage/mocha target/kibana-coverage/mocha-combined
''',
"run `yarn kbn bootstrap && merge coverage`"
)
sh 'tar -czf kibana-jest-coverage.tar.gz target/kibana-coverage/jest-combined/*'
kibanaPipeline.uploadCoverageArtifacts("coverage/jest-combined", 'kibana-jest-coverage.tar.gz')
sh 'tar -czf kibana-functional-coverage.tar.gz target/kibana-coverage/functional-combined/*'
kibanaPipeline.uploadCoverageArtifacts("coverage/functional-combined", 'kibana-functional-coverage.tar.gz')
sh 'tar -czf kibana-mocha-coverage.tar.gz target/kibana-coverage/mocha-combined/*'
kibanaPipeline.uploadCoverageArtifacts("coverage/mocha-combined", 'kibana-mocha-coverage.tar.gz')
}
}
}
kibanaPipeline.sendMail()
}
}
}
}
19 changes: 15 additions & 4 deletions scripts/functional_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,23 @@
* under the License.
*/

require('../src/setup_node_env');
require('@kbn/test').runTestsCli([
// eslint-disable-next-line no-restricted-syntax
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would all of these changes feel better as a separate file (e.g. scripts/functional_tests_for_coverage.js or similar)? You'd be able to skip the list combining and eslint disables... I can't decide, just a thought

Copy link
Member Author

@dmlemeshko dmlemeshko Jan 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was in a separate file initially, but I talked to Spencer and made it this way. @spalger is ok or better in an own file?

const alwaysImportedTests = [
require.resolve('../test/functional/config.js'),
require.resolve('../test/api_integration/config.js'),
require.resolve('../test/plugin_functional/config.js'),
require.resolve('../test/interpreter_functional/config.ts'),
require.resolve('../test/ui_capabilities/newsfeed_err/config.ts'),
];
// eslint-disable-next-line no-restricted-syntax
const onlyNotInCoverageTests = [
require.resolve('../test/api_integration/config.js'),
require.resolve('../test/interpreter_functional/config.ts'),
require.resolve('../test/examples/config.js'),
];

require('../src/setup_node_env');
require('@kbn/test').runTestsCli([
// eslint-disable-next-line no-restricted-syntax
...alwaysImportedTests,
// eslint-disable-next-line no-restricted-syntax
...(!!process.env.CODE_COVERAGE ? [] : onlyNotInCoverageTests),
]);
2 changes: 1 addition & 1 deletion src/dev/jest/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default {
],
setupFilesAfterEnv: ['<rootDir>/src/dev/jest/setup/mocks.js'],
coverageDirectory: '<rootDir>/target/kibana-coverage/jest',
coverageReporters: ['html', 'text'],
coverageReporters: !!process.env.CODE_COVERAGE ? ['json'] : ['html', 'text'],
moduleFileExtensions: ['js', 'json', 'ts', 'tsx'],
modulePathIgnorePatterns: ['__fixtures__/', 'target/'],
testMatch: ['**/*.test.{js,ts,tsx}'],
Expand Down
2 changes: 1 addition & 1 deletion src/legacy/server/config/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export default () =>
.default('localhost'),
watchPrebuild: Joi.boolean().default(false),
watchProxyTimeout: Joi.number().default(10 * 60000),
useBundleCache: Joi.boolean().default(Joi.ref('$prod')),
useBundleCache: Joi.boolean().default(!!process.env.CODE_COVERAGE ? true : Joi.ref('$prod')),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that the schema is the best place to put logic like this...

Actually, do you need to set this at all? It's always set to true here:

buildArgs: ['--optimize.useBundleCache=true'],

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is somehow without setting useBundleCache in a schema, I'm getting flaky tests and maybe it is because we don't make a build, but run tests from the source. This change was also made in discussion with @spalger. If I remove it, tests are started to fail for code coverage runs.

sourceMaps: Joi.when('$prod', {
is: true,
then: Joi.boolean().valid(false),
Expand Down
1 change: 1 addition & 0 deletions tasks/config/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ module.exports = function(grunt) {
args: [
'nyc',
'--reporter=html',
'--reporter=json-summary',
'--report-dir=./target/kibana-coverage/mocha',
NODE,
'scripts/mocha',
Expand Down
29 changes: 17 additions & 12 deletions tasks/function_test_groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ const TEST_TAGS = safeLoad(JOBS_YAML)
.JOB.filter(id => id.startsWith('kibana-ciGroup'))
.map(id => id.replace(/^kibana-/, ''));

const getDefaultArgs = tag => {
return [
'scripts/functional_tests',
'--include-tag',
tag,
'--config',
'test/functional/config.js',
'--config',
'test/ui_capabilities/newsfeed_err/config.ts',
// '--config', 'test/functional/config.firefox.js',
'--bail',
'--debug',
];
};

export function getFunctionalTestGroupRunConfigs({ kibanaInstallDir } = {}) {
return {
// include a run task for each test group
Expand All @@ -38,18 +53,8 @@ export function getFunctionalTestGroupRunConfigs({ kibanaInstallDir } = {}) {
[`functionalTests_${tag}`]: {
cmd: process.execPath,
args: [
'scripts/functional_tests',
'--include-tag',
tag,
'--config',
'test/functional/config.js',
'--config',
'test/ui_capabilities/newsfeed_err/config.ts',
// '--config', 'test/functional/config.firefox.js',
'--bail',
'--debug',
'--kibana-install-dir',
kibanaInstallDir,
...getDefaultArgs(tag),
...(!!process.env.CODE_COVERAGE ? [] : ['--kibana-install-dir', kibanaInstallDir]),
],
},
}),
Expand Down
4 changes: 3 additions & 1 deletion test/functional/services/remote/remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ export async function RemoteProvider({ getService }: FtrProviderContext) {
.subscribe({
next({ message, level }) {
const msg = message.replace(/\\n/g, '\n');
log[level === 'SEVERE' ? 'error' : 'debug'](`browser[${level}] ${msg}`);
log[level === 'SEVERE' || level === 'error' ? 'error' : 'debug'](
`browser[${level}] ${msg}`
);
},
});

Expand Down
7 changes: 5 additions & 2 deletions test/scripts/jenkins_build_kibana.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ node scripts/es snapshot --license=oss --download-only;
echo " -> Ensuring all functional tests are in a ciGroup"
yarn run grunt functionalTests:ensureAllTestsInCiGroup;

echo " -> building and extracting OSS Kibana distributable for use in functional tests"
node scripts/build --debug --oss
# Do not build kibana for code coverage run
if [[ -z "$CODE_COVERAGE" ]] ; then
echo " -> building and extracting OSS Kibana distributable for use in functional tests"
node scripts/build --debug --oss
fi
38 changes: 23 additions & 15 deletions test/scripts/jenkins_ci_group.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,30 @@

source test/scripts/jenkins_test_setup.sh

if [[ -z "$IS_PIPELINE_JOB" ]] ; then
yarn run grunt functionalTests:ensureAllTestsInCiGroup;
node scripts/build --debug --oss;
else
installDir="$(realpath $PARENT_DIR/kibana/build/oss/kibana-*-SNAPSHOT-linux-x86_64)"
destDir=${installDir}-${CI_WORKER_NUMBER}
cp -R "$installDir" "$destDir"
if [[ -z "$CODE_COVERAGE" ]] ; then
if [[ -z "$IS_PIPELINE_JOB" ]] ; then
yarn run grunt functionalTests:ensureAllTestsInCiGroup;
node scripts/build --debug --oss;
else
installDir="$(realpath $PARENT_DIR/kibana/build/oss/kibana-*-SNAPSHOT-linux-x86_64)"
destDir=${installDir}-${CI_WORKER_NUMBER}
cp -R "$installDir" "$destDir"

export KIBANA_INSTALL_DIR="$destDir"
fi
export KIBANA_INSTALL_DIR="$destDir"
fi

checks-reporter-with-killswitch "Functional tests / Group ${CI_GROUP}" yarn run grunt "run:functionalTests_ciGroup${CI_GROUP}";

if [ "$CI_GROUP" == "1" ]; then
source test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh
yarn run grunt run:pluginFunctionalTestsRelease --from=source;
yarn run grunt run:exampleFunctionalTestsRelease --from=source;
yarn run grunt run:interpreterFunctionalTestsRelease;
fi
else
echo " -> Running Functional tests with code coverage"

checks-reporter-with-killswitch "Functional tests / Group ${CI_GROUP}" yarn run grunt "run:functionalTests_ciGroup${CI_GROUP}";
export NODE_OPTIONS=--max_old_space_size=8192

if [ "$CI_GROUP" == "1" ]; then
source test/scripts/jenkins_build_kbn_tp_sample_panel_action.sh
yarn run grunt run:pluginFunctionalTestsRelease --from=source;
yarn run grunt run:exampleFunctionalTestsRelease --from=source;
yarn run grunt run:interpreterFunctionalTestsRelease;
yarn run grunt "run:functionalTests_ciGroup${CI_GROUP}";
fi
14 changes: 13 additions & 1 deletion test/scripts/jenkins_unit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,16 @@ set -e

export TEST_BROWSER_HEADLESS=1

"$(FORCE_COLOR=0 yarn bin)/grunt" jenkins:unit --dev;
if [[ -z "$CODE_COVERAGE" ]] ; then
"$(FORCE_COLOR=0 yarn bin)/grunt" jenkins:unit --dev;
else
echo "NODE_ENV=$NODE_ENV"
echo " -> Running jest tests with coverage"
node scripts/jest --ci --verbose --coverage
echo ""
echo ""
echo " -> Running mocha tests with coverage"
yarn run grunt "test:mochaCoverage";
echo ""
echo ""
fi
75 changes: 45 additions & 30 deletions test/scripts/jenkins_xpack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,48 @@ set -e

export TEST_BROWSER_HEADLESS=1

echo " -> Running mocha tests"
cd "$XPACK_DIR"
checks-reporter-with-killswitch "X-Pack Karma Tests" yarn test:browser
echo ""
echo ""

echo " -> Running jest tests"
cd "$XPACK_DIR"
checks-reporter-with-killswitch "X-Pack Jest" node scripts/jest --ci --verbose
echo ""
echo ""

echo " -> Running SIEM cyclic dependency test"
cd "$XPACK_DIR"
checks-reporter-with-killswitch "X-Pack SIEM cyclic dependency test" node legacy/plugins/siem/scripts/check_circular_deps
echo ""
echo ""

# FAILING: https://github.com/elastic/kibana/issues/44250
# echo " -> Running jest contracts tests"
# cd "$XPACK_DIR"
# SLAPSHOT_ONLINE=true CONTRACT_ONLINE=true node scripts/jest_contract.js --ci --verbose
# echo ""
# echo ""

# echo " -> Running jest integration tests"
# cd "$XPACK_DIR"
# node scripts/jest_integration --ci --verbose
# echo ""
# echo ""
if [[ -z "$CODE_COVERAGE" ]] ; then
echo " -> Running mocha tests"
cd "$XPACK_DIR"
checks-reporter-with-killswitch "X-Pack Karma Tests" yarn test:browser
echo ""
echo ""

echo " -> Running jest tests"
cd "$XPACK_DIR"
checks-reporter-with-killswitch "X-Pack Jest" node scripts/jest --ci --verbose
echo ""
echo ""

echo " -> Running SIEM cyclic dependency test"
cd "$XPACK_DIR"
checks-reporter-with-killswitch "X-Pack SIEM cyclic dependency test" node legacy/plugins/siem/scripts/check_circular_deps
echo ""
echo ""

# FAILING: https://github.com/elastic/kibana/issues/44250
# echo " -> Running jest contracts tests"
# cd "$XPACK_DIR"
# SLAPSHOT_ONLINE=true CONTRACT_ONLINE=true node scripts/jest_contract.js --ci --verbose
# echo ""
# echo ""

# echo " -> Running jest integration tests"
# cd "$XPACK_DIR"
# node scripts/jest_integration --ci --verbose
# echo ""
# echo ""
else
echo " -> Running jest tests with coverage"
cd "$XPACK_DIR"
# build runtime for canvas
echo "NODE_ENV=$NODE_ENV"
node ./legacy/plugins/canvas/scripts/shareable_runtime
node scripts/jest --ci --verbose --coverage
# rename file in order to be unique one
test -f ../target/kibana-coverage/jest/coverage-final.json \
Copy link
Contributor

@brianseeders brianseeders Jan 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test will fail the build if the file isn't there (because it returns a non-zero exit code), in case that isn't what you want.

Also, you still might have the problem I mentioned before:

If node scripts/jest --ci --verbose --coverage has a test that fails, this script will exit before the rename happens. So, later on, when you expect the file to be called xpack-coverage-final.json, it will be called coverage-final.json. Is this a problem?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if any test will fail coverage-final.json won't be generated. And actually we agreed not to proceed with coverage merging if any tests failed.

So exiting before renaming is fine, build should be red and next step (merge) is not starting. If the tests pass, json file is expected to be generated and I rename it because the json with the same name will be generated for oss jest tests.
During merge step I extract both oss and xpack in the same folder for merging, names should be unique to avoid overwriting.
What do you think is the best solution with context I provided?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just asked @LeeDr and he feels we should not push the coverage data if there's a failure as that will skew the coverage numbers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good, just wanted to make sure the file not getting renamed wasn't going to cause a downstream issue!

&& mv ../target/kibana-coverage/jest/coverage-final.json \
../target/kibana-coverage/jest/xpack-coverage-final.json
echo ""
echo ""
fi
17 changes: 10 additions & 7 deletions test/scripts/jenkins_xpack_build_kibana.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ node scripts/functional_tests --assert-none-excluded \
--include-tag ciGroup9 \
--include-tag ciGroup10

echo " -> building and extracting default Kibana distributable for use in functional tests"
cd "$KIBANA_DIR"
node scripts/build --debug --no-oss
linuxBuild="$(find "$KIBANA_DIR/target" -name 'kibana-*-linux-x86_64.tar.gz')"
installDir="$PARENT_DIR/install/kibana"
mkdir -p "$installDir"
tar -xzf "$linuxBuild" -C "$installDir" --strip=1
# Do not build kibana for code coverage run
if [[ -z "$CODE_COVERAGE" ]] ; then
echo " -> building and extracting default Kibana distributable for use in functional tests"
cd "$KIBANA_DIR"
node scripts/build --debug --no-oss
linuxBuild="$(find "$KIBANA_DIR/target" -name 'kibana-*-linux-x86_64.tar.gz')"
installDir="$PARENT_DIR/install/kibana"
mkdir -p "$installDir"
tar -xzf "$linuxBuild" -C "$installDir" --strip=1
fi
Loading