Skip to content

Commit

Permalink
fix: distribute rest files over shards (#13476)
Browse files Browse the repository at this point in the history
  • Loading branch information
marionebl committed Oct 20, 2022
1 parent 57d103f commit 571c940
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,8 @@

### Fixes

- `[@jest/test-sequencer]` Make sure sharding does not produce empty groups ([#13476](https://github.com/facebook/jest/pull/13476))

### Chore & Maintenance

### Performance
Expand Down
Expand Up @@ -368,6 +368,23 @@ test('returns expected 100/8 shards', async () => {
);

expect(shards.map(shard => shard.length)).toEqual([
13, 13, 13, 13, 13, 13, 13, 9,
13, 13, 13, 13, 12, 12, 12, 12,
]);
});

test('returns expected 55/12 shards', async () => {
const allTests = toTests(new Array(55).fill(true).map((_, i) => `/${i}.js`));

const shards = await Promise.all(
new Array(12).fill(true).map((_, i) =>
sequencer.shard(allTests, {
shardCount: 12,
shardIndex: i + 1,
}),
),
);

expect(shards.map(shard => shard.length)).toEqual([
5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4,
]);
});
31 changes: 28 additions & 3 deletions packages/jest-test-sequencer/src/index.ts
Expand Up @@ -24,6 +24,10 @@ export type ShardOptions = {
shardCount: number;
};

type ShardPositionOptions = ShardOptions & {
suiteLength: number;
};

/**
* The TestSequencer will ultimately decide which tests should run first.
* It is responsible for storing and reading from a local cache
Expand Down Expand Up @@ -72,6 +76,19 @@ export default class TestSequencer {
return cache;
}

private _shardPosition(options: ShardPositionOptions): number {
const shardRest = options.suiteLength % options.shardCount;
const ratio = options.suiteLength / options.shardCount;

return new Array(options.shardIndex)
.fill(true)
.reduce<number>((acc, _, shardIndex) => {
const dangles = shardIndex < shardRest;
const shardSize = dangles ? Math.ceil(ratio) : Math.floor(ratio);
return acc + shardSize;
}, 0);
}

/**
* Select tests for shard requested via --shard=shardIndex/shardCount
* Sharding is applied before sorting
Expand All @@ -97,9 +114,17 @@ export default class TestSequencer {
tests: Array<Test>,
options: ShardOptions,
): Array<Test> | Promise<Array<Test>> {
const shardSize = Math.ceil(tests.length / options.shardCount);
const shardStart = shardSize * (options.shardIndex - 1);
const shardEnd = shardSize * options.shardIndex;
const shardStart = this._shardPosition({
shardCount: options.shardCount,
shardIndex: options.shardIndex - 1,
suiteLength: tests.length,
});

const shardEnd = this._shardPosition({
shardCount: options.shardCount,
shardIndex: options.shardIndex,
suiteLength: tests.length,
});

return tests
.map(test => {
Expand Down

0 comments on commit 571c940

Please sign in to comment.