-
Notifications
You must be signed in to change notification settings - Fork 253
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
Run each test using a temporary directory #217
Conversation
test/shared/utils.py
Outdated
env=env, | ||
) | ||
except: | ||
assert len(os.listdir(output_dir)) == 0 |
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.
Hmmm, interesting. Are we sure about this?
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 was hesitant about this and thought I'd get feedback.
While all tests are passing as of now, this check is not applicable in the general case.
Wheels are put in the output directory config per config on Windows/macOS or all at once on Linux.
The behavior is thus different depending on the platform. On Linux, you either get all or none of the wheels depending of a single error. On macOS/Windows, you get all wheels with tests successful (if applicable) up until the error.
Either we consider the linux behavior to be the right one and this check can be left as-is (requiring to add further tests later to ensure this behavior) or I can make this check optional for the one test that does use it (and we keep a different behavior depending on the platform).
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.
The behavior is thus different depending on the platform.
Good point. I hadn't even considered that. But that's a good point.
I was more thinking in terms that it should be the test asserting (because asserting no wheels are built is part of the test-), rather than here in utils
.
In the end, the difference between OSs doesn't matter that much, I'd say? The error is thrown anyway?
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.
There are two more solutions, though:
-
Catch all errors, and just return the list? Normally, the test should catch that the wrong wheels are built? If necessary, we can return a few things, like error status, output, and built wheels; or return built wheels and
None
/caught exception? -
Throw a custom exception on catching this one, that "includes the list of built wheels", as a way of having an exception ánd return value?
Neither of these two solutions give me a very warm feeling, though.
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.
There's yet another solution which provides flexibility (but consistency-wise would be a bit lower).
Add an output_dir=None
default arg to cibuildwheel_run
, much like @Czaki proposed at one time in order to use tmp_path
only on selected project before saying all tests shall use a temp folder.
My feeling is that all tests needs to run in a temp folder.
90% of them won't need to bother with an output_dir
and just need the resulting wheel names and what's here just works. By adding output_dir=None
, we allow selected tests that require access to output_dir
to provide it.
Any thoughts ?
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.
No. If you build 64 an 32 bits, then it copy wheels in two packs.
Huh? We don't mount a directory into the docker image anymore, do we? Because CircleCI doesn't allow that?
EDIT: See https://github.com/joerick/cibuildwheel/blob/34515b78c6a097df9c709d484cb7cecefda33d28/cibuildwheel/linux.py#L174; I think @mayeut was correct?
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.
There's yet another solution which provides flexibility (but consistency-wise would be a bit lower).
[...]
Any thoughts ?
Hmmm, myes, interesting; I hadn't thought of that, indeed. I guess that's as good of a solution as the other two things I suggested (or even better), since it's less of a hack, and doesn't try to "return a value from a function that's throwing an exception". (Or maybe this is the sign that the abstraction of having run_cibuildwheel
return a list of wheels is not completely right?)
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.
But you run separated docker containers for x86_64 and i686 wheels.
and when container finish work then result is copied. So you will have two transactions.
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.
@Czaki Ooooh, yes, right. I thought you meant you get pairs of 32- and 64-bit wheels. But you get two separate batches of all 32- and all 64-bit wheels.
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.
No. If you build 64 an 32 bits, then it copy wheels in two packs.
You're right. Doesn't change the fact that behavior is different though. Anyway, this is not the matter here.
Or maybe this is the sign that the abstraction of having run_cibuildwheel return a list of wheels is not completely right?
I think the option doesn't hurt too much the abstraction.
17ce49d
to
a444d16
Compare
test/shared/utils.py
Outdated
with TemporaryDirectory() as output_dir: | ||
try: | ||
subprocess.check_call( | ||
[sys.executable, '-m', 'cibuildwheel', '--output-dir', output_dir, project_path], |
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.
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.
But now this test (from #179) has symilar structure to other. After this changes, even after refactor to new style it will have "different structure"
@YannickJadoul @mayeut In my opinion test should be self explaining. So person who do not have perfect knowledge about project should understand what scenario is executed. For me this PR and #214 do not satisfy this. Reading test under this PR I rather expect that I think that all my remarks can be removed by rename functions. Ex. |
a444d16
to
40d2c1e
Compare
Thanks for that feedback, that's valuable. I do understand this point of view and I guess the current size of this part of the project does allow for what you're asking. @joerick ? From a generic maintenance point of view, duplicate code is most often a nightmare. Things can grow out of proportions quite fast and, I really dislike having to change something at many places when it could have been factored. Yes, it does requires a better understanding of the code base but it's a trade-off between maintainability and ease of discovery. It does require to spend time thinking this refactor in order not to create something too convoluted either. (and if you think this PR is, maybe I'm not leaning towards a solution that's good enough) May I ask if the current state of tests in master could have benefited from a bit more docs (in the specific README probably) ? |
Hmmm, I don't fully understand why, because I feel the opposite is more intuitive: If you are not very familiar with the code or My resistance against making
So I completely agree on this; I just seem to have a different solution for it :-) |
40d2c1e
to
a7f0d3b
Compare
Simpler way of getting each test to run in a unique temporary directory than #213 and #214 which also attempts to make all tests being run with a single
pytest
invocation.