Skip to content

Commit

Permalink
LOBSTER-Cpptest tool to use configuration files
Browse files Browse the repository at this point in the history
- Replaced command-line arguments with a YAML-based configuration file for improved usability and maintainability.
- Simplifies parameter management and enhances readability.
  • Loading branch information
SurajBDeore committed Dec 11, 2024
1 parent 3105b8e commit 9de144b
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 65 deletions.
53 changes: 25 additions & 28 deletions lobster/tools/cpptest/cpptest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
# License along with this program. If not, see
# <https://www.gnu.org/licenses/>.

import json
import sys
import argparse
import os.path
from copy import copy
from enum import Enum

import yaml
from lobster.items import Tracing_Tag, Activity
from lobster.location import File_Reference
from lobster.io import lobster_write
Expand Down Expand Up @@ -66,19 +65,19 @@ class RequirementTypes(Enum):

def parse_config_file(file_name: str) -> dict:
"""
Parse the configuration dictionary from given config file.
Parse the configuration dictionary from the given YAML config file.
The configuration dictionary for cpptest must contain the OUTPUT and
CODEBEAMER_URL keys.
Each output configuration dictionary contains a file name as key and
a value dictionary containing the keys MARKERS and KIND.
The supported values for the MARKERS list are specified in
The configuration dictionary for cpptest must contain the `output` and
`codebeamer_url` keys.
Each output configuration dictionary contains a file name as a key and
a value dictionary containing the keys `markers` and `kind`.
The supported values for the `markers` list are specified in
SUPPORTED_REQUIREMENTS.
Parameters
----------
file_name : str
The file name of the cpptest config file.
The file name of the cpptest YAML config file.
Returns
-------
Expand All @@ -88,17 +87,17 @@ def parse_config_file(file_name: str) -> dict:
Raises
------
Exception
If the config dict does not contain the required keys
or contains not supported values.
If the config dictionary does not contain the required keys
or is improperly formatted.
"""
if not os.path.isfile(file_name):
raise ValueError(f'{file_name} is not an existing file!')

with open(file_name, "r", encoding='utf-8') as file:
config_dict: dict = json.loads(file.read())
config_dict = yaml.safe_load(file)

