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

Removing the mapCoverage condition on reading inlineSourceMaps. #5177

Merged
merged 9 commits into from
Feb 15, 2018

Conversation

Aftabnack
Copy link
Contributor

Summary

Test plan

@codecov-io
Copy link

codecov-io commented Dec 25, 2017

Codecov Report

Merging #5177 into master will decrease coverage by 1.09%.
The diff coverage is 92%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    #5177     +/-   ##
=========================================
- Coverage   61.72%   60.63%   -1.1%     
=========================================
  Files         213      213             
  Lines        7170     7311    +141     
  Branches        4        3      -1     
=========================================
+ Hits         4426     4433      +7     
- Misses       2743     2877    +134     
  Partials        1        1
Impacted Files Coverage Δ
packages/jest-config/src/defaults.js 100% <ø> (ø) ⬆️
packages/jest-jasmine2/src/index.js 5.47% <ø> (ø) ⬆️
packages/jest-config/src/valid_config.js 100% <ø> (ø) ⬆️
packages/jest-cli/src/generate_empty_coverage.js 85.71% <ø> (ø) ⬆️
packages/jest-config/src/index.js 25.92% <ø> (ø) ⬆️
packages/jest-runner/src/run_test.js 2.22% <0%> (ø) ⬆️
packages/jest-config/src/deprecated.js 57.14% <100%> (-9.53%) ⬇️
packages/jest-runtime/src/index.js 73.55% <100%> (-0.45%) ⬇️
packages/jest-runtime/src/script_transformer.js 85.38% <100%> (+0.85%) ⬆️
...n-tests/coverage-transform-instrumented/covered.js 100% <100%> (ø)
... and 34 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d065e87...520a141. Read the comment docs.

@SimenB
Copy link
Member

SimenB commented Dec 25, 2017

Interesting, nice find!

I think we also want to revert the changes in the snapshot in #5117 as well.

Adding an integration test showing that the coverage is mapped correctly in a stack would be great. So not just testing the .map file, but the mapping as well

@Aftabnack
Copy link
Contributor Author

I think, I might need some pointers adding the integration tests. Is there an example I can look at?

PS: I will do this in the morning. It's night time here! :P

@Aftabnack
Copy link
Contributor Author

@SimenB
Copy link
Member

SimenB commented Dec 26, 2017

Hmm, I wonder if the correct fix is to pass mapCoverage from the skipped test. Looking at its docs it's a way to disable source maps in order to increase performance.

Do you agree?

I think I'll have to dig a bit deeper into how sourcemaps work and how they're merged

@Aftabnack
Copy link
Contributor Author

But what doesn't make sense is the mapCoverage option seems to affect only inline source maps. The Boolean is used only at the place where inline sourcemaps are attempted to be parsed.

If we have to stick to it's intended usage mentioned in docs, we should enforce mapCoverage on all sourcemaps, which would mean nullifying map emitted from preprocessors.

I'm strongly against that, since the coverage remapping will be messed up, the coverage annotations will be all wrong.

@jwbay
Copy link
Contributor

jwbay commented Dec 28, 2017

Hi 👋 I implemented the initial source map support for Jest, so I think I can provide some context.

  1. It was added in Map code coverage from transformers #2290 to support code coverage remapping
  2. Some checks were removed in Sourcemaps #3458 to support stack trace remapping
  3. That last one was reverted in fix(jest-runtime): only write map files to disk when mapCoverage: true #5117

And I think that brings us to this PR.

I think the integration test snapshot should definitely stay reverted. It shouldn't have changed in #3458. I haven't checked, but the line/column numbers in that snapshot map directly to the visual alignment of covered code in the HTML report, so if they changed things probably broke. I can't think of a good way to keep that from happening again in the future.

The mapCoverage option used to affect more than inline source maps. It used to null out the map property on the transform result when it was false, whether it was populated via a separate map or an inline source map. You can find that in the initial source map PR: https://github.com/facebook/jest/pull/2290/files#diff-7de44d08766eddcf4bca597034b5b4c2R314

