-
-
Notifications
You must be signed in to change notification settings - Fork 12
Newer NodeJS Source Files for Specs #42
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
Conversation
This will be used for fetching NodeJS source and headers, and other related files, which are used for running certain tests having to do with building native C/C++ modules. (Updating the version of Node's source/headers we build against in the tests has proven necessary from time to time, for reasons that aren't entirely clear. It seems most likely to me that `node-gyp` has trouble running on a recent NodeJS version but building against a much older Node version, perhaps due to subtle changes in Node over time, and due to assumptions made in node-gyp that the running version of Node will have similar properties to the target version of Node, with those assumptions failing to anticipate the actual scope of changes made to newer Node compared to older versions?) So, we do have to update these source/header files every do often. Newer NodeJS versions are getting bigger and bigger, to the point where checking in all the necessary files would amount to over 100 megabytes, and potentially triple the bandwitdth/disk space needed to clone this repository. And it would be at least as bad all over again if we even needed to bump these files to even newer Node later on. To this day, one of the largest contributors to this repo's size was the bump to Node v10.20.1 I did over a year ago. Small text files compress incredibly efficiently, whereas binary files don't compress anywhere near as well (like Node's source tarballs, for example). GitHub also warns when you upload files over 50 megabytes, whereas some of these tarballs are closer to 70 or 80 megabytes now. So, this script ensures we can fetch & populate the files into this repo's spec/fixtures dir just before running the tests. If you've already run it once, this script will simply check the cryptographic hashes of the files, to make sure they were downloaded correctly. If the hash is incorrect, it will attempt to redownload at most once per already-existing file before giving up. This should do a reasonable job at ensuring we reliably have these files, without having to check them in to the repo in git, and without wasting a lot of bandwidth and disk space for a simple clone of this repo. (Git submodules were another option, but their tooling is somewhat clunky in my opinion, and it would just be punting the "really large files" problem to somewhere else on GitHub. I think it's much better to simply fetch these large files off the web as-needed, and make some attempt to cache them/keep them around afterward, rather than checking them in to any sort of main git repo or submodule repo. So that's what this script does instead -- fetch files from the web.)
Runs the new script to make sure we have the needed node source files (used by certain tests having to do with building native C/C++ modules), before tests start. (These source files will be needed for the tests to pass once the old, checked-in source files are deleted, and we switch to newer ones that will be fetched on-demand from nodejs.org on the web.) (The new files are too big to check in without bloating the repository and causing a warning from GitHub -- some of the files are over 50MB.) This commit also mildly re-factors the `test` script to break out the `specs` into their own sub-script. Makes it easier to read the shorter `test` script on one line. Also makes it so you can quickly re-run the specs if you already have the repo prepared and the .coffee files haven't been updated.
These new fixture source files are *not* meant to be checked in. They should be fetched on-demand and cached/re-downloaded as needed. (These source files are becoming way too big to check in to git each time we need to update them to a newer Node version. They get bigger with each Node version, as NodeJS continues to add new features.)
Use the new fixture files under 'spec/fixtures/node-source'. (These files are set up to be automatically fetched by the 'ensure-fixtures' script, just before the tests are run.) Also: Stop hard-coding the full NodeJS version repeatedly, several times per file. Hard-code it at most once per file, and make use of string interpolation to fill it in throughout the file. (We could perhaps hard-code this fixture version just once in a config file, and read it from there. But I didn't do that, for now.)
We are using the newer NodeJS source fixture files under 'spec/fixtures/node-source' now, so we can get rid of the old ones.
Should improve reliability and speed for these tests in CI, as well as reducing our bandwidth usage from the NodeJS.org servers.
|
This comment ended up being long also, bold stuff is for skimming. While I'm pretty confident this PR works as it should, I would note in particular that the code style of the new JS script I wrote for this PR was not linted. I don't really have any strong opinions on it, but would be willing to accept any wisdom/suggestions for changes. For example: I would be willing to run (Codacy seems pretty unhappy about it, but a lot of that is it doesn't like single quotes (Note: You can do I put a lot of comments in the new script file, so I hope it is easy to quickly get a handle of what the new script is doing. Which reminds me, one more thing. The script I wrote has a kind of ridiculously long and verbose filename. I would be open to shortening that filename if people want it to not be quite so long. |
Spiker985
left a comment
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 have spent far too long transposing most of the Codacy suggestions
|
It's amazing to see all passing CI here, and know that our lives will be easier in the future, to have to avoid this exact thing in the next couple years. Of wondering what we did all that time ago to fix it. So this is looking great from the commits and summary, but I'll review the actual source in a moment here. Otherwise I personally love the long descriptions, especially the history I keep finding out about Atom as it was created with them. Additionally I appreciate @Spiker985 added all the Codacy suggestions, but do want to note, these shouldn't be taken as law. They can be great suggestions, but this Codacy instance on PPM is basically the default. I haven't spent the same amount of time tweaking it as I did on Pulsar, so if a suggestion feels unnecessary, it just might be. Specifically about But I'll create an issue to keep a reminder to myself to fine tune these Codacy rules in the future to avoid any confusion. |
|
Yeah, the primary reason I went through the effort of transposing them was simply that there were mixed cases of ', ", and ` So I at least transposed the ' -> " rules so there would only be " and ` |
b33caab to
5ac1ba7
Compare
00bd481 to
4d68839
Compare
|
Hi folks, I made some changes, and this is ready for review again! IndentationAll but one of the remaining Codacy suggestions are "indentation level" suggestions from suggested diff from
|
|
So, having thoroughly bikeshedded the JS style... I'm still open to that I suppose, but the more meaningful feedback would be: On this branch, has anyone tested the new code?
So if anyone wants to test, or any additional comments on the new JS script, that'd be great. Otherwise if it's all looking good, I'm looking for an approve to merge this. Thanks everyone. Best Regards, |
(Thank you Spiker985 for implementing most of these.) * lint: Codacy suggestion: File needs no shebang * lint: Codacy suggestion: Single quote -> Double quote * lint: Codacy suggestion: End semicolon * lint: Codacy suggestion: Expand object declaration for legibility * lint: Codacy Suggestion: Add spaces to object declarations for better legibility * Apply style suggestion from @Spiker985 Personal Suggestion: Template strings are always much nicer than concatenating * Apply template literal fix from @confused-Techie * lint: Fix one more instance of single-quotes * lint: Update function declaration code style No space between function name and args * lint: Add missing semicolon * script: Remove unused argument in function Per Codacy suggestion. Co-authored-by: Spiker985 <7829451+Spiker985@users.noreply.github.com> Co-authored-by: confused_techie <dev@lhbasics.com>
7895404 to
1377150
Compare
|
I just squashed the 11 lint commits into one. We don't need all those separate in the repo's history, IMO. If anyone needs to see all the individual lint commits for whatever reason, they are still around in the git objects here: commits/ I'd like to merge this ~within the next week if there are no outright objections. (The old "Changes requested" review of this is outdated and has already been addressed. Not sure why it's still showing, but who knows?) |
confused-Techie
left a comment
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.
Overall this looks fantastic!
I've left a couple notes about nice to haves, or in general comments on the code, but otherwise I'd be happy to merge as is.
Especially love your liberal use of declaring variables to contain node versions, rather than the madness of having it declared a dozen times across files.
The biggest concern here is this would need work to be redone on some of the Spec PR's which like we discussed I'm just now trying to finally get a handle on. So would be rough to ask them to redo the work, but if this is a needed fix then we do what we have to, otherwise if I were to set a strict deadline for myself on reviewing and merging those, would you be comfortable merging this after and making the needed changes to have this work on the decaffed spec?
Feel free to let me know your thoughts, but again overall super rad work
| // for the new files and update them here to match the new files. | ||
|
|
||
| const sourceFixtureDir = path.resolve(__dirname, "..", "spec", "fixtures", "node-source"); | ||
| fs.mkdirSync(sourceFixtureDir, { recursive: true }); |
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 personally would wrap this in a try...catch block just to ensure we are aware of a failure and can fail gracefully.
Otherwise as this is a simple script file we may not want to fail gracefully, and in that case feel free to leave as 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.
At least for the case of the path already existing, recursive: true makes it so no error is raised for that case.
It's inspired by how certain recursive Unix commands (cp, rm, etc.) don't raise certain errors when you run with --recursive.
See: https://nodejs.org/api/fs.html#fsmkdirpath-options-callback
Calling
fs.mkdir()whenpathis a directory that exists results in an error only whenrecursiveisfalse.
If that's the only error you had in mind, then it is handled by using the recursive: true option.
Otherwise if there are other concerns, I can look at try...catch. We do need to make that dir, or the script won't work. The whole objective in this script is to download some files to that dir. But we could print something more helpful than just the bare error and then exit, I guess.
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.
An alternative to even making the dir in this script would be to commit the dir with an empty .keep file in it, so git can track the folder and we can commit the folder as already existing in the repo.
(git won't track a truly empty dir. So I guess it wants to track files and record their paths, not track dirs, per se. So I needed to either do the .keep thing and commit the dir in git, or generate the folder during this script.)
With that, we could avoid using fs.mkDirSync() in this script.
|
|
||
| // This module apparently needs to be required each time this function runs, | ||
| // or hashing multiple files in parallel can get messed up? Not sure why. | ||
| const { createHash } = require("node:crypto"); |
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'm glad you left the comment here, otherwise I was about to write up worried about unneeded resource usage.
But I've seen that before funnily enough in native modules that aren't context aware, or what's more likely is this builder works with a globally defined object (in relation to the actual module) and since NodeJS will require the same module it would likely actually retain it's state, including any global variables declared. So probably why it gets all worried about being used multiple times simultaneously.
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.
Yeah, I'm convinced there's a proper way to clear that reused state, but I tried a bunch of things and wasn't able to figure it out. I would not at all mind a fix for this that only require()s it once. But I couldn't figure it out myself, personally. All the hashes were coming out wrong starting at the second file I tried to hash, IIRC.
This is the order the files are listed in Windows' `dir` command, and the order they will be displayed when locally re-calculating all the file hashes, assuming these ever need to be updated. This also much closer matches the order the files show in Linux's `ls` command, as well as in the `shasum` command available on Linux/macOS. So in general, this should make copy-pasting the updated hashes much less confusing for whoever has to do that next.
Test against Electron v12.2.3, not Node v18.12.1. --- This commit introduces a `distUrl` variable to "script/ensure-node-source-fixture-files.js", where we can specify the Node or Electron dist URL we are grabbing our source files and headers from, and so on... and sets it to the official Electron headers/tarballs dist URL, so we can test against Electron -- particularly the Electron version that Pulsar uses. Also updates `nodeVersion` for this script and the specs to "v12.2.3". --- In effect: Test building native dummy modules against Electron 12, not Node 18, during the relevant specs.
D.R.Y. means "Don't Repeat Yourself". (See: https://en.wikipedia.org/wiki/Dont_repeat_yourself) This makes it much easier to update this value correctly, simultaneously updating the specs and script that use it. Also: Move the const declaration up and out of the beforeEach() function, so we only require config.json once per file, as opposed to multiple times in the beforeEach() function.
Read it from spec/config.json, which is the single source for this variable across the repo now.
Mmkes it much easier to understand which request resulted in an HTTP error (non-200) status code. For example, 404s or 500s. Previously, only the error status code was printed, with no indication of which request had resulted in that status code.
This is the new folder structure for the node.lib files (of various arches), which are used only on Windows. (This directory structure change apparently happened all the way back with the iojs fork (version 1.x in 2015) and carried through to NodeJS when iojs was eventually used as the basis of NodeJS 4.x and newer.) See the location of the `node.lib` files at: - https://nodejs.org/dist/v0.11.16/node.lib (old x86 path) - https://nodejs.org/dist/v0.11.16/x64/node.lib (old x64 path) ... - https://iojs.org/dist/v1.0.0/win-x64/iojs.lib (new x64 path) - https://nodejs.org/dist/v4.0.0/win-x64/node.lib (new x64 path) - https://nodejs.org/dist/v19.3.0/win-x64/node.lib (new x64 path) - https://nodejs.org/dist/v19.3.0/win-x86/node.lib (new x86 path) Since this directory structure change happened, newer node-gyp requests the files from the updated paths used by this commit, not the old paths (the ones from all the way before version 1.0 of NodeJS or Electron were ever released! ~8 years ago!) So we need to serve node-gyp's requests pointing to these new paths for the spec fixture files to actually serve their purpose, and for compilation to work on Windows in these tests (if the user hasn't already downloaded/cached them from a previous node-gyp run.) The tests still don't work on Windows right now, for unknown reasons, but it does appear from my testing to have _something_ to do with native module compilation and node-gyp? It's good to be actually providing these files as are needed for those specs under Windows, regardless of other reasons for Windows- specific test failures. One less problem makes it likelier that we get everything resolved, however unlikely that may still be.
a27a733 to
662f7d5
Compare
|
I probably went overboard on the changes... And uh, sorry this is so long, bolded the important bits.
I guess I just had too much freedom here and went a little wild waiting for this to have the right moment to be merged. Let me know if this is too much to review right now and I'll break it off into a follow-up PR, since the stuff that was there was also working. These are nice improvements, IMO, but I don't want to overburden reviewers. Also: I already got an approve on the prior design, so I am willing to YOLO merge (as in, without a reviewer) these additional changes at some point if it goes a while longer and there are no objections, when the timing is right vis-a-vis decaf work, and I'll be available for any questions/complaints/reverts anyone wants. |
|
(Also, I am starting to be inclined to remove |
|
IMPORTANT UPDATE: So... The Electron files are a ton smaller than Node's. NodeJS v10.20.1's This alternate implementation (see link just below) of what this PR is trying to do can check in all the relevant files for Electron v12.2.3, and have the entire spec/fixtures dir weigh in at ~2.5 MB. (Or ~1.8 MB if we give up on testing on Windows 32-bit, ~613 KB - ~1.1 MB if we give up on testing on Windows altogether.) Alternate implementation: master...DeeDeeG:ppm:alt-pr-42 as of commit 399a40f (Tangent/Reminder: The spec runner is super broken on Windows for this repo, not even outputting anything other than dots So... I think this whole effort I put in is a moot point, and we can just check in the newer Electron fixture files directly in git. No added complexity needed. They are tiny. About ~1.75 MB!!! |
confused-Techie
left a comment
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.
@DeeDeeG Lets go ahead and get this merged.
I had hoped to have the decaf PR's merged by end of week, and that has passed some time ago. So lets not hold up other fixes and improvements for decaf work.
I still do want to get to those, but may need to restructure things a bit more to assist in that process, since as is, can still be rather painful. And when that's done we will just have to work around your changes here, thanks as always.
|
Okay, thanks for touching base. But I think I may spin up a much simpler version. Reasons for the simpler version (click to expand):since the Electron headers (~ < 1mb per file?) turned out to be much smaller than the NodeJS headers, and the big source tarball turns out can be just deleted, so I'm comfortable checking those into the repo and getting rid of this complexity -- @Spiker985 commented in the Discord about the complexity and I realized I might have gone a bit overboard. But besides, when I found out the Electron files were just so small... it's like on the order of a large JS file or something... I suddenly felt like that would be pretty manageable. Once I get the simpler version up I will give people a chance to weigh in which approach they like better. It'll be a much, much simpler PR than this one, hopefully a breeze to review. I didn't want to post it until decafing the specs was done, but given your comment above I'll go ahead and post that now. |
|
UPDATE: I posted #52 as the simpler alternative to this. |
|
Gonna close this, just a memo that if anyone wants a convenient script to automate bumping these spec fixtures to be ones for a newer Electron version, please ping me, as the JS script I put together here is still good for that and can be adapted to meet that use-case a little better than what I was going for here, but could also be used pretty much as-is with tweaks to match PR #52's dir structure instead of how this PR set things up. |
As per usual, I'm writing really long stuff in these PR bodies.
The short story is, this fixes the specs.
See the diff and commit messages for details. (Although I wrote some really long commit messages, too. Whoops.)
There is the summary below, which was meant to be the condensed info, but ended up being long again.
I also bolded the bare minimum info in the paragraphs below, so one can skim to know what this PR is about/why.
Summary:
script/ensure-node-source-fixture-files.js) to fetch the files from NodeJS.org on the web as-needed, (or verify the local copies if you already fetched them once) rather than check them into the repo..gitignore, since the whole point is we do not want these huge ~70MB+ files checked into git under any circumstances. They are to be fetched from the web as-needed only.npm run testscript to run the newensure-fixturesscript (which I wrote for this PR) before running the specs, so the files will (or at least should) exist locally on disk, and the specs that need these files can pass.Hi folks.
When bumping to bundled NodeJS to v16.0.0 (#41 --> 12ae15d), it turned out ppm stopped being able to pass certain specs.
On closer look, these specs failing in this particular way seemed very familiar to me, reminding me of the time I had to bump the copy of NodeJS's source and headers that we use to build some basic example/test modules against in certain tests. I had to do this to get specs passing again during the upgrade to node-gyp v5.X (atom/apm#887 --> atom/apm@77227d8)
However, the same solution again (bumping to newer NodeJS source/headers for the specs) would baloon this git repo's size by just over 100 megabytes. (Newer NodeJS versions keep getting larger and larger and larger as they continue adding new features to NodeJS core.)
So I put together a script to download these large files off the web from NodeJS.org as-needed and just keep them around for subsequent test runs, since they won't be changing often. I then made sure this script is run (and the source/header files verified or re-downloaded as needed) before each test run -- I added it to the steps that get run when you do
./bin/npm run test. I also reconfigured some spec files to expect these files to be in the newspec/fixtures/node-sourcedir where these files will live. And I.gitignored the new files, since they are not meant to be checked in to git. And I added a step to the CI workflow to cache these files, so we can somewhat reliably have these files, even if NodeJS.org flakes or goes down. This also saves NodeJS.org some bandwidth, and makes the tests run ever so slightly faster. (Although it's only faster by a second or two! None of this file downloading/verifying takes very long at all, nor does the caching in CI! I am impressed that it only takes about 5 seconds or less either way. Usually less than 5 seconds!)In other words, I fixed the specs, and made it easier to change the version of NodeJS these test/example modules build against during the specs, and did so without causing this git repo to become really super huge to download.
(Most of this repo's download size is from the NodeJS 10.20.1 source/headers I added in atom/apm#887! I have always regretted that fact after I realized there might have been a better way to do it. So here is my shot to redeem the situation!)
(Historical note: NodeJS used to be so small that checking its entire source into git was a fairly reasonable thing to do. For version v0.10.3, all NodeJS files needed for these specs were under 1 megabyte! For NodeJS v10.20.1, one file at 0.5MB, two files just over 6.5 MB each and one file at 45MB (the NodeJS main source tarball) were needed. So that's almost exactly the size to download this repo, and it's all those NodeJS source files I added in that PR some time ago. Ah, well.)