-
Notifications
You must be signed in to change notification settings - Fork 31.2k
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-runner: run tests as soon as find them #48584
Conversation
Review requested:
|
337a2ac
to
1d80a2b
Compare
async readdir(path) { | ||
const cached = this.#readdirCache.get(path); | ||
if (cached) { | ||
return cached; | ||
} | ||
let val; | ||
try { | ||
val = await readdir(path, { __proto__: null, withFileTypes: true }); | ||
} catch { | ||
val = []; | ||
} | ||
this.#readdirCache.set(path, val); |
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 the goal is to streamline the process of finding test files, shouldn't we be using opendir
rather than readdir
?
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.
thanks, I need to check how I can insert it here, I did not change the logic...
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.
+1 for opendir
@@ -14,7 +14,7 @@ const testFixtures = fixtures.path('test-runner'); | |||
|
|||
assert.strictEqual(child.status, 1); | |||
assert.strictEqual(child.signal, null); | |||
assert.strictEqual(child.stdout.toString(), ''); | |||
assert.strictEqual(child.stdout.toString(), 'TAP version 13\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.
as we first start running and then check as we get the files asynchronously
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 should not be outputed if no test files are fond. we should emit the start event only at the first test
lib/internal/test_runner/runner.js
Outdated
// TODO - find better way to check if promise | ||
if (typeof testFiles.then === 'function') { |
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 it's not a promise, it's an array, right? could this check be inverted, so it can use IsArray, and then PromisePrototypeThen can be used unconditionally, and if it's not a promise, it'll throw?
(or if it's not an array and i'm just confused because it has .map
, presumably there's another way to check whatever it is)
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.
files
can be array when provided by the user
it can be:
- array: when provided by the user
- stream: when we find the tests
- promise: when we find the tests but we are in watch mode
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.
ok, so IsArray works for array, and surely we have a way to brand check node's own streams?
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.
do we need to? checked array and promise...
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.
right, but there isn't a brand check for Promise, and this TODO comment references it.
Therefore, if you flip the conditions so you check the two other options, then you can just assume it's a promise.
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.
gotcha, thanks
on another note, is there a way not to get a bazillion emails when the build cancels due to a new commit being pushed? it's really annoying!
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 the common interface should be anything that is async iterable. (arrays are, so are readable streams, so only watch mode needs to be adjusted to use an async iterable - that should not be hard since it uses an event emitter)
Co-authored-by: Jordan Harband <[email protected]>
Co-authored-by: Jordan Harband <[email protected]>
… into run-tests-as-soon-as-get-a-file # Conflicts: # lib/internal/test_runner/runner.js
// Overriding testFiles so we won't try to consume again the stream | ||
testFiles = ArrayIsArray(testFiles) ? testFiles : testFiles.toArray(); | ||
|
||
// TODO - should not pass a promise |
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.
Any idea how can I avoid passing promise? as the tests need to have the filesWatcher
, should I just mark the run
function as async
and await it normally?
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.
testFiles
should probably just be async iterable
|
||
if (isNodeStream(testFiles)) { | ||
return testFiles | ||
.map(runSingleFile, { __proto__: null, signal, concurrency: NumberMAX_SAFE_INTEGER }) |
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.
used this concurrency to not wait for tests otherwise tests that not finish not allow us to run other tests, and this is also to keep the behavior of AllSettled...
will be changed to Infinity
once the below PR is merged:
@@ -152,7 +152,7 @@ function setup(root) { | |||
|
|||
const terminationHandler = async () => { | |||
await exitHandler(); | |||
process.exit(); | |||
process.exit(1); |
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.
changed to 1
as otherwise this test failed:
assert.strictEqual(code, 1); |
the exit code is equal to 0 instead of 1
weird it worked before...
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 feel strongly like this should not be changed
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 agree, changed it here until I fix the rest of the things
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.
needed to change this file as the order of the tests file are not sorted anymore
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.
There is a lot going on in this PR.
I suggest to break out pieces to make it easier to review and test,
for example make globSync
use Symbol.Iterator
can be split out
@@ -376,6 +396,238 @@ class Glob { | |||
} | |||
} | |||
} | |||
|
|||
async *#addSubpatterns(path, pattern) { |
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.
we should try to avoid this code duplication, perhaps extracting logic to common methods will allow that
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.
extracted in:
Why do you think it's harder to implement that way? we can get all files in that case like we do in watch mode... Also, sharding and randomization isn't the common case IMO |
I am Just saying there are many cases whre this optimization will not work with that it might be an overkill, since the gain isnt vert big anyway |
Is this still being worked on or can it be closed? |
Depending on what @MoLow thinks, I implemented sharding and this should not affect that It is just like watch - precomputing the file list (which will be the same as randomization tests) |
I am not blocking this - but it is probably a breaking change since tests wont run in the same order anymore |
I'm going to close this for now since it doesn't appear to be progressing. |
currently find the tests files to run and then run them, this runs the tests as soon as finding them
Following our conversation in NodeTLV 2023:
Cc @MoLow @cjihrig
this is still WIP, just want the CI to run and general feedback
TODOs: