Skip to content

Commit

Permalink
Added coverage computation method.
Browse files Browse the repository at this point in the history
  • Loading branch information
NikosDelijohn committed Sep 9, 2024
1 parent 8d71ec5 commit 75ca73e
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions src/zoix.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,73 @@ def parse_fault_report(self) -> list[Fault]:

return [ Fault(**dict(zip(attributes, csv_row))) for csv_row in reader ]

@staticmethod
def compute_flist_coverage(fault_list : list[Fault], sff_file: pathlib.Path, formula: str, precision : int = 2, status_attribute : str = "Status") -> float:
"""Computes the test coverage percentage as described by `formula`, which must be comprised
of mathematical operations of Z01X fault classes (i.e., 2 letter strings).
- Parameters:
- fault_list (list(Fault)): A fault-list generated after parssing Z01X fault report csv.
- sff_file (pathlib.Path): The fault format configuration file.
- formula (str): A formula which computes the coverage e.g., `"DD/(NA + DA + DN + DD)"`.
- precision (int): the number of decimals to consider for the coverage. Default is `2`.
- status_attribute (str): The attribute of the `Fault` object which represents its Z01X fault status/class.
By default this attribute is set to `"Status"`.
- Returns:
float: The coverage percentage i.e., the evaluated `formula`."""

# Gather fault statuses numbers.
fault_statuses = dict()

for fault in fault_list:

status = fault.get(status_attribute)
if status in fault_statuses:
fault_statuses[status] += 1
else:
fault_statuses[status] = 1


# Parse StatusGroups section.
with open(sff_file) as config:

try:
status_groups_raw = re.search(
r"StatusGroups\n\s*{([^}]+)\s*}",
config.read(),
re.MULTILINE).group(1).splitlines()

except AttributeError:
log.critical(f"Unable to extract StatusGroups segment from {sff_file}. Exiting...")
exit(1)

# Remove empty lines if any.
status_groups_raw = list(filter(lambda x : len(x), map(str.strip, status_groups_raw)))
status_groups = dict()

for line in status_groups_raw:

group, *statuses = re.findall(r"([A-Z]{2})", line)

status_groups[group] = 0

for status in statuses:
if status in fault_statuses:
status_groups[group] += fault_statuses[status]


# Finally get any group only present
# in the formula and set it to 0.
non_present_statuses = dict()

for status in re.findall(r"[A-Z]{2}", formula):

if status not in fault_statuses.keys() and \
status not in status_groups.keys():
non_present_statuses[status] = 0

return round(eval(formula, {**fault_statuses, **status_groups, **non_present_statuses}), precision)

class ZoixInvoker():
"""A wrapper class to be used in handling calls to VCS-Z01X."""
def __init__(self) -> "ZoixInvoker":
Expand Down

0 comments on commit 75ca73e

Please sign in to comment.