To be clear, mapCoverage was added and defaulted to false to prevent silent performance regressions for the case where people with large projects had a transformer set up that happened to return inline source maps.

"jest": {
"rootDir": "./",
"transform": {
"^.+\\.(js)$": "babel-jest"
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this test is valuable currently because babel-jest doesn't deal with source maps. It instruments and then transforms, so there's no coverage remapping necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Doesn't it emit inline sourcemaps? Here Which are then read?

Copy link
Member

@SimenB SimenB Jan 16, 2018

Choose a reason for hiding this comment

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

I'd also like to better understand this 🙂

Copy link
Member

Choose a reason for hiding this comment

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

FWIW, inline sourcemaps is pretty recent: #3738

Copy link
Contributor

@jwbay jwbay Jan 20, 2018

Choose a reason for hiding this comment

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

Since mapCoverage is not passed in this integration test (which is correct*), no remapping should be performed here. I'm not positive, but I would expect this integration test to pass with the same output on master. Since the main purpose of this PR, as I understand it, is accurate line/col numbers for error stacktraces and codeframes, maybe the integration test should try to cover one of those use cases.

* If a transformer instruments before doing downlevel compilation (as babel-jest does), any sort of source map processing for coverage is probably going to break things. Source map processing for coverage only makes sense when going the other direction (downlevel compilation, then instrumentation)

Edit: I see mapCoverage is being passed after all. I'm curious what the HTML report looks like

transformed.map = inlineSourceMap.toJSON();
}
if (!transformed.map) {
const inlineSourceMap = convertSourceMap.fromSource(transformed.code);
Copy link
Contributor

@jwbay jwbay Dec 28, 2017

Choose a reason for hiding this comment

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

This is where performance issues may surface with this unguarded. convertSourceMap.fromSource looks for inline source maps in code files with a regex (src). For sufficiently huge source files, this can freeze node (ex: babel/babel#5081). It depends on the regex as well as file size, I think.

I don't have a good answer here. Some tests are probably in order; it may not be a problem. Or we may need a new sourceMaps option or something. Or we could kill inline source map support and required a separate code/map pair always.

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 hadn't looked into the source code of convert-source-map. I'm okay with using mapCoverage to guard against this. But like it was in the original PR, it should be nullifying the explicit sourcemaps emitted from preprocessors.

Also as a user of Jest, I would want it to come with sensible defaults, IMO defaulting map coverage to true, adding a caveat that this should be set to false in case you are facing some freeze issue is better than defaulting to false. Cuz more often than not, it will work and is incredibly important.

Copy link
Member

@SimenB SimenB Jan 16, 2018

Choose a reason for hiding this comment

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

Is mapCoverage used anymore with this changeset. Also, if we combine this with #5257 at least it wouldn't hit the default babel-jest configuration

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With this change, inline sourceMaps emitted from the default babel-jest will be read. #5257 may not be necessary.

Copy link
Member

Choose a reason for hiding this comment

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

The point is that inline sourcempas are way slower than just using the returned sourcemap.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. I'm actually leaning towards removing inline-source-map support. But I don't know the ramifications of it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Inline source map support helps when debugging tests. VS Code at least tends to behave better when everything it needs is in script it's executing.

@@ -261,7 +259,7 @@ export default class ScriptTransformer {
code = transformed.code;
}

if (instrument && mapCoverage && transformed.map) {
if (instrument && transformed.map) {
Copy link
Contributor

Choose a reason for hiding this comment

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

For proper stack trace support, the instrument check should probably be killed as well. Test files are (almost) never instrumented, so line numbers in stacktraces for errors won't be fully correct otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. If map is there save it, otherwise don't.

Copy link
Member

Choose a reason for hiding this comment

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

Can you remove instrument?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

@Aftabnack
Copy link
Contributor Author

Also what do you think about stripping out the inline sourcemaps before caching the actual code file.? I think it's important we do that, we can cut down the amount of cache space we are taking by almost half for inline sourcemaps. 😉

@lightsofapollo
Copy link

Looking forward to this landing!

@SimenB
Copy link
Member

SimenB commented Jan 16, 2018

@jwbay thanks for chiming in!

Are we able to test this against a real project and check that it works correctly?

@Aftabnack Please update the changelog as well 🙂

@Aftabnack
Copy link
Contributor Author

@SimenB Updated the changelog.

Also added this comment:
https://github.com/Aftabnack/jest/blob/24d822848f576554e8f2ce99ef0bcac76ad0b2fe/packages/jest-runtime/src/script_transformer.js#L246-L247

I don't know of any big projects where this could be tried.

@SimenB
Copy link
Member

SimenB commented Jan 16, 2018

I don't know of any big projects where this could be tried.

We can at least test against some of the repros in #5109

@Aftabnack
Copy link
Contributor Author

The repo in that issue, worked out of the box without me having to link my local jest-cli

@SimenB
Copy link
Member

SimenB commented Jan 16, 2018

It does now as we have reverted the change which broke them. Does it still work if you link in this? If any of the reproductions have lockfiles, that'd help

@Aftabnack
Copy link
Contributor Author

  • It works after linking my local jest-cli too.
  • Also the jest test-ci-partial also works in my local. On CircleCI it says timed out. Do I have to change the timeout somewhere?

@SimenB
Copy link
Member

SimenB commented Jan 16, 2018

If the tests time out with this change, I consider than an issue. I don't think we should increase the timeout, we don't want to make Jest slower

@Aftabnack
Copy link
Contributor Author

But why am I not able to see the same thing in my local.?

This is what I got when running yarn test-ci-partial

screenshot from 2018-01-16 17-18-35

@SimenB
Copy link
Member

SimenB commented Jan 16, 2018

My guess is because your machine is more powerful.

Try running with and without your change 3 times or something, is there a difference in execution time?

@Aftabnack
Copy link
Contributor Author

I'll try running on master and my branch separately 3 times.

My config is 8GB ram with 256GB SSD running on i5 processor. Wouldn't call it powerful.. 😉

@Aftabnack
Copy link
Contributor Author

This was my mistake. I didn't rebuild the packages. Testcases are actually failing. It is because we have removed the instrument check. I will re-add the instrument check and try to figure out why that is important and what it is needed for.

@Aftabnack
Copy link
Contributor Author

@SimenB Why do we save sourcemaps of test files themselves?

@SimenB
Copy link
Member

SimenB commented Jan 16, 2018

Debugging the tests themselves, including codeframe on assertion errors

@Aftabnack
Copy link
Contributor Author

After hours of debugging, I found this:

https://github.com/facebook/jest/blob/7743c0970e974bca166bff67099d28462ddb3187/packages/jest-runtime/src/index.js#L436-L447

The testcases that were failing, were because the Files that were returned in the coverage collected (getAllCoverageInfoCopy) were lesser than what was there in the sourceMaps map returned from getSourceMapInfo.

Because this was the case, when it tries to assert which file the sourceMaps belonged to, it throws since coverageCollected from the test run won't have the file in which the tets case was written; here:
https://github.com/facebook/jest/blob/7743c0970e974bca166bff67099d28462ddb3187/packages/jest-cli/src/reporters/coverage_reporter.js#L63

@Aftabnack
Copy link
Contributor Author

Aftabnack commented Jan 16, 2018

I have modified the getCoverageInfo() to accept array of filenames for which the coverage was generated, and I am returning sourceMaps for files which are present in that array.

Thoughts @SimenB ?

@Aftabnack
Copy link
Contributor Author

Upon debugging the timeout issue, I found out that the testcase is timing out when the automock is set to true in that particular testcase. I've pushed removing that to verify that was the case.

@SimenB can you help me understand how automock is related to the changes that I have done?

@Aftabnack Aftabnack deleted the fix-coverage branch February 15, 2018 18:08
termosa added a commit to termosa/vuejs-templates-webpack that referenced this pull request Feb 25, 2018
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants