twister: Fix quarantine performance issue

When using a quarantine file with more than 512 unique
entries, than time of matching quarantine increases
significantly. This is because regexp cache size is
512. Add precompiled regexp entries to the quarantine
as a fix.

Signed-off-by: Grzegorz Chwierut <grzegorz.chwierut@nordicsemi.no>
This commit is contained in:
Grzegorz Chwierut 2023-09-29 10:48:50 +02:00 committed by Fabio Baltieri
commit fd6f3c5a2a
2 changed files with 18 additions and 9 deletions

View file

@ -41,6 +41,10 @@ class QuarantineElement:
architectures: list[str] = field(default_factory=list) architectures: list[str] = field(default_factory=list)
simulations: list[str] = field(default_factory=list) simulations: list[str] = field(default_factory=list)
comment: str = 'NA' comment: str = 'NA'
re_scenarios: list = field(default_factory=list)
re_platforms: list = field(default_factory=list)
re_architectures: list = field(default_factory=list)
re_simulations: list = field(default_factory=list)
def __post_init__(self): def __post_init__(self):
# If there is no entry in filters then take all possible values. # If there is no entry in filters then take all possible values.
@ -53,6 +57,12 @@ class QuarantineElement:
self.architectures = [] self.architectures = []
if 'all' in self.simulations: if 'all' in self.simulations:
self.simulations = [] self.simulations = []
# keep precompiled regexp entiries to speed-up matching
self.re_scenarios = [re.compile(pat) for pat in self.scenarios]
self.re_platforms = [re.compile(pat) for pat in self.platforms]
self.re_architectures = [re.compile(pat) for pat in self.architectures]
self.re_simulations = [re.compile(pat) for pat in self.simulations]
# However, at least one of the filters ('scenarios', platforms' ...) # However, at least one of the filters ('scenarios', platforms' ...)
# must be given (there is no sense to put all possible configuration # must be given (there is no sense to put all possible configuration
# into quarantine) # into quarantine)
@ -101,16 +111,16 @@ class QuarantineData:
for qelem in self.qlist: for qelem in self.qlist:
matched: bool = False matched: bool = False
if (qelem.scenarios if (qelem.scenarios
and (matched := _is_element_matched(scenario, qelem.scenarios)) is False): and (matched := _is_element_matched(scenario, qelem.re_scenarios)) is False):
continue continue
if (qelem.platforms if (qelem.platforms
and (matched := _is_element_matched(platform, qelem.platforms)) is False): and (matched := _is_element_matched(platform, qelem.re_platforms)) is False):
continue continue
if (qelem.architectures if (qelem.architectures
and (matched := _is_element_matched(architecture, qelem.architectures)) is False): and (matched := _is_element_matched(architecture, qelem.re_architectures)) is False):
continue continue
if (qelem.simulations if (qelem.simulations
and (matched := _is_element_matched(simulation, qelem.simulations)) is False): and (matched := _is_element_matched(simulation, qelem.re_simulations)) is False):
continue continue
if matched: if matched:
@ -118,9 +128,9 @@ class QuarantineData:
return None return None
def _is_element_matched(element: str, list_of_elements: list) -> bool: def _is_element_matched(element: str, list_of_elements: list[re.Pattern]) -> bool:
"""Return True if given element is matching to any of elements from the list""" """Return True if given element is matching to any of elements from the list"""
for pattern in list_of_elements: for pattern in list_of_elements:
if re.fullmatch(pattern, element): if pattern.fullmatch(element):
return True return True
return False return False

View file

@ -104,10 +104,9 @@ def test_quarantinedata_post_init():
quarantine_element = QuarantineElement( quarantine_element = QuarantineElement(
platforms=['dummy platform'], platforms=['dummy platform'],
architectures=[] architectures=[],
simulations=['dummy simulation', 'another simulation']
) )
quarantine_element.scenarios = []
quarantine_element.simulations = ['dummy simulation', 'another simulation']
quarantine_data_qlist = [quarantine_element, quarantine_element_dict] quarantine_data_qlist = [quarantine_element, quarantine_element_dict]