from functools import reduce
from typing import Dict, List, Optional, Set
class FailedPlatform:
def __init__(
self,
oop_permutations: Optional[
Dict[
str, Dict[str, Dict[str, int]], ]
],
) -> None:
self.failures: Dict[str, Set[str]] = {}
self.oop_permutations = oop_permutations
def get_possible_build_types(self) -> List[str]:
return (
list(self.oop_permutations.keys())
if self.oop_permutations is not None
else []
)
def get_possible_test_variants(self, build_type: str) -> List[str]:
permutations = (
self.oop_permutations.get(build_type, {})
if self.oop_permutations is not None
else []
)
return [tv for tv in permutations]
def is_full_fail(self) -> bool:
build_types = set(self.failures.keys())
possible_build_types = self.get_possible_build_types()
if len(possible_build_types) == 0:
return False
return all(
[
bt in build_types and self.is_full_test_variants_fail(bt)
for bt in possible_build_types
]
)
def is_full_test_variants_fail(self, build_type: str) -> bool:
failed_variants = self.failures.get(build_type, [])
possible_test_variants = self.get_possible_test_variants(build_type)
if len(possible_test_variants) == 0:
return False
return all([t in failed_variants for t in possible_test_variants])
def get_negated_variant(self, test_variant: str):
if not test_variant.startswith("!"):
return "!" + test_variant
return test_variant.replace("!", "", 1)
def get_no_variant_conditions(self, and_str: str, build_type: str):
variants = [
tv
for tv in self.get_possible_test_variants(build_type)
if tv != "no_variant"
]
return_str = ""
for tv in variants:
return_str += and_str + self.get_negated_variant(tv)
return return_str
def get_test_variant_condition(
self, and_str: str, build_type: str, test_variant: str
):
all_test_variants_parts = [
tv.split("+")
for tv in self.get_possible_test_variants(build_type)
if tv not in ["no_variant", test_variant]
]
test_variant_parts = test_variant.split("+")
matching_variants_parts = [
tv_parts
for tv_parts in all_test_variants_parts
if all(x in tv_parts for x in test_variant_parts)
]
variants_to_negate = [
part
for tv_parts in matching_variants_parts
for part in tv_parts
if part not in test_variant_parts
]
return_str = reduce((lambda x, y: x + and_str + y), test_variant_parts, "")
return_str = reduce(
(lambda x, y: x + and_str + self.get_negated_variant(y)),
variants_to_negate,
return_str,
)
return return_str
def get_test_variant_string(self, test_variant: str):
if test_variant == "no-fission":
return "!fission"
if test_variant == "1proc":
return "!e10s"
return test_variant
def get_skip_string(self, and_str: str, build_type: str, test_variant: str) -> str:
if self.failures.get(build_type) is None:
self.failures[build_type] = {test_variant}
else:
self.failures[build_type].add(test_variant)
return_str = ""
if not self.is_full_fail():
return_str += and_str + build_type
if not self.is_full_test_variants_fail(build_type):
if test_variant == "no_variant":
return_str += self.get_no_variant_conditions(and_str, build_type)
else:
return_str += self.get_test_variant_condition(
and_str, build_type, test_variant
)
return return_str