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
Add support for batched pytest
execution
#17385
Add support for batched pytest
execution
#17385
Conversation
All the existing tests for the logic changed here are integration tests, so I'll need to wait until the entire batching implementation is done to check if the new logic works... but this at least makes the types line up.
Same as coverage, the tests for the change logic are all integration tests so we'll need to wait until the end to see if this works properly...
The custom partitioner still creates one partition per field-set, but the runner rule should now be capable of testing an arbitrary number of input field-sets. As part of this, I've defined the metadata type for `pytest` partitions and shifted some logic for calculating metadata fields from the runner rule into the partitioner rule.
If two `python_test` targets have the same value for `batch_compatibility_tag`, then they are eligible to be batched into the same `pytest` process. They might _not_ be batched in the same process if: * There are "too many" compatible tests as determined by the `[test].batch_size` config option * Compatible tests have some incompatible Pants metadata (i.e. different `extra_env_vars` or `xdist_concurrency`) Tests that don't set the new field are assumed to be incompatible with all others, and continue to run one-target-per-process.
Improve batching hit-rate when the vars are the same, but listed in a different order.
Ensure that the expected results don't change in the presence of batching.
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.
Looks great! Thanks a lot.
src/python/pants/backend/python/goals/coverage_py_integration_test.py
Outdated
Show resolved
Hide resolved
Only calculate it if needed.
Make sure coverage collection works in both cases
I think ideally the plugin wouldn't need to think about this, but for now the core `test` logic will raise an error if a partition spans multiple environments so we should do our best not to get into that situation...
Head branch was pushed to by a user without write access
🎉 |
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.
Neat!
if concurrency is None: | ||
contents = await Get(DigestContents, Digest, field_set_source_files.snapshot.digest) | ||
concurrency = _count_pytest_tests(contents) | ||
xdist_concurrency = concurrency | ||
|
||
timeout_seconds: int | None = None | ||
for field_set in request.field_sets: | ||
timeout = field_set.timeout.calculate_from_global_options(test_subsystem, pytest) |
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.
It probably would be good to update the help for the timeout field to mention this summing behavior
* Compatible tests have some incompatibility in Pants metadata (i.e. different \ | ||
`resolve`s or `extra_env_vars`). |
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.
Thoughts on adding logs in this situation?
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.
Not opposed - in our repo we don't (yet) use the Pants features that cause this sort of incompatibility so I'm not sure how to judge the noisiness vs. usefulness
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.
Maybe debug level to start
Closes #14941
It's sometimes safe to run multiple
python_test
s within a singlepytest
process, and doing so can give significant wins by allowing reuse of expensive test setup/teardown logic. To allow users to opt into this behavior we introduce a newbatch_compatibility_tag
field onpython_test
, with semantics:pytest
processpython_test
, the test is explicitly incompatible with the other and is guaranteed to not run in the samepytest
processpython_test
, the tests are explicitly compatible and may run in the samepytest
processCompatible tests may not end up in the same
pytest
batch if:[test].batch_size
resolve
orextra_env_vars
)When tests with the same
batch_compatibility_tag
have incompatibilities in some other Pants metadata, the custom partitioning rule will split them into separate partitions. We'd previously discussed raising an error in this case when calling the fieldbatch_key
/batch_tag
, but IMO that approach will have a worse UX - this way users can set a high-levelbatch_compatibility_tag
using__defaults__
and then have things continue to Just Work as they add/removeextra_env_vars
and parameterizeresolve
s on lower-level targets.