@samitouri / QOS-React-2 / commits / 85215413cb

[ci] Improve parallelism of yarn test

This PR adds parallelism similar to our existing circleci setup for running yarn tests with the various test params. It does this by sharding tests into `$SHARD_COUNT` number of groups, then spawning a job for each of them and using jest's built in `--shard` option. Effectively this means that the job will spawn an additional (where `n` is the number of test params) `n * $SHARD_COUNT` number of jobs to run tests in parallel for a total of `n + (n * $SHARD_COUNT)` jobs. This does mean the GitHub UI at the bottom of each PR gets longer and unfortunately it's not sorted in any way as far as I can tell. But if something goes wrong it should still be easy to find out what the problem is. The PR also changes the `ci` argument for jest-cli to be an enum instead so the tests use all available workers in GitHub actions. This will have to live around for a bit until we can fully migrate off of circleci. ghstack-source-id: 08f2d16353aeca7cd15655d5ce2b7963a12507a7 Pull Request resolved: https://github.com/facebook/react/pull/30033

Lauren Tan committed Jun 22, 2024 at 12:33 UTC 85215413cbfd5f28a4448b0d649b9198458e00e8
5 files changed +81 -45
.circleci/config.yml
+3 -3
@@ -281,7 +281,7 @@ jobs:
281 at: .
282 - setup_node_modules
283 - run: ./scripts/circleci/download_devtools_regression_build.js << parameters.version >> --replaceBuild
284 - - run: node ./scripts/jest/jest-cli.js --build --project devtools --release-channel=experimental --reactVersion << parameters.version >> --ci
284 + - run: node ./scripts/jest/jest-cli.js --build --project devtools --release-channel=experimental --reactVersion << parameters.version >> --ci=circleci
285
286 run_devtools_e2e_tests_for_versions:
287 docker: *docker
@@ -368,7 +368,7 @@ jobs:
368 steps:
369 - checkout
370 - setup_node_modules
371 - - run: yarn test <<parameters.args>> --ci
371 + - run: yarn test <<parameters.args>> --ci=circleci
372
373 yarn_test_build:
374 docker: *docker
@@ -382,7 +382,7 @@ jobs:
382 - attach_workspace:
383 at: .
384 - setup_node_modules
385 - - run: yarn test --build <<parameters.args>> --ci
385 + - run: yarn test --build <<parameters.args>> --ci=circleci
386
387 RELEASE_CHANNEL_stable_yarn_test_dom_fixtures:
388 docker: *docker
.github/workflows/fuzz_tests.yml
+2 -2
@@ -28,5 +28,5 @@ jobs:
28 shell: bash
29 - name: Run fuzz tests
30 run: |-
31 - FUZZ_TEST_SEED=$RANDOM yarn test fuzz --ci
32 - FUZZ_TEST_SEED=$RANDOM yarn test --prod fuzz --ci
31 + FUZZ_TEST_SEED=$RANDOM yarn test fuzz --ci=github
32 + FUZZ_TEST_SEED=$RANDOM yarn test --prod fuzz --ci=github
.github/workflows/runtime_test.yml
+57 -27
@@ -7,37 +7,67 @@ on:
7 paths-ignore:
8 - 'compiler/**'
9
10 +env:
11 + # Number of workers (one per shard) to spawn
12 + SHARD_COUNT: 5
13 +
14 jobs:
15 + # Define the various test parameters and parallelism for this workflow
16 + build_test_params:
17 + name: Build test params
18 + runs-on: ubuntu-latest
19 + outputs:
20 + params: ${{ steps.define-params.outputs.result }}
21 + shard_id: ${{ steps.define-shards.outputs.result }}
22 + steps:
23 + - uses: actions/github-script@v7
24 + id: define-shards
25 + with:
26 + script: |
27 + function range(from, to) {
28 + const arr = [];
29 + for (let n = from; n <= to; n++) {
30 + arr.push(n);
31 + }
32 + return arr;
33 + }
34 + return range(1, process.env.SHARD_COUNT);
35 + - uses: actions/github-script@v7
36 + id: define-params
37 + with:
38 + script: |
39 + return [
40 + "-r=stable --env=development",
41 + "-r=stable --env=production",
42 + "-r=experimental --env=development",
43 + "-r=experimental --env=production",
44 + "-r=www-classic --env=development --variant=false",
45 + "-r=www-classic --env=production --variant=false",
46 + "-r=www-classic --env=development --variant=true",
47 + "-r=www-classic --env=production --variant=true",
48 + "-r=www-modern --env=development --variant=false",
49 + "-r=www-modern --env=production --variant=false",
50 + "-r=www-modern --env=development --variant=true",
51 + "-r=www-modern --env=production --variant=true",
52 + "-r=xplat --env=development --variant=false",
53 + "-r=xplat --env=development --variant=true",
54 + "-r=xplat --env=production --variant=false",
55 + "-r=xplat --env=production --variant=true",
56 + // TODO: Test more persistent configurations?
57 + "-r=stable --env=development --persistent",
58 + "-r=experimental --env=development --persistent"
59 + ];
60 +
61 + # Spawn a job for each shard for a given set of test params
62 test:
12 - name: yarn test
63 + name: yarn test ${{ matrix.params }} (Shard ${{ matrix.shard_id }})
64 runs-on: ubuntu-latest
14 - continue-on-error: true
65 + needs: build_test_params
66 strategy:
67 matrix:
17 - # Intentionally passing these as strings instead of creating a
18 - # separate parameter per CLI argument, since it's easier to
19 - # control/see which combinations we want to run.
20 - params: [
21 - "-r=stable --env=development",
22 - "-r=stable --env=production",
23 - "-r=experimental --env=development",
24 - "-r=experimental --env=production",
25 - "-r=www-classic --env=development --variant=false",
26 - "-r=www-classic --env=production --variant=false",
27 - "-r=www-classic --env=development --variant=true",
28 - "-r=www-classic --env=production --variant=true",
29 - "-r=www-modern --env=development --variant=false",
30 - "-r=www-modern --env=production --variant=false",
31 - "-r=www-modern --env=development --variant=true",
32 - "-r=www-modern --env=production --variant=true",
33 - "-r=xplat --env=development --variant=false",
34 - "-r=xplat --env=development --variant=true",
35 - "-r=xplat --env=production --variant=false",
36 - "-r=xplat --env=production --variant=true",
37 - # TODO: Test more persistent configurations?
38 - "-r=stable --env=development --persistent",
39 - "-r=experimental --env=development --persistent"
40 - ]
68 + params: ${{ fromJSON(needs.build_test_params.outputs.params) }}
69 + shard_id: ${{ fromJSON(needs.build_test_params.outputs.shard_id) }}
70 + continue-on-error: true
71 steps:
72 - uses: actions/checkout@v4
73 - uses: actions/setup-node@v4
@@ -52,4 +82,4 @@ jobs:
82 path: "**/node_modules"
83 key: ${{ runner.arch }}-${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}
84 - run: yarn install --frozen-lockfile
55 - - run: yarn test ${{ matrix.params }} --ci
85 + - run: yarn test ${{ matrix.params }} --ci=github --shard=${{ matrix.shard_id }}/${{ env.SHARD_COUNT }}
packages/react-dom/src/__tests__/ReactMultiChildText-test.js
+1 -1
@@ -77,7 +77,7 @@ const expectChildren = function (container, children) {
77 * faster to render and update.
78 */
79 describe('ReactMultiChildText', () => {
80 - jest.setTimeout(20000);
80 + jest.setTimeout(30000);
81
82 it('should correctly handle all possible children for render and update', async () => {
83 await expect(async () => {
scripts/jest/jest-cli.js
+18 -12
@@ -91,8 +91,8 @@ const argv = yargs
91 ci: {
92 describe: 'Run tests in CI',
93 requiresArg: false,
94 - type: 'boolean',
95 - default: false,
94 + type: 'choices',
95 + choices: ['circleci', 'github'],
96 },
97 compactConsole: {
98 alias: 'c',
@@ -309,10 +309,14 @@ function getCommandArgs() {
309 }
310
311 // CI Environments have limited workers.
312 - if (argv.ci) {
312 + if (argv.ci === 'circleci') {
313 args.push('--maxWorkers=2');
314 }
315
316 + if (argv.ci === 'github') {
317 + args.push('--maxConcurrency=10');
318 + }
319 +
320 // Push the remaining args onto the command.
321 // This will send args like `--watch` to Jest.
322 args.push(...argv._);
@@ -364,16 +368,18 @@ function main() {
368 const envars = getEnvars();
369 const env = Object.entries(envars).map(([k, v]) => `${k}=${v}`);
370
367 - // Print the full command we're actually running.
368 - const command = `$ ${env.join(' ')} node ${args.join(' ')}`;
369 - console.log(chalk.dim(command));
371 + if (argv.ci !== 'github') {
372 + // Print the full command we're actually running.
373 + const command = `$ ${env.join(' ')} node ${args.join(' ')}`;
374 + console.log(chalk.dim(command));
375
371 - // Print the release channel and project we're running for quick confirmation.
372 - console.log(
373 - chalk.blue(
374 - `\nRunning tests for ${argv.project} (${argv.releaseChannel})...`
375 - )
376 - );
376 + // Print the release channel and project we're running for quick confirmation.
377 + console.log(
378 + chalk.blue(
379 + `\nRunning tests for ${argv.project} (${argv.releaseChannel})...`
380 + )
381 + );
382 + }
383
384 // Print a message that the debugger is starting just
385 // for some extra feedback when running the debugger.