Skip to content
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: switch to native v8 coverage #25157

Closed
wants to merge 1 commit into from
Closed

Conversation

bcoe
Copy link
Contributor

@bcoe bcoe commented Dec 21, 2018

Switches to using v8's built in coverage support.

Note: these results will get better once https://chromium-review.googlesource.com/c/v8/v8/+/1339119 is landed.

CC: @schuay, @hashseed we're almost over the finish line \o/

TODO:

  • update documentation on how to run coverage.
Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@bcoe bcoe requested a review from mhdawson December 21, 2018 01:35
@nodejs-github-bot nodejs-github-bot added the build Issues and PRs related to build files or the CI. label Dec 21, 2018
@bcoe bcoe requested a review from addaleax December 21, 2018 01:40
@bcoe
Copy link
Contributor Author

bcoe commented Dec 21, 2018

@mhdawson I note that cctest is commented out currently in the make file, is this a known issue?

@bcoe
Copy link
Contributor Author

bcoe commented Dec 31, 2018

@mhdawson @schuay I've finally been able to test our work on v8, here are some findings:

  1. tests run about 24% slower for the entire Node.js test suite; it feels like it might be worth moving some of our work into Torque (see if we can get this a bit better) but I believe that the historical approach ran closer to 100% slower.
  • tldr; I think the current approach is better, but performance improvements would certainly be good for the community.
  1. internal modules now have no wrapper, making it easy to run reports.
  2. the ends of if statements (in most cases) no longer show up as missing coverage:

screen shot 2018-12-31 at 11 10 42 am

  1. I have found one additional edge case, we do not handle throw statements -- I think this is an oversight we could correct in v8:

screen shot 2018-12-31 at 11 17 12 am

  1. coverage is looking good with the new approach, we have 95.88% coverage (very close to the instrumented coverage); only three tests fail when NODE_V8_COVERAGE is enabled (all related to code that is shared with the coverage writing logic).

screen shot 2018-12-31 at 11 19 16 am

Things are working well enough that I'd vote:

  1. we land the v8 changes in Node.js.
  2. update documentation.
  3. switch our approach to coverage.

@nodejs/build 👆

@hashseed
Copy link
Member

The throw case should be handled just like a return as last statement.

@mhdawson
Copy link
Member

mhdawson commented Jan 4, 2019

Lets get a CI job running which uses the new approach to validate and then plan the steps to land the PRs to enable in core. @bcoe let's try to catch up on Monday to work on the CI job,

@bcoe bcoe changed the title [WIP] test: switch to native v8 coverage test: switch to native v8 coverage Jan 5, 2019
@bcoe bcoe added the c++ Issues and PRs that require attention from people who are familiar with C++. label Jan 5, 2019
Copy link
Contributor Author

@bcoe bcoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mhdawson 👍 I think this is pretty much ready to go, I've been playing a bit of whack a mole with a few edge-case tests, but the vast majority run effectively under test.

