-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
bootstrap: Add doctests and unitests #43046
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
In this commit 26885c8 you'll find initial support for Python 3. I did some tests with tox including the current unit tests for Python 2.7, 3.5, and 3.6 and everything seems to be working: $ cd src/bootstrap
$ tox
GLOB sdist-make: /Development/rust/rust/src/bootstrap/setup.py
py27 create: /Development/rust/rust/src/bootstrap/.tox/py27
py27 inst: /Development/rust/rust/src/bootstrap/.tox/dist/rust-bootstrap-0.0.1.zip
py27 installed: rust-bootstrap==0.0.1
py27 runtests: PYTHONHASHSEED='3410238989'
py27 runtests: commands[0] | /Development/rust/rust/src/bootstrap/.tox/py27/bin/python bootstrap_test.py
bin_root (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.bin_root ... ok
bootstrap_binary (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.bootstrap_binary ... ok
cargo_stamp (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.cargo_stamp ... ok
get_mk (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.get_mk ... ok
get_string (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.get_string ... ok
get_toml (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.get_toml ... ok
rustc_stamp (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.rustc_stamp ... ok
format_build_time (bootstrap)
Doctest: bootstrap.format_build_time ... ok
test_stage0_data (__main__.Stage0DataTestCase)
Extract data from stage0.txt ... ok
test_invalid_file (__main__.VerifyTestCase)
Should verify that the file is invalid ... invalid checksum:
found: 334d016f755cd6dc58c53a86e183882f8ec14f52fb05345887c8a5edd42c87b7
expected: 64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c
ok
test_valid_file (__main__.VerifyTestCase)
Check if the sha256 sum of the given file is valid ... ok
----------------------------------------------------------------------
Ran 11 tests in 0.013s
OK
py35 create: /Development/rust/rust/src/bootstrap/.tox/py35
py35 inst: /Development/rust/rust/src/bootstrap/.tox/dist/rust-bootstrap-0.0.1.zip
py35 installed: rust-bootstrap==0.0.1
py35 runtests: PYTHONHASHSEED='3410238989'
py35 runtests: commands[0] | /Development/rust/rust/src/bootstrap/.tox/py35/bin/python bootstrap_test.py
bin_root (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.bin_root ... ok
bootstrap_binary (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.bootstrap_binary ... ok
cargo_stamp (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.cargo_stamp ... ok
get_mk (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.get_mk ... ok
get_string (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.get_string ... ok
get_toml (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.get_toml ... ok
rustc_stamp (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.rustc_stamp ... ok
format_build_time (bootstrap)
Doctest: bootstrap.format_build_time ... ok
test_stage0_data (__main__.Stage0DataTestCase)
Extract data from stage0.txt ... ok
test_invalid_file (__main__.VerifyTestCase)
Should verify that the file is invalid ... invalid checksum:
found: 334d016f755cd6dc58c53a86e183882f8ec14f52fb05345887c8a5edd42c87b7
expected: 64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c
ok
test_valid_file (__main__.VerifyTestCase)
Check if the sha256 sum of the given file is valid ... ok
----------------------------------------------------------------------
Ran 11 tests in 0.021s
OK
py36 create: /Development/rust/rust/src/bootstrap/.tox/py36
py36 inst: /Development/rust/rust/src/bootstrap/.tox/dist/rust-bootstrap-0.0.1.zip
py36 installed: rust-bootstrap==0.0.1
py36 runtests: PYTHONHASHSEED='3410238989'
py36 runtests: commands[0] | /Development/rust/rust/src/bootstrap/.tox/py36/bin/python bootstrap_test.py
bin_root (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.bin_root ... ok
bootstrap_binary (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.bootstrap_binary ... ok
cargo_stamp (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.cargo_stamp ... ok
get_mk (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.get_mk ... ok
get_string (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.get_string ... ok
get_toml (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.get_toml ... ok
rustc_stamp (bootstrap.RustBuild)
Doctest: bootstrap.RustBuild.rustc_stamp ... ok
format_build_time (bootstrap)
Doctest: bootstrap.format_build_time ... ok
test_stage0_data (__main__.Stage0DataTestCase)
Extract data from stage0.txt ... ok
test_invalid_file (__main__.VerifyTestCase)
Should verify that the file is invalid ... invalid checksum:
found: 334d016f755cd6dc58c53a86e183882f8ec14f52fb05345887c8a5edd42c87b7
expected: 64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c
ok
test_valid_file (__main__.VerifyTestCase)
Check if the sha256 sum of the given file is valid ... ok
----------------------------------------------------------------------
Ran 11 tests in 0.019s
OK
___________________________________ summary ____________________________________
py27: commands succeeded
py35: commands succeeded
py36: commands succeeded
congratulations :) |
@milmazz thanks for the PR! We'll make sure @alexcrichton or another reviewer gets to this soon. One question - as far as I remember we try and keep this compatible with python 3, can you clarify what was broken? |
@aidanhs For example: C:\Development\rust\src\bootstrap>python -V
Python 3.6.1
C:\Development\rust\src\bootstrap>python bootstrap_test.py
Traceback (most recent call last):
File "bootstrap_test.py", line 21, in <module>
import bootstrap
File "C:\Users\tusc0958\Downloads\Development\rust\src\bootstrap\bootstrap.py", line 273
except OSError, reason:
^
SyntaxError: invalid syntax Also, the |
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! This part of the codebase very rarely regresses so the need to add tests isn't too high, but if you're willing go to through the hoops to add them then I don't see why we shouldn't land them. Can you ensure though that they run as part of our CI?
Otherwise python 3 compatibility is fine, but unfortuantely (last we checked) building LLVM required 2.7 (doesn't work with 3). That being said we can always be compatible for when they're compatible and then we can also provide nicer warnings when 3 is detected.
src/bootstrap/bootstrap.py
Outdated
|
||
def download_stage0(self): | ||
"""Download stage0""" |
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.
Hm I personally prefer to avoid comments like this, it seems like this doesn't provide any utility over the name of the method itself?
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.
@alexcrichton Thanks for the review! I agree with you, I added more information in both methods as you suggested. Please let me know what do you think.
src/bootstrap/bootstrap.py
Outdated
# If we're on NixOS we need to change the path to the dynamic loader | ||
@staticmethod | ||
def fix_executable(fname): | ||
"""This method tries to fix the given executable |
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.
Similarly as above, this doc string isn't too helpful :(
What's being "fixed" here?
I think this PR should also mean that users with a system version of LLVM to link against will be able to build without python 2 installed, which is something (not that system versions of LLVM are recommended). |
return data | ||
lines = [line.rstrip() for line in nightlies | ||
if not line.startswith("#")] | ||
return dict([line.split(": ", 1) for line in lines if line]) |
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.
Could you move the if line
into the filtering above (if line and not line.startswith("#")
)? Seems like it'd make more sense there.
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.
@aidanhs The way you propose it will break the code when we try to split an empty line. First, we need to delete all the trailing whitespace (eg: \t\n\x0b\x0c\r
) with rstrip()
, then we discard all the empty lines, after that, we can apply the split()
method. HTH
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.
Ah yes, I see.
return | ||
except OSError as reason: | ||
if getattr(reason, 'winerror', None) is not None: | ||
return |
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.
Surely this needs to raise
in an else?
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.
@aidanhs I tried to keep the same behavior, please note that we only catch subprocess.CalledProcessError
, and WindowsError
(which only occurs on Windows and it's a subclass of OSError
). So, if any OSError
exception occurs in another OS it will certainly raise an exception as you pointed out.
WDYT? Do we need to handle this case in other OSs?
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'd follow your current theme and leave any behaviour changes for a separate PR, i.e. restore the behaviour of throwing the exception upwards.
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.
@milmazz do you have thoughts on the re-raise here?
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.
@alexcrichton I think is not required to re-raise here because if the following condition is true
:
if getattr(reason, 'winerror', None) is not None:
Then, we can agree that we don't need to modify the interpreter section to fix the dynamic linker in the given executable. This condition only applies on NixOS. wdyt?
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.
Actually, after thinking a little bit more, you're right, we should have something like this:
except OSError as reason:
if getattr(reason, 'winerror', None) is not None:
return
raise reason
If we receive an OSError
exception that means that the system cannot find the
uname
command and that is OK in Windows but not in other Operating Systems.
except subprocess.CalledProcessError as e: | ||
print("warning: failed to call patchelf: %s" % e) | ||
except subprocess.CalledProcessError as reason: | ||
print("warning: failed to call patchelf:", reason) |
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.
You removed the %s
on this print, but not the others - I don't think it matters, but it's probably worth being consistent.
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.
@aidanhs Sure thing, I can change those lines too.
@aidanhs @alexcrichton I think this is ready for another review. Please let me know what do you think. In the meantime, I'll start learning some Rust :-) |
appveyor.yml
Outdated
@@ -125,6 +125,9 @@ install: | |||
- copy C:\Python27\python.exe C:\Python27\python2.7.exe | |||
- set PATH=C:\Python27;%PATH% | |||
|
|||
# Run unit tests for bootstrap.py | |||
- python src\bootstrap\bootstrap_test.py |
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.
Why is this being run during the install phase?
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.
@aidanhs I just thought it was a good place because the 2 preconditions that I need are already meet at this stage:
- The repository is already cloned
- Python is already configured
But I'm open to suggestions, please let me know where do you think is the right place to move this section.
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.
Wherever it happens, it should probably be in the same place in both travis and appveyor. My personal preference it to put it in the "test" or "script" or whatever phase just for clarity.
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.
In .travis.yml
we can run custom commands before the script
phase with before_script
, it seems that the equivalent phase in appveyor.yml
is before_build
.
Ping @aidanhs, looks like this is back in your court for rereview? |
appveyor.yml
Outdated
before_build: | ||
# Run unit tests for bootstrap.py | ||
- python src\bootstrap\bootstrap_test.py | ||
|
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 I've had a look at this again and realised I missed something - we run Docker containers for a number of our builds and so this python script should ideally run in those as well.
My suggestion is to remove the additions to the travis and appveyor yml, and instead mimic https://github.com/rust-lang/rust/blob/3447aa7/src/ci/run.sh#L65-L69 - hopefully that will work!
Other than the comment about moving this testing into |
@aidanhs Any idea why the build is failing now? is it related with the latest change? |
Build is actually green, just the mac builders were apparently canceled for some reason. |
@Mark-Simulacrum Yes, I saw it and I was curious about that. Anyway, I see that a new job was triggered for those cases. Thanks! |
Wow, that was fast! now the build is green :) @aidanhs @alexcrichton Are we ready to go? |
src/ci/run.sh
Outdated
@@ -74,6 +74,12 @@ retry make prepare | |||
travis_fold end make-prepare | |||
travis_time_finish | |||
|
|||
travis_fold start configure |
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.
Can you change the travis folds to be something like bootstrap-test
? Both the start
and the end
need altering.
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.
@aidanhs Good Catch! already fixed! 👍
Looking good! If you can squash your commits then I'll r+. |
@aidanhs Done! |
@bors r=aidanhs |
📌 Commit 72d4856 has been approved by |
🔒 Merge conflict |
The failures were because the OSX builds didn't start for some reason. They're no-ops anyway, but I restarted them to get the PR build clean. @bors r+ |
📌 Commit 22f36db has been approved by |
bootstrap: Add doctests and unitests This commit includes the following changes: * Include more docstrings in classes, methods, and functions * Add doctests, which are great for self-documenting our source code * Add some unit tests with the `unittest` module * Remove `WindowsError` reference on non-windows systems * Rename some variables to be more explicit about their meaning * Move all the attributes defined outside of `__init__` * Add initial support for Python 3 r? @alexcrichton
|
src/ci/run.sh
Outdated
@@ -74,6 +74,12 @@ retry make prepare | |||
travis_fold end make-prepare | |||
travis_time_finish | |||
|
|||
travis_fold start bootstrap-test | |||
travis_time_start | |||
python $SRC/src/bootstrap/bootstrap_test.py |
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.
Let's add this as a target to the makefile. I think you can edit Makefile.in
to do so, and then we can use the CFG_PYTHON
and CFG_SRC_DIR
variables. check-bootstrap
seems fine.
Wait, I don't understand why bors tested this again? I requested a change to put this in the makefile three days ago, this PR was assigned to me two days ago...and then bors tested it an hour ago? |
Huh. Possibly because we synchronized bors' queue and it somehow forgot about the failure, but odd indeed. |
@aidanhs @Mark-Simulacrum Done! 🤞 |
Thanks! @bors r+ |
📌 Commit 7c737b3 has been approved by |
🔒 Merge conflict |
☔ The latest upstream changes (presumably #43384) made this pull request unmergeable. Please resolve the merge conflicts. |
This commit includes the following: * Fix syntax errors in Python 3 * Include more docstrings in classes, methods, and functions * Include unit tests using `unittest` * Merge implementation of `{rustc,cargo}_out_of_date` * Merge implementation of `RustBuild.{cargo,rustc}` * Remove unnecessary source code * Move all the attributes defined outside of `__init__` * Remove remaining `%s` from print function * Remove `WindowsError` reference on non-windows systems * Rename some variables to be more explicit avoid their meaning * Run bootstrap tests in the CI process * Remove non-pythonic getters * Remove duplicate code in `download_stage0` method * Reduce the number of branches in `build_bootstrap` method * Re-raise exception when we cannot execute uname in non-windows systems * Avoid long lines
@bors r+ |
📌 Commit f516765 has been approved by |
⌛ Testing commit f516765 with merge 96acd85c692a74fb27aa8bbf1c39c86450b3c754... |
💔 Test failed - status-travis |
bootstrap: Add doctests and unitests This commit includes the following changes: * Include more docstrings in classes, methods, and functions * Add doctests, which are great for self-documenting our source code * Add some unit tests with the `unittest` module * Remove `WindowsError` reference on non-windows systems * Rename some variables to be more explicit about their meaning * Move all the attributes defined outside of `__init__` * Add initial support for Python 3 r? @alexcrichton
💔 Test failed - status-travis |
@bors retry
|
bootstrap: Add doctests and unitests This commit includes the following changes: * Include more docstrings in classes, methods, and functions * Add doctests, which are great for self-documenting our source code * Add some unit tests with the `unittest` module * Remove `WindowsError` reference on non-windows systems * Rename some variables to be more explicit about their meaning * Move all the attributes defined outside of `__init__` * Add initial support for Python 3 r? @alexcrichton
☀️ Test successful - status-appveyor, status-travis |
@aidanhs @alexcrichton @Mark-Simulacrum Thank you for your help! 🎉 🕺 🎉 |
This commit includes the following changes:
unittest
moduleWindowsError
reference on non-windows systems__init__
r? @alexcrichton