Skip to content

Commit

Permalink
Scenario check support for sequence searches
Browse files Browse the repository at this point in the history
The search property supports different types of search
but only "simple" searches are considered in checks. This
adds support for performing a sequence search in a check.
  • Loading branch information
dosaboy committed Oct 24, 2023
1 parent a74724a commit 34978e3
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 9 deletions.
44 changes: 35 additions & 9 deletions hotsos/core/ycheck/engine/properties/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,40 @@ def _search_results(self):
search constraints requested.
"""
global_results = self.context.search_results
if global_results is not None:
tag = self.search.unique_search_tag
_results = global_results.find_by_tag(tag)
log.debug("check %s has %s search results with tag %s",
self.check_name, len(_results), tag)
return self.search.apply_extra_constraints(_results)

raise Exception("no search results provided to check '{}'".
format(self.check_name))
if global_results is None:
raise Exception("no search results provided to check '{}'".
format(self.check_name))

tag = self.search.unique_search_tag

# first get simple search results
simple_results = global_results.find_by_tag(tag)
log.debug("check %s has %s simple search results with tag %s",
self.check_name, len(simple_results), tag)
results = self.search.apply_extra_constraints(simple_results)

seq_def = self.search.cache.sequence_search
if not seq_def:
return results

# Not try for sequence search results
sections = global_results.find_sequence_by_tag(tag).values()
log.debug("check %s has %s sequence search results with tag %s",
self.check_name, len(sections), tag)
if not sections:
return results

# Use the result of the first section start as the final
# result. This is enough for now because the section is guaranteed
# to be complete i.e. a full match and the result is ultimately
# True/False based on whether or not a result was found.
for result in list(sections)[0]:
if result.tag == seq_def.start_tag:
# NOTE: we don't yet support applying extra constraints here
results.append(result)
break

return results

@classmethod
def _override_keys(cls):
Expand Down Expand Up @@ -84,6 +109,7 @@ def _result(self):
return False

return True

if self.requires:
if self.cache.requires:
result = self.cache.requires.passes
Expand Down
36 changes: 36 additions & 0 deletions tests/unit/test_ycheck_scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,28 @@ def init_test_scenario_inner2(*args, **kwargs):
""" # noqa


SCENARIO_W_SEQ_SEARCH = r"""
input:
path: {path}
checks:
seqsearch1:
start: "it's the start"
body: ".+"
end: "it's the end"
seqsearch2:
start: "it's the start"
end: "it's the end"
conclusions:
seqsearchworked:
decision:
- seqsearch1
- seqsearch2
raises:
type: SystemWarning
message: yay seq searches worked!
""" # noqa


SCENARIO_W_ERROR = r"""
scenarioA:
checks:
Expand Down Expand Up @@ -702,6 +724,20 @@ def test_yaml_def_expr_list(self):
msg = "yay list search"
self.assertEqual(issue['message'], msg)

@init_test_scenario(SCENARIO_W_SEQ_SEARCH.
format(path=os.path.basename('data.txt')))
@utils.create_data_root({'data.txt': ("blah blah\nit's the start\nblah "
"blah\nit's the end")})
def test_yaml_def_seq_search(self):
scenarios.YScenarioChecker().load_and_run()
issues = list(IssuesStore().load().values())
self.assertEqual(len(issues[0]), 1)
i_types = [i['type'] for i in issues[0]]
self.assertEqual(i_types, ['SystemWarning',])
for issue in issues[0]:
msg = "yay seq searches worked!"
self.assertEqual(issue['message'], msg)

@init_test_scenario(SCENARIO_CHECKS)
@utils.create_data_root({'foo.log': '2021-04-01 00:31:00.000 an event\n',
'uptime': (' 16:19:19 up 17:41, 2 users, '
Expand Down

0 comments on commit 34978e3

Please sign in to comment.