Skip to content

Commit

Permalink
lobster-cpptest should support dynamic marker strings
Browse files Browse the repository at this point in the history
The config file has been adapted. the regex should be provided. The tests are being extracted based on provided regex.

Resolves #98
  • Loading branch information
TannazVhdBMWExt committed Oct 15, 2024
1 parent 5966e49 commit 2f038ec
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 85 deletions.
72 changes: 20 additions & 52 deletions lobster/tools/cpptest/cpptest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@

OUTPUT = "output"
CODEBEAMER_URL = "codebeamer_url"
MARKERS = "markers"
REGEX = "regex"
REGEX_LIST = "regex_list"
KIND = "kind"

NAMESPACE_CPP = "cpp"
Expand All @@ -43,26 +44,6 @@
CB_PREFIX = "CB-#"
MISSING = "Missing"


class RequirementTypes(Enum):
REQS = '@requirement'
REQ_BY = '@requiredby'
DEFECT = '@defect'


SUPPORTED_REQUIREMENTS = [
RequirementTypes.REQS.value,
RequirementTypes.REQ_BY.value,
RequirementTypes.DEFECT.value
]

map_test_type_to_key_name = {
RequirementTypes.REQS.value: 'requirements',
RequirementTypes.REQ_BY.value: 'required_by',
RequirementTypes.DEFECT.value: 'defect_tracking_ids',
}


