benchmark: add initial support for benchmark coverage #54333
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hey,
I'm opening it as a draft as there are a lot of loose ends to solve before considering such usage. This is an experiment related to research I'm conducting.
The idea is to generate a benchmark coverage for all of our exported modules. For instance, check if the functions exposed by
require('node:fs')
are covered in our benchmark suite (benchmark/fs/*.js
). To achieve an intermediary goal I had to monkey-patch theModule.prototype.require
before executing each benchmark (we run each one in a separate process) to return a singleton that basically manages the state of how many times that function was called.I have tried to use our
test_runner
coverage for that, but it couldn't identify the location of built-in modules (require('node:*')
) which is expected by the nature of a coverage tool. The other reason it didn't fit was the need to cover only the exported modules, not thelib/internal/*
functions. The result I wanted to have was: "I need to know which functions/classes that are exposed to users do not contain a benchmark".It's also worth it to mention that, a nested call is ignored in the benchmark report. Example:
fs.exists
callsfs.access
behind the scenesnode/lib/fs.js
Line 260 in b8a2550
fs.exists
andfs.access
as "covered" in the benchmark report. It should only countfs.exists
as covered.benchmark/**/*.js
Results
Full result: https://gist.github.com/RafaelGSS/66d33091560d61932b26d74af2fa8b82
Current limitations
coverage.js
to set up the monkey patch ofModule.require
(-r ./coverage.js
). However, any benchmark setup would impact the report. For instance:This will result in:
fs.existsSync
status "covered"fs.readdir
status "covered"This is unfortunate, as in reality only
fs.existsSync
is being measured. One theory that came to my mind to fix that is to intercept thebench.start
calls and only then return the patched modules. I might try it later.typeof require('node:assert') === 'function'
. This also means that classes such asAsyncLocalStorage
(or function classes) aren't covered as the constructor (called withnew ..
) isn't patched. I think usingProxy
might solve it, but I haven't tested yet.I'm certain there's a better way to approach this goal and fix the limitations. Hence, I'm opening it as a draft.
cc: @nodejs/benchmarking @nodejs/test_runner @lemire