-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
test: Run node integration tests in isolation #5721
Conversation
c90e3bd
to
dd5fe3f
Compare
|
||
const threads = os.cpus().map(async (_, i) => { | ||
let testPath = testPaths.pop(); | ||
while (testPath !== undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not a .forEach
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If by forEach
you mean iterating over the jobs - I didn't do that because a) I don't want to overload the host machine by instantly starting a bazillion of processes, b) I wanted to distribute the jobs among the workers evenly, i.e. by popping another job off the queue when they're done with their current one. I honestly wouldn't know how to do that with forEach
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had in my head to just split the tests by cpus beforehand and then sync iterate, but the producer - consumer pattern you have here is way more effective, I just didn't think it through.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nicely done!
Perhaps at some point we can apply the same logic to places where we run jest with --runInBand
.
import childProcess from 'child_process'; | ||
import os from 'os'; | ||
|
||
const testPaths = childProcess.execSync('jest --listTests', { encoding: 'utf8' }).trim().split('\n'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think having an explanation here is both helpful in its own right and possibly a way to forestall other folks asking the same question Abhi asked about foreEach
.
const testPaths = childProcess.execSync('jest --listTests', { encoding: 'utf8' }).trim().split('\n'); | |
// This will serve as a pool of remaining tests from which the threads spawned below can draw | |
const testPaths = childProcess.execSync('jest --listTests', { encoding: 'utf8' }).trim().split('\n'); |
Also:
jest --listTests
TIL! 🙂
const numTests = testPaths.length; | ||
const fails: string[] = []; | ||
|
||
const threads = os.cpus().map(async (_, i) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I think this makes it slightly clearer that two things are really happening, thread creation and thread use.
const threads = os.cpus().map(async (_, i) => { | |
const threads = os.cpus() | |
threads.map(async (_, i) => { |
let output = ''; | ||
|
||
jestProcess.stdout.on('data', (data: Buffer) => { | ||
output = output + data.toString(); | ||
}); | ||
|
||
jestProcess.stderr.on('data', (data: Buffer) => { | ||
output = output + data.toString(); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you doing it this way (rather than just setting stdio
to inherit
in your spawn
options) so that the output from each test is printed in a single block, rather than being interleaved with output from the other running tests? If so, a) good thinking!, and b) I think a comment saying so would be helpful.
Since even after merging #5715 I have trouble with the global context being shared across tests we should definitely isolate the individual node integration tests before something slips though because of it.
This PR adds a quick and dirty script that runs all the test files with an individual
jest
command. It doesn't do anything fancy except for creating a worker sharing work for each CPU core available.Also removes the
portfinder
package from the integration tests as it was a bit inconsistent - we now let the OS choose a port on its own.This PR admittedly doesn't contain a lot of effort but was done to unblock #5710