Makefile Outdated Show resolved Hide resolved
@@ -69,6 +69,7 @@ static void EnvSetter(Local<Name> property,
Environment* env = Environment::GetCurrent(info);
if (env->options()->pending_deprecation && env->EmitProcessEnvWarning() &&
!value->IsString() && !value->IsNumber() && !value->IsBoolean()) {
env->SetEmitProcessEnvWarning(true);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EmitProcessEnvWarning has the side effect of setting emit_env_nonstring_warning_ = false; which I believe shouldn't be set unless a warning has actually been emitted?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would this be necessary? Does c8 use the the process.env setter in the deprecated way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joyeecheung I'll dig a bit further, I don't believe that coverage.js is setting process.env incorrectly (c8 doesn't come into play until the reporting step). It just seemed like setting the environment variable in internal/process/coverage.js was suppressing the warning message generated by the unit test.

@bcoe bcoe added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. test Issues and PRs related to the tests. labels Jan 5, 2019
@mhdawson
Copy link
Member

mhdawson commented Jan 7, 2019

@bcoe working on a job here to test it out: https://ci.nodejs.org/view/All/job/node-test-commit-linux-coverage-new

@addaleax
Copy link
Member

addaleax commented Jan 7, 2019

@bcoe Nice! I think this is ready for merging?

@bcoe
Copy link
Contributor Author

bcoe commented Jan 7, 2019

@addaleax I thought of a slightly less invasive patch to correct the one test that was failing, I'll get this checked in tonight; also, it would be good to wait for the experimenting that @mhdawson is doing.

@addaleax addaleax removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Jan 7, 2019
@@ -12,5 +12,9 @@ common.expectWarning(
'DEP0104'
);

// Make sure setting a valid environment variable doesn't
// result in warning being suppressed, see:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joyeecheung confirmed that this failure wasn't coverage related, setting an environment variable correctly would suppress future warnings; easy fix is simply calling env->EmitProcessEnvWarning() last.

Copy link
Member

@joyeecheung joyeecheung Jan 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change relevant to this PR (making a switch in coverage)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turning on coverage surfaced this bug, and made this test not run if coverage was enabled. I figured it was an innocent enough change that it was worth patching; If you'd like me to break it out into another patch I can.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW: After this PR will the test suite in make coverage pass (RE: #25543 (comment))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack not quite, there are a couple addon tests that fail; I think related to the inspector session creating resources that break a few assertions.

I would be happy to help isolate these, and maybe we could use TEST_TO_SKIP_FOR_COVERAGE to remove them, then maybe we could get to the point where @mhdawson and I can abort on failure for coverage tests?

Would folks be okay with keeping this patch in, if @mhdawson and I work on making this pull request run coverage without ignoring errors?

@bcoe bcoe force-pushed the native-coverage branch 2 times, most recently from 39c3179 to 5730abd Compare January 9, 2019 01:52
@mhdawson
Copy link
Member

mhdawson commented Jan 9, 2019

Latest CI run (new job to test out) ran ok, and generated coverage results and artifacts.

I do see that some of the end brackets are not covered (already mentioned by @bcoe ).

A few other things I've noticed so far:

  • It shows significantly less branch coverage. For example in internal/crypto/random.js.html it shows additions lines (for example 64x return offset >>> 0; // Convert to uint32. not being covered. For the file it reports 76.36% as opposed to 93.02%. It shows 42/55 branches but I only see 5 highlighted (including the ones not highlighted by the existing reports) as opposed to 13 reported as not covered.
  • the path shows with lib instead of root, which is an improvement :). For example: / lib/internal/crypto random.js instead of / root/internal/crypto random.js

@mhdawson
Copy link
Member

mhdawson commented Jan 9, 2019

Also noticed it does not show coverage as missing in:

/lib/internal/fs/utils.js.html

It shows these 2 paths as being covered, where as the existing report does not.

if (throwError) {
    Error.stackTraceLimit = 0;
  }
  const err = new ERR_INVALID_ARG_VALUE(
    propName,
    path,
    'must be a string or Uint8Array without null bytes'
  );
 
 if (throwError) {
    Error.stackTraceLimit = tmpLimit;
    Error.captureStackTrace(err, nullCheck);
    throw err;
  }
  return err;

BUILDING.md Outdated
Alternatively, for the JavaScript test suite, it's faster to run:

```text
$ CI_JS_SUITES=fs-mkdir CI_NATIVE_SUITES= make jscov
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: A note about unsetting CI_NATIVE_SUITES would help the readers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps:

Note: CI_NATIVE_SUITES is unset, ensuring that the fs-mkdir tests are the only tests executed, otherwise the default suite of native tests will also be run.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that makes it crystal clear 🙂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should recommend the use of CI_* variables to the public. AFAICT they are meant for internal use by our CI systems, and should be considered "private".

Copy link
Contributor Author

@bcoe bcoe Jan 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack we reference this variable earlier in the document already:

CI_JS_SUITES=child-process CI_NATIVE_SUITES= make coverage

and it's a nice way to kick off a partial suite of tests with coverage, which is somewhat involved:

  1. you need to set the NODE_V8_COVERAGE variable to the appropriate path.
  2. you need to know to run make js-coverage-report.

Long story short I'd like to expose something like this behavior to users, open to alternate suggestions for implementation.

Makefile Outdated
coverage-build-js:
mkdir -p node_modules
if [ ! -d node_modules/c8 ]; then \
$(NODE) ./deps/npm install c8@next --no-save --no-package-lock; fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can we have fi in a new line?

@@ -72,8 +72,9 @@ static void EnvSetter(Local<Name> property,
Local<Value> value,
const PropertyCallbackInfo<Value>& info) {
Environment* env = Environment::GetCurrent(info);
if (env->options()->pending_deprecation && env->EmitProcessEnvWarning() &&
!value->IsString() && !value->IsNumber() && !value->IsBoolean()) {
if (env->options()->pending_deprecation && !value->IsString() &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment indicating EmitProcessEnvWarning should be called at the end would help future readers and refactorings.

Makefile Outdated
$(MAKE) coverage-build-js
-NODE_V8_COVERAGE=out/$(BUILDTYPE)/.coverage \
CI_SKIP_TESTS=core_line_numbers.js,testFinalizer.js,test_function/test.js \
$(MAKE) jstest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This could be aligned with the previous line, right?

-NODE_V8_COVERAGE=out/$(BUILDTYPE)/.coverage \
CI_SKIP_TESTS=core_line_numbers.js,testFinalizer.js,test_function/test.js \
$(MAKE) jstest
$(MAKE) coverage-report-js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just trying to understand this better. Even if the previous command fails, does it make sense to run this command?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mhdawson and I are having a discussion around this right now -- currently (and I believe historically) there are a small minority of tests that fail when under coverage, and we've simply opted to not fail when running under coverage and still run reports.

If we start failing the coverage test suite on failures, we'll need top explicitly exclude a few tests, and be more diligent about not introducing new tests that fail under coverage going forward.

Copy link
Contributor Author

@bcoe bcoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thefourtheye I think I've addressed your review.

@mhdawson I've rebased this with the back ported v8 changes, and am quite happy with how things are looking; you should be able to run your coverage tests against this pull now.

Coverage tests failing should no longer break coverage report outputting -- going forward, I can certainly get onboard with the argument that we should fail tests, maybe instead of reporting on failure, we should identify the specific tests that fail and add them to an ignore list?

-NODE_V8_COVERAGE=out/$(BUILDTYPE)/.coverage \
CI_SKIP_TESTS=core_line_numbers.js,testFinalizer.js,test_function/test.js \
$(MAKE) jstest
$(MAKE) coverage-report-js
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mhdawson and I are having a discussion around this right now -- currently (and I believe historically) there are a small minority of tests that fail when under coverage, and we've simply opted to not fail when running under coverage and still run reports.

If we start failing the coverage test suite on failures, we'll need top explicitly exclude a few tests, and be more diligent about not introducing new tests that fail under coverage going forward.

@@ -12,5 +12,9 @@ common.expectWarning(
'DEP0104'
);

// Make sure setting a valid environment variable doesn't
// result in warning being suppressed, see:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turning on coverage surfaced this bug, and made this test not run if coverage was enabled. I figured it was an innocent enough change that it was worth patching; If you'd like me to break it out into another patch I can.

@bcoe
Copy link
Contributor Author

bcoe commented Jan 17, 2019

@thefourtheye
Copy link
Contributor

we should identify the specific tests that fail and add them to an ignore list?

Could it be possible that a file with a lot of tests in it fail during the coverage? If so, we can work towards breaking them down to multiple smaller tests.

Copy link
Contributor

@refack refack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some naming and semantic comments

test/parallel/test-bootstrap-modules.js Show resolved Hide resolved
@@ -12,5 +12,9 @@ common.expectWarning(
'DEP0104'
);

// Make sure setting a valid environment variable doesn't
// result in warning being suppressed, see:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW: After this PR will the test suite in make coverage pass (RE: #25543 (comment))

Makefile Outdated Show resolved Hide resolved
Makefile Show resolved Hide resolved
Makefile Outdated
$(RM) -r out/$(BUILDTYPE)/.coverage
$(MAKE) coverage-build-js
-NODE_V8_COVERAGE=out/$(BUILDTYPE)/.coverage \
CI_SKIP_TESTS=core_line_numbers.js,testFinalizer.js,test_function/test.js \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the list of tests be refactored to a new var (TEST_TO_SKIP_FOR_COVERAGE)? and D.R.Y. L307?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could use TEST_TO_SKIP_FOR_COVERAGE to isolate the tests that fail under coverage (@mhdawson?) and stop using - to suppress erros.

BUILDING.md Outdated
Alternatively, for the JavaScript test suite, it's faster to run:

```text
$ CI_JS_SUITES=fs-mkdir CI_NATIVE_SUITES= make jscov
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should recommend the use of CI_* variables to the public. AFAICT they are meant for internal use by our CI systems, and should be considered "private".

Copy link
Contributor Author

@bcoe bcoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack a few things I think we need to discuss with @mhdawson.

Makefile Outdated Show resolved Hide resolved
Makefile Outdated
$(RM) -r out/$(BUILDTYPE)/.coverage
$(MAKE) coverage-build-js
-NODE_V8_COVERAGE=out/$(BUILDTYPE)/.coverage \
CI_SKIP_TESTS=core_line_numbers.js,testFinalizer.js,test_function/test.js \
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could use TEST_TO_SKIP_FOR_COVERAGE to isolate the tests that fail under coverage (@mhdawson?) and stop using - to suppress erros.

test/parallel/test-bootstrap-modules.js Show resolved Hide resolved
@@ -12,5 +12,9 @@ common.expectWarning(
'DEP0104'
);

// Make sure setting a valid environment variable doesn't
// result in warning being suppressed, see:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack not quite, there are a couple addon tests that fail; I think related to the inspector session creating resources that break a few assertions.

I would be happy to help isolate these, and maybe we could use TEST_TO_SKIP_FOR_COVERAGE to remove them, then maybe we could get to the point where @mhdawson and I can abort on failure for coverage tests?

Would folks be okay with keeping this patch in, if @mhdawson and I work on making this pull request run coverage without ignoring errors?

@mhdawson
Copy link
Member

We have chosen to allow failing tests when run with coverage. With unlimited resources, we would fix that. I'd be concerned with the ongoing maintenance (for those keeping coverage going) as well as showing things that are covered as not-covered that we'd get from excluding tests.

My personal feeling is that allowing failing tests is a reasonable balance between work/benefit but of course I'm open to other thoughts.

@mhdawson
Copy link
Member

Coverage CI run with all the changes - https://ci.nodejs.org/view/All/job/node-test-commit-linux-coverage-new/9/

@bcoe bcoe closed this Jan 20, 2019
@bcoe bcoe deleted the native-coverage branch January 20, 2019 22:17
@bcoe bcoe restored the native-coverage branch January 20, 2019 22:18
bcoe added a commit to bcoe/node-1 that referenced this pull request Jan 20, 2019
PR-URL: nodejs#25157
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@bcoe
Copy link
Contributor Author

bcoe commented Jan 20, 2019

Landed in d1dee49

@bcoe bcoe deleted the native-coverage branch January 20, 2019 22:21
addaleax pushed a commit that referenced this pull request Jan 23, 2019
PR-URL: #25157
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@MylesBorins MylesBorins mentioned this pull request Jan 24, 2019
jasnell pushed a commit that referenced this pull request Jul 19, 2021
Update the comments for the `coverage` Makefile target.
- Source files under `lib` are no longer instrumented since
d1dee49
- Fix the name of the related CI job.

PR-URL: #39365
Refs: #25157
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
targos pushed a commit that referenced this pull request Jul 20, 2021
Update the comments for the `coverage` Makefile target.
- Source files under `lib` are no longer instrumented since
d1dee49
- Fix the name of the related CI job.

PR-URL: #39365
Refs: #25157
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
BethGriggs pushed a commit that referenced this pull request Jul 29, 2021
Update the comments for the `coverage` Makefile target.
- Source files under `lib` are no longer instrumented since
d1dee49
- Fix the name of the related CI job.

PR-URL: #39365
Refs: #25157
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
targos pushed a commit that referenced this pull request Sep 4, 2021
Update the comments for the `coverage` Makefile target.
- Source files under `lib` are no longer instrumented since
d1dee49
- Fix the name of the related CI job.

PR-URL: #39365
Refs: #25157
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Issues and PRs related to build files or the CI. c++ Issues and PRs that require attention from people who are familiar with C++. test Issues and PRs related to the tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants