Skip to content

Commit

Permalink
[ci] Splits Jest integration tests (elastic#125454)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyler Smalley authored Feb 14, 2022
1 parent d383bda commit 435b772
Show file tree
Hide file tree
Showing 27 changed files with 467 additions and 62 deletions.
3 changes: 2 additions & 1 deletion .buildkite/pipelines/hourly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,10 @@ steps:

- command: .buildkite/scripts/steps/test/jest_integration.sh
label: 'Jest Integration Tests'
parallelism: 2
agents:
queue: n2-4
timeout_in_minutes: 120
timeout_in_minutes: 90
key: jest-integration

- command: .buildkite/scripts/steps/test/api_integration.sh
Expand Down
3 changes: 2 additions & 1 deletion .buildkite/pipelines/pull_request/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,10 @@ steps:

- command: .buildkite/scripts/steps/test/jest_integration.sh
label: 'Jest Integration Tests'
parallelism: 2
agents:
queue: n2-4
timeout_in_minutes: 120
timeout_in_minutes: 90
key: jest-integration

- command: .buildkite/scripts/steps/test/api_integration.sh
Expand Down
4 changes: 2 additions & 2 deletions .buildkite/scripts/steps/test/jest_integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ is_test_execution_step
.buildkite/scripts/bootstrap.sh

echo '--- Jest Integration Tests'
checks-reporter-with-killswitch "Jest Integration Tests" \
node --max-old-space-size=6144 scripts/jest_integration --ci
checks-reporter-with-killswitch "Jest Integration Tests $((BUILDKITE_PARALLEL_JOB+1))" \
.buildkite/scripts/steps/test/jest_parallel.sh jest.integration.config.js
6 changes: 3 additions & 3 deletions .buildkite/scripts/steps/test/jest_parallel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exitCode=0
while read -r config; do
if [ "$((i % JOB_COUNT))" -eq "$JOB" ]; then
echo "--- $ node scripts/jest --config $config"
node --max-old-space-size=14336 ./node_modules/.bin/jest --config="$config" --runInBand --coverage=false
node --max-old-space-size=14336 ./node_modules/.bin/jest --config="$config" --runInBand --coverage=false --passWithNoTests
lastCode=$?

if [ $lastCode -ne 0 ]; then
Expand All @@ -25,6 +25,6 @@ while read -r config; do

((i=i+1))
# uses heredoc to avoid the while loop being in a sub-shell thus unable to overwrite exitCode
done <<< "$(find src x-pack packages -name jest.config.js -not -path "*/__fixtures__/*" | sort)"
done <<< "$(find src x-pack packages -name ${1:-jest.config.js} -not -path "*/__fixtures__/*" | sort)"

exit $exitCode
exit $exitCode
4 changes: 3 additions & 1 deletion dev_docs/tutorials/debugging.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ Next we will go over how to exactly enable the inspector for different aspects o

You will need to run Jest directly from the Node script:

`node --inspect-brk scripts/jest [TestPathPattern]`
`node --inspect-brk node_modules/.bin/jest --runInBand --config [JestConfig] [TestPathPattern]`

Additional information can be found in the [Jest troubleshooting documentation](https://jestjs.io/docs/troubleshooting).

### Functional Test Runner

Expand Down
13 changes: 13 additions & 0 deletions packages/kbn-es/jest.integration.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test/jest_integration',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-es'],
};
13 changes: 13 additions & 0 deletions packages/kbn-optimizer/jest.integration.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test/jest_integration',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-optimizer'],
};
13 changes: 13 additions & 0 deletions packages/kbn-plugin-generator/jest.integration.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test/jest_integration',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-plugin-generator'],
};
13 changes: 13 additions & 0 deletions packages/kbn-plugin-helpers/jest.integration.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test/jest_integration',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-plugin-helpers'],
};
13 changes: 13 additions & 0 deletions packages/kbn-test/jest.integration.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test/jest_integration',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-test'],
};
8 changes: 7 additions & 1 deletion packages/kbn-test/jest_integration/jest-preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ module.exports = {
],
reporters: [
'default',
['@kbn/test/target_node/jest/junit_reporter', { reportName: 'Jest Integration Tests' }],
[
'@kbn/test/target_node/jest/junit_reporter',
{
rootDirectory: '.',
reportName: 'Jest Integration Tests',
},
],
[
'@kbn/test/target_node/jest/ci_stats_jest_reporter',
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions packages/kbn-test/src/jest/configs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export * from './jest_configs';
116 changes: 116 additions & 0 deletions packages/kbn-test/src/jest/configs/jest_configs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* 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 mockFs from 'mock-fs';
import fs from 'fs';

import { JestConfigs } from './jest_configs';

describe('jestConfigs', () => {
let jestConfigs: JestConfigs;

beforeEach(async () => {
mockFs({
'/kbn-test/packages': {
a: {
'jest.config.js': '',
'a_first.test.js': '',
'a_second.test.js': '',
},
b: {
'b.test.js': '',
integration_tests: {
'b_integration.test.js': '',
},
nested: {
d: {
'd.test.js': '',
},
},
},
c: {
'jest.integration.config.js': '',
integration_tests: {
'c_integration.test.js': '',
},
},
},
});
jestConfigs = new JestConfigs('/kbn-test', ['packages/b/nested', 'packages']);
});

afterEach(mockFs.restore);

describe('#files', () => {
it('lists unit test files', async () => {
const files = await jestConfigs.files('unit');
expect(files).toEqual([
'packages/a/a_first.test.js',
'packages/a/a_second.test.js',
'packages/b/b.test.js',
'packages/b/nested/d/d.test.js',
]);
});

it('lists integration test files', async () => {
const files = await jestConfigs.files('integration');
expect(files).toEqual([
'packages/b/integration_tests/b_integration.test.js',
'packages/c/integration_tests/c_integration.test.js',
]);
});
});

describe('#expected', () => {
it('expects unit config files', async () => {
const files = await jestConfigs.expected('unit');
expect(files).toEqual([
'packages/a/jest.config.js',
'packages/b/jest.config.js',
'packages/b/nested/d/jest.config.js',
]);
});

it('expects integration config files', async () => {
const files = await jestConfigs.expected('integration');
expect(files).toEqual([
'packages/b/jest.integration.config.js',
'packages/c/jest.integration.config.js',
]);
});

it('throws if test file outside root', async () => {
fs.writeFileSync('/kbn-test/bad.test.js', '');
await expect(() => jestConfigs.expected('unit')).rejects.toMatchSnapshot();
});
});

describe('#existing', () => {
it('lists existing unit test config files', async () => {
const files = await jestConfigs.existing('unit');
expect(files).toEqual(['packages/a/jest.config.js']);
});

it('lists existing integration test config files', async () => {
const files = await jestConfigs.existing('integration');
expect(files).toEqual(['packages/c/jest.integration.config.js']);
});
});

describe('#missing', () => {
it('lists existing unit test config files', async () => {
const files = await jestConfigs.missing('unit');
expect(files).toEqual(['packages/b/jest.config.js', 'packages/b/nested/d/jest.config.js']);
});

it('lists existing integration test config files', async () => {
const files = await jestConfigs.missing('integration');
expect(files).toEqual(['packages/b/jest.integration.config.js']);
});
});
});
85 changes: 85 additions & 0 deletions packages/kbn-test/src/jest/configs/jest_configs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* 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 path from 'path';
import globby from 'globby';

// @ts-ignore
import { testMatch } from '../../../jest-preset';

export const CONFIG_NAMES = {
unit: 'jest.config.js',
integration: 'jest.integration.config.js',
};

export class JestConfigs {
cwd: string;
roots: string[];
allFiles: string[] | undefined;

constructor(cwd: string, roots: string[]) {
this.cwd = cwd;
this.roots = roots;
}

async files(type: 'unit' | 'integration') {
if (!this.allFiles) {
this.allFiles = await globby(testMatch, {
gitignore: true,
cwd: this.cwd,
});
}

return this.allFiles.filter((f) =>
type === 'integration' ? f.includes('integration_tests') : !f.includes('integration_tests')
);
}

async expected(type: 'unit' | 'integration') {
const filesForType = await this.files(type);
const directories: Set<string> = new Set();

filesForType.forEach((file) => {
const root = this.roots.find((r) => file.startsWith(r));

if (root) {
const splitPath = file.substring(root.length).split(path.sep);

if (splitPath.length > 2) {
const name = splitPath[1];
directories.add([root, name].join(path.sep));
}
} else {
throw new Error(
`Test file (${file}) can not exist outside roots (${this.roots.join(
', '
)}). Move it to a root or configure additional root.`
);
}
});

return [...directories].map((d) => [d, CONFIG_NAMES[type]].join(path.sep));
}

async existing(type: 'unit' | 'integration') {
return await globby(`**/${CONFIG_NAMES[type]}`, {
gitignore: true,
cwd: this.cwd,
});
}

async missing(type: 'unit' | 'integration') {
const expectedConfigs = await this.expected(type);
const existingConfigs = await this.existing(type);
return await expectedConfigs.filter((x) => !existingConfigs.includes(x));
}

async allMissing() {
return (await this.missing('unit')).concat(await this.missing('integration'));
}
}
Loading

0 comments on commit 435b772

Please sign in to comment.