forked from pantsbuild/pants
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add one-partition-per-input partitioning strategy. (pantsbuild#17255)
I would like to implement batched testing using the same partitioning infrastructure as `lint`/`fmt`/`fix`. Unlike those goals, it's not necessarily safe/possible for Pants to assume that all tests can run in the same process by default - instead, Pants will need to continue testing one-file-per-process unless a plugin specifically implements the logic for batching compatible test files. This commit adds a new partitioning type to our generic types to support this use-case. In addition to extending the enum with a new value, it: * Adds default `@rule`s for the new value, and * Consolidates the logic for deciding which default rules (if any) should be registered into a new method on the enum type [ci skip-build-wheels]
- Loading branch information
Showing
5 changed files
with
282 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
from dataclasses import dataclass | ||
from typing import Any | ||
|
||
import pytest | ||
|
||
from pants.build_graph.address import Address | ||
from pants.core.goals.fix import Partitions | ||
from pants.core.util_rules.partitions import ( | ||
Partition, | ||
PartitionerType, | ||
_PartitionFieldSetsRequestBase, | ||
) | ||
from pants.engine.rules import QueryRule | ||
from pants.engine.target import FieldSet, MultipleSourcesField, SingleSourceField | ||
from pants.option.option_types import SkipOption | ||
from pants.option.subsystem import Subsystem | ||
from pants.testutil.rule_runner import RuleRunner | ||
|
||
|
||
class KitchenSource(SingleSourceField): | ||
pass | ||
|
||
|
||
@dataclass(frozen=True) | ||
class KitchenSingleUtensilFieldSet(FieldSet): | ||
required_fields = (KitchenSource,) | ||
|
||
utensil: SingleSourceField | ||
|
||
|
||
@dataclass(frozen=True) | ||
class KitchenMultipleUtensilsFieldSet(FieldSet): | ||
required_fields = (KitchenSource,) | ||
|
||
utensils: MultipleSourcesField | ||
|
||
|
||
class KitchenSubsystem(Subsystem): | ||
options_scope = "kitchen" | ||
help = "a cookbook might help" | ||
name = "The Kitchen" | ||
skip = SkipOption("cook") | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"kitchen_field_set_type, field_sets", | ||
[ | ||
( | ||
KitchenSingleUtensilFieldSet, | ||
( | ||
KitchenSingleUtensilFieldSet( | ||
Address("//:bowl"), SingleSourceField("bowl.utensil", Address("")) | ||
), | ||
KitchenSingleUtensilFieldSet( | ||
Address("//:knife"), SingleSourceField("knife.utensil", Address("")) | ||
), | ||
), | ||
), | ||
( | ||
KitchenMultipleUtensilsFieldSet, | ||
( | ||
KitchenMultipleUtensilsFieldSet( | ||
Address("//:utensils"), | ||
MultipleSourcesField(["*.utensil"], Address("")), | ||
), | ||
), | ||
), | ||
], | ||
) | ||
def test_default_single_partition_partitioner(kitchen_field_set_type, field_sets) -> None: | ||
class CookRequest: | ||
class PartitionRequest(_PartitionFieldSetsRequestBase[Any]): | ||
pass | ||
|
||
tool_subsystem = KitchenSubsystem | ||
field_set_type = kitchen_field_set_type | ||
|
||
rules = [ | ||
*PartitionerType.DEFAULT_SINGLE_PARTITION.default_rules(CookRequest, by_file=True), | ||
QueryRule(Partitions, [CookRequest.PartitionRequest]), | ||
] | ||
rule_runner = RuleRunner(rules=rules) | ||
rule_runner.write_files({"BUILD": "", "knife.utensil": "", "bowl.utensil": ""}) | ||
partitions = rule_runner.request(Partitions, [CookRequest.PartitionRequest(field_sets)]) | ||
assert partitions == Partitions( | ||
[ | ||
Partition( | ||
( | ||
"bowl.utensil", | ||
"knife.utensil", | ||
), | ||
None, | ||
) | ||
] | ||
) | ||
|
||
rule_runner.set_options(["--kitchen-skip"]) | ||
partitions = rule_runner.request(Partitions, [CookRequest.PartitionRequest(field_sets)]) | ||
assert partitions == Partitions([]) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"kitchen_field_set_type, field_sets", | ||
[ | ||
( | ||
KitchenSingleUtensilFieldSet, | ||
( | ||
KitchenSingleUtensilFieldSet( | ||
Address("//:bowl"), SingleSourceField("bowl.utensil", Address("")) | ||
), | ||
KitchenSingleUtensilFieldSet( | ||
Address("//:knife"), SingleSourceField("knife.utensil", Address("")) | ||
), | ||
), | ||
), | ||
( | ||
KitchenMultipleUtensilsFieldSet, | ||
( | ||
KitchenMultipleUtensilsFieldSet( | ||
Address("//:utensils"), | ||
MultipleSourcesField(["*.utensil"], Address("")), | ||
), | ||
), | ||
), | ||
], | ||
) | ||
def test_default_one_partition_per_input_partitioner(kitchen_field_set_type, field_sets) -> None: | ||
class CookRequest: | ||
class PartitionRequest(_PartitionFieldSetsRequestBase[Any]): | ||
pass | ||
|
||
tool_subsystem = KitchenSubsystem | ||
field_set_type = kitchen_field_set_type | ||
|
||
rules = [ | ||
*PartitionerType.DEFAULT_ONE_PARTITION_PER_INPUT.default_rules(CookRequest, by_file=True), | ||
QueryRule(Partitions, [CookRequest.PartitionRequest]), | ||
] | ||
rule_runner = RuleRunner(rules=rules) | ||
rule_runner.write_files({"BUILD": "", "knife.utensil": "", "bowl.utensil": ""}) | ||
partitions = rule_runner.request(Partitions, [CookRequest.PartitionRequest(field_sets)]) | ||
assert partitions == Partitions( | ||
[ | ||
Partition(("bowl.utensil",), None), | ||
Partition(("knife.utensil",), None), | ||
] | ||
) | ||
|
||
rule_runner.set_options(["--kitchen-skip"]) | ||
partitions = rule_runner.request(Partitions, [CookRequest.PartitionRequest(field_sets)]) | ||
assert partitions == Partitions([]) |