if (OUTPUT not in config_dict.keys() or
CODEBEAMER_URL not in config_dict.keys()):
if (not config_dict or OUTPUT not in config_dict or
CODEBEAMER_URL not in config_dict):
raise ValueError(f'Please follow the right config file structure! '
f'Missing attribute "{OUTPUT}" and '
f'"{CODEBEAMER_URL}"')
Expand All @@ -107,17 +106,16 @@ def parse_config_file(file_name: str) -> dict:

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 MARKERS not in output_file_config_dict:
raise ValueError(f'Please follow the right config file structure! '
f'Missing attribute "{MARKERS}" for output file '
f'"{output_file}"')
if KIND not in output_file_config_dict.keys():
if KIND not in output_file_config_dict:
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:
for output_file_marker in output_file_config_dict.get(MARKERS, []):
if output_file_marker not in SUPPORTED_REQUIREMENTS:
raise ValueError(f'"{output_file_marker}" is not a supported '
f'"{MARKERS}" value '
Expand Down Expand Up @@ -377,20 +375,19 @@ def main():
and launch lobster_cpptest.
"""
# lobster-trace: cpptest_req.Dummy_Requirement
ap.add_argument("files",
nargs="+",
metavar="FILE|DIR")
ap.add_argument("--config-file",
help="path of the config file, it consists of "
"a requirement types as keys and "
"output filenames as value",
required=True,
default=None)
ap = argparse.ArgumentParser()
ap.add_argument("--config",
help=("Path to YAML file with arguments, "
"by default (cpptest-config.yaml)"),
default="cpptest-config.yaml")

options = ap.parse_args()

try:
config_dict = parse_config_file(options.config_file)
config_dict = parse_config_file(options.config)

options.files = config_dict.get("files", ["."])
config_dict.pop("files", None)

lobster_cpptest(
file_dir_list=options.files,
Expand Down
66 changes: 32 additions & 34 deletions packages/lobster-tool-cpptest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ markers in the comments of the source code.

## Tools

* `lobster-cpptest`: Extract requirements with specific references
from tests.
* `lobster-cpptest`: Extract requirements with dynamic refrences
from comments.

## Configuration

The tool requires a YAML configuration file to define its settings.
You must provide this file when running the tool to specify parameters to process.

## Usage

Expand All @@ -31,44 +36,37 @@ For this you have to provide a C/C++ test documentation with `markers`:
*/
TEST(RequirementTagTest1, RequirementsAsMultipleComments) {}
```
You have to provide a config-file which determines which `markers` should be extracted in which output-files.
The expected `kind` for each output-file should also be specified.
You can also provide parameters to specify which markers should be extracted from which files.
Additionally, you need to provide the Codebeamer URL.
* Note: If you want to extract the other tests with other `markers`,
you can use an empty list as `markers` value. Be aware in this case the tests do not have any references.
Examples:
```yaml
output:
component_tests.lobster:
markers:
- "@requirement"
kind: "req"
```config
{
"markers": [],
"kind": "req"
}
```
unit_tests.lobster:
markers:
- "@requiredby"
kind: "req"
In addition, you have to provide the codebeamer-url:

`Kind` can be either `req`, `imp` or `act`.

```config
{
"output": {
"unit_tests.lobster" :
{
"markers": ["@requirement"],
"kind": "req"
},
"components_tests.lobster" :
{
"markers": ["@requiredby", "@requirement"],
"kind": "imp"
}
},
"codebeamer_url": "https://codebeamer.example.com/test"
}
```
other_tests.lobster:
markers: []
kind: ""
For more information about how to setup cpp and config files take a look at [manual-lobster_cpptest](../../documentation/manual-lobster_cpptest.md)
codebeamer_url: "https://codebeamer.com"
```
You can also include CPP files in the YAML configuration file.

```yaml
files:
- 'path/to/source1.cpp'
- 'path/to/source2.cpp'
```
Note: File paths are accepted only in single quotes.
## Copyright & License information
Expand Down
11 changes: 11 additions & 0 deletions tests-unit/lobster-cpptest/data/cpptest-config_1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output:
component_tests.lobster:
markers: ["@requirement", "@requiredby"]
kind: "req"

other_tests.lobster:
markers: []

kind: ""

codebeamer_url: "https://codebeamer.com"
17 changes: 17 additions & 0 deletions tests-unit/lobster-cpptest/data/cpptest-config_2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
output:
component_tests.lobster:
markers:
- "@requirement"
kind: "req"

unit_tests.lobster:
markers:
- "@requiredby"
kind: "req"

other_tests.lobster:
markers: []

kind: ""

codebeamer_url: "https://codebeamer.com"
8 changes: 5 additions & 3 deletions tests-unit/lobster-cpptest/test_cpptest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def setUp(self):
self.test_case_file = str(Path(dirname(__file__), "data", "test_case.cpp"))
self.test_config_1 = str(Path(dirname(__file__), "data", "test_1.config"))
self.test_config_2 = str(Path(dirname(__file__), "data", "test_2.config"))
self.test_config_3 = str(Path(dirname(__file__), "data", "cpptest-config_1.yaml"))
self.test_config_4 = str(Path(dirname(__file__), "data", "cpptest-config_2.yaml"))

self.req_test_type = [RequirementTypes.REQS.value]
self.req_by_test_type = [RequirementTypes.REQ_BY.value]
Expand All @@ -46,7 +48,7 @@ def setUp(self):
self.component_test_lobster_file, self.other_test_lobster_file]

def test_parse_config_file_with_two_markers_for_two_outputs(self):
config_dict = parse_config_file(self.test_config_1)
config_dict = parse_config_file(self.test_config_4)
self.assertIsNotNone(config_dict)
self.assertIsInstance(config_dict, dict)
self.assertEqual(2, len(config_dict))
Expand Down Expand Up @@ -114,7 +116,7 @@ def test_parse_config_file_with_two_markers_for_two_outputs(self):
self.assertEqual('', other_test_kind_value)

def test_parse_config_file_with_two_markers_for_one_output(self):
config_dict = parse_config_file(self.test_config_2)
config_dict = parse_config_file(self.test_config_3)
self.assertIsNotNone(config_dict)
self.assertIsInstance(config_dict, dict)
self.assertEqual(2, len(config_dict))
Expand Down Expand Up @@ -314,7 +316,7 @@ def test_not_existing_file_dir(self):

def test_separate_output_config(self):
file_dir_list = [self.test_case_file]
config_dict: dict = parse_config_file(self.test_config_1)
config_dict: dict = parse_config_file(self.test_config_4)

lobster_cpptest(
file_dir_list=file_dir_list,
Expand Down

0 comments on commit 9de144b

Please sign in to comment.