Skip to content
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

Extract linenum from file_regex for metrics #1751

Merged
merged 5 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions buildtest/builders/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -932,25 +932,26 @@ def _get_variables(self, variables):

return lines

def _extract_content(self, regex):
"""Extract content based on the stream and linenum properties
from the regex field and return it as a string.
def _extract_line(self, linenum, content):
"""Extract content based on the line number and return it as a string.

Args:
regex (dict): regex section from the metrics field
linenum (int): line number
content (str): content to be extracted from
"""

stream = regex.get("stream")
content = self._output if stream == "stdout" else self._error

linenum = regex.get("linenum")
if linenum is not None and content:
lines = content.split("\n")
try:
content = lines[linenum]
except IndexError as e:
content = ""
self.logger.error(e)
if linenum is None:
return content

lines = content.split("\n")
# removen last line if file ends in new line character
if lines[-1] == "":
lines.pop()
try:
content = lines[linenum]
except IndexError as e:
content = ""
self.logger.error(e)
return content

def add_metrics(self):
Expand All @@ -970,7 +971,11 @@ def add_metrics(self):

if regex:

content = self._extract_content(regex)
stream = regex.get("stream")
content_input = self._output if stream == "stdout" else self._error

linenum = regex.get("linenum")
content = self._extract_line(linenum, content_input)

if regex.get("re") == "re.match":
match = re.match(regex["exp"], content, re.MULTILINE)
Expand Down Expand Up @@ -998,7 +1003,10 @@ def add_metrics(self):
console.print(msg, style="red")
continue

content = read_file(resolved_fname)
linenum = file_regex.get("linenum")
content_input = read_file(resolved_fname)
content = self._extract_line(linenum, content_input)

match = (
re.search(file_regex["exp"], content, re.MULTILINE)
if content
Expand Down
4 changes: 4 additions & 0 deletions buildtest/schemas/definitions.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@
"minimum": 0,
"description": "Specify the item number used to index element in `match.group() <https://docs.python.org/3/library/re.html#match-objects>`_"
},
"linenum": {
"type": "integer",
"description": "Specify the line number used to extract from the file content where regex is applied"
},
"re": {
"type": "string",
"description": "Specify the regular expression type, it can be either re.search, re.match, or re.fullmatch. By default it uses re.search",
Expand Down
1 change: 1 addition & 0 deletions tests/builders/metrics_file_regex_with_invalid_linenum.yml
1 change: 1 addition & 0 deletions tests/builders/metrics_file_regex_with_linenum.yml
18 changes: 18 additions & 0 deletions tests/builders/test_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,21 @@ def test_metrics_regex_with_invalid_linenum():
configuration=config,
)
cmd.build()


def test_metrics_file_regex_with_linenum():
"""This test will perform status check on a particular line from a file where regular expression is applied"""
cmd = BuildTest(
buildspecs=[os.path.join(here, "metrics_file_regex_with_linenum.yml")],
configuration=config,
)
cmd.build()


def test_metrics_file_regex_with_invalid_linenum():
"""This test will test metrics file regex with invalid line number"""
cmd = BuildTest(
buildspecs=[os.path.join(here, "metrics_file_regex_with_invalid_linenum.yml")],
configuration=config,
)
cmd.build()
16 changes: 16 additions & 0 deletions tutorials/metrics/metrics_file_regex_with_invalid_linenum.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
buildspecs:
metric_file_regex_with_linenum_failure_example:
executor: generic.local.bash
type: script
description: capture result metric from file path
run: |
echo -e "HPCG result is INVALID with a GFLOP/s rating of=28.1215" > hpcg.txt
echo -e "HPCG result is VALID with a GFLOP/s rating of=68.9888" >> hpcg.txt
tags: tutorials
metrics:
second_line:
type: float
file_regex:
exp: '(\d+\.\d+)$'
linenum: 10
file: hpcg.txt
28 changes: 28 additions & 0 deletions tutorials/metrics/metrics_file_regex_with_linenum.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
buildspecs:
metric_file_regex_with_linenum_example:
executor: generic.local.bash
type: script
description: capture result metric from file path
run: |
echo -e "HPCG result is INVALID with a GFLOP/s rating of=28.1215" > hpcg.txt
echo -e "HPCG result is VALID with a GFLOP/s rating of=68.9888" >> hpcg.txt
tags: tutorials
metrics:
last_line:
type: float
file_regex:
exp: '(\d+\.\d+)$'
linenum: -1
file: hpcg.txt
without_linenum:
type: float
file_regex:
exp: '(\d+\.\d+)$'
file: hpcg.txt
status:
assert_eq:
comparisons:
- name: last_line
ref: 68.9888
- name: without_linenum
ref: 28.1215
Loading