def parse_config_file(file_name: str) -> dict:
"""
Parse the configuration dictionary from given config file.
Expand Down Expand Up @@ -103,26 +84,18 @@ def parse_config_file(file_name: str) -> dict:
f'"{CODEBEAMER_URL}"')

output_config_dict = config_dict.get(OUTPUT)
config_dict[REGEX_LIST] = []

supported_markers = ', '.join(SUPPORTED_REQUIREMENTS)
for output_file, output_file_config_dict in output_config_dict.items():
if MARKERS not in output_file_config_dict.keys():
if REGEX not in output_file_config_dict.keys():
raise ValueError(f'Please follow the right config file structure! '
f'Missing attribute "{MARKERS}" for output file '
f'Missing attribute "{REGEX}" for output file '
f'"{output_file}"')
if KIND not in output_file_config_dict.keys():
raise ValueError(f'Please follow the right config file structure! '
f'Missing attribute "{KIND}" for output file '
f'"{output_file}"')

output_file_marker_list = output_file_config_dict.get(MARKERS)
for output_file_marker in output_file_marker_list:
if output_file_marker not in SUPPORTED_REQUIREMENTS:
raise ValueError(f'"{output_file_marker}" is not a supported '
f'"{MARKERS}" value '
f'for output file "{output_file}". '
f'Supported values are: '
f'"{supported_markers}"')
config_dict[REGEX_LIST] = list(set(config_dict[REGEX_LIST] + output_file_config_dict.get(REGEX, [])))

return config_dict

Expand Down Expand Up @@ -177,6 +150,7 @@ def get_test_file_list(file_dir_list: list, extension_list: list) -> list:


def collect_test_cases_from_test_files(test_file_list: list,
regex_list: list,
codebeamer_url: str) -> list:
"""
Collects the list of test cases from the given test files.
Expand All @@ -185,24 +159,22 @@ def collect_test_cases_from_test_files(test_file_list: list,
----------
test_file_list : list
The list of test files.
regex_list: list
codebeamer_url: str
Returns
-------
list
The list of test cases.
"""
parser = ParserForRequirements()
test_case_list = parser.collect_test_cases_for_test_files(
test_files=test_file_list,
codebeamer_url = codebeamer_url
)
parser = ParserForRequirements(regex_list=regex_list, codebeamer_url = codebeamer_url)
test_case_list = parser.collect_test_cases_for_test_files(test_files=test_file_list)
return test_case_list


def create_lobster_items_output_dict_from_test_cases(
test_case_list: list,
config_dict: dict) -> dict:
output_config: dict) -> dict:
"""
Creates the lobster items dictionary for the given test cases grouped by
configured output.
Expand All @@ -211,7 +183,7 @@ def create_lobster_items_output_dict_from_test_cases(
----------
test_case_list : list
The list of test cases.
config_dict : dict
output_config : dict
The configuration dictionary.
Returns
Expand All @@ -224,12 +196,11 @@ def create_lobster_items_output_dict_from_test_cases(
lobster_items_output_dict = {}

no_marker_output_file_name = ''
output_config: dict = config_dict.get(OUTPUT)
marker_output_config_dict = {}
for output_file_name, output_config_dict in output_config.items():
lobster_items_output_dict[output_file_name] = {}
marker_list = output_config_dict.get(MARKERS)
if isinstance(marker_list, list) and len(marker_list) >= 1:
regex_list = output_config_dict.get(REGEX)
if isinstance(regex_list, list) and len(regex_list) >= 1:
marker_output_config_dict[output_file_name] = output_config_dict
else:
no_marker_output_file_name = output_file_name
Expand Down Expand Up @@ -261,14 +232,10 @@ def create_lobster_items_output_dict_from_test_cases(
marker_output_config_dict.items()):
tracing_target_list = []
tracing_target_kind = output_config_dict.get(KIND)
for marker in output_config_dict.get(MARKERS):
if marker not in map_test_type_to_key_name:
continue

for test_case_marker_value in getattr(
test_case,
map_test_type_to_key_name.get(marker)
):
for regex in output_config_dict.get(REGEX):

for test_case_marker_value in (
getattr(test_case, "custom_tags").get(regex)):
if MISSING not in test_case_marker_value:
test_case_marker_value = (
test_case_marker_value.replace(CB_PREFIX, ""))
Expand Down Expand Up @@ -353,13 +320,14 @@ def lobster_cpptest(file_dir_list: list, config_dict: dict):
test_case_list = \
collect_test_cases_from_test_files(
test_file_list=test_file_list,
regex_list=config_dict.get(REGEX_LIST, []),
codebeamer_url=config_dict.get(CODEBEAMER_URL, '')
)

lobster_items_output_dict: dict = \
create_lobster_items_output_dict_from_test_cases(
test_case_list=test_case_list,
config_dict=config_dict
output_config=config_dict.get(OUTPUT)
)

write_lobster_items_output_dict(
Expand Down
26 changes: 2 additions & 24 deletions lobster/tools/cpptest/parser/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,11 @@


class Constants:
def __init__(self, codebeamer_url = ''):

self.codebeamer_link = codebeamer_url + "/issue/"
self.requirement = re.compile(r".*[@\\]requirement\s+"
r"([\s*/]*(((CB-#)|({}))\d+)\s*,?)+"
.format(self.codebeamer_link))
self.requirement_tag_http = ((r"([@\\]requirement(\s+"
r"(CB-#\d+\s+)*({}\d+\s*,?\s*/*\*?)+)+)")
.format(self.codebeamer_link))
self.requirement_tag_http_named = (r"({}(?P<number>\d+))"
.format(self.codebeamer_link))

NON_EXISTING_INFO = "---"

CUSTOM_KEY = "custom_key"

LOBSTER_GENERATOR = "lobster-cpptest"

VALID_TESTMETHODS = [
Expand Down Expand Up @@ -46,16 +37,3 @@ def __init__(self, codebeamer_url = ''):
r"^\s*(" + "|".join(VALID_TEST_MACROS) +
r")\s*\(\s*(?P<suite_name>\w+),\s*(?P<test_name>\w+)\)"
)
REQUIREMENT_TAG = r"(CB-#\d+)"

REQUIRED_BY = re.compile(r".*[@\\]requiredby\s+([\s*/]*(\w*::\w+),?\s*)+")
REQUIRED_BY_TAG = r"(\w*::\w+)"
DEFECT = re.compile(
r"(@defect\s+)(((?:(CB-#\d+)|(OCT-#\d+)),?\s*)+)" +
r"(?:///|/)\s+(((?:(CB-#\d+)|(OCT-#\d+)),?\s)+)?"
)
BRIEF = re.compile(r"(@brief\s+)([^@]+)")
VERSION = re.compile(r"(@version\s+)(\d+([,]? \d+)*)+")
OCT_TAG = r"(OCT-#\d+)"
TESTMETHODS = re.compile(r"(@testmethods\s+)([^@]+)")
TEST = re.compile(r"(@test\s+)([^@]+)")
19 changes: 10 additions & 9 deletions lobster/tools/cpptest/parser/requirements_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@


class ParserForRequirements:
@staticmethod

def __init__(self, regex_list: list = [], codebeamer_url: str = ''):
self.regex_list = regex_list
self.codebeamer_url = codebeamer_url

def collect_test_cases_for_test_files(
test_files: List[Path],
codebeamer_url: str = "",
self,
test_files: List[Path]
) -> List:
"""
Parse a list of source files for test cases
Expand All @@ -22,7 +26,6 @@ def collect_test_cases_for_test_files(
----------
test_files: List[Path]
Source files to parse
codebeamer_url: str
Returns
-------
Expand All @@ -33,15 +36,14 @@ def collect_test_cases_for_test_files(

for file in set(test_files):
file_test_cases = (
ParserForRequirements.collect_test_cases(file, codebeamer_url))
self.collect_test_cases(file))
test_cases.extend(file_test_cases)

return test_cases

@staticmethod
def collect_test_cases(
self,
file: Path,
codebeamer_url: str = "",
) -> List[TestCase]:
"""
Parse a source file for test cases
Expand All @@ -50,7 +52,6 @@ def collect_test_cases(
----------
file: Path
Source file to parse
codebeamer_url: str
Returns
-------
Expand All @@ -69,7 +70,7 @@ def collect_test_cases(
test_cases = []

for i in range(0, len(lines)):
test_case = TestCase.try_parse(file, lines, i, codebeamer_url)
test_case = TestCase.try_parse(file, lines, i, self.regex_list, self.codebeamer_url)

if test_case:
test_cases.append(test_case)
Expand Down

0 comments on commit 2f038ec

Please sign in to comment.