diff --git a/lobster/tools/core/report/requirements.trlc b/lobster/tools/core/report/requirements.trlc index 0803a33c..28e16a41 100644 --- a/lobster/tools/core/report/requirements.trlc +++ b/lobster/tools/core/report/requirements.trlc @@ -162,3 +162,11 @@ req.System_Requirement_Aspect File_Not_Found { THEN the tool shall report "file not found " and exit with a non-zero return code. ''' } + +req.System_Requirement_Aspect Message_Trace_Coverage { + description = ''' + IF an item contains a "message" and traces to another item, + THEN the traced item shall have 100% coverage, + AND the item with the message shall have 0% coverage. + ''' +} diff --git a/tests_system/lobster_report/data/message_trace_coverage.conf b/tests_system/lobster_report/data/message_trace_coverage.conf new file mode 100644 index 00000000..e2bb8889 --- /dev/null +++ b/tests_system/lobster_report/data/message_trace_coverage.conf @@ -0,0 +1,8 @@ +requirements "Requirements" { + source: "trlc_message_trace_coverage.lobster"; +} + +implementation "Code" { + source: "python_message_trace_coverage.lobster"; + trace to: "Requirements"; +} diff --git a/tests_system/lobster_report/data/python_message_trace_coverage.lobster b/tests_system/lobster_report/data/python_message_trace_coverage.lobster new file mode 100644 index 00000000..74e22699 --- /dev/null +++ b/tests_system/lobster_report/data/python_message_trace_coverage.lobster @@ -0,0 +1,26 @@ +{ + "data": [ + { + "tag": "python software.Example", + "location": { + "kind": "file", + "file": ".\\software.py", + "line": 1, + "column": null + }, + "name": "software.Example", + "messages": ["trace"], + "just_up": [], + "just_down": [], + "just_global": [], + "refs": [ + "req example.adas_100" + ], + "language": "Python", + "kind": "Function" + } + ], + "generator": "lobster_python", + "schema": "lobster-imp-trace", + "version": 3 +} diff --git a/tests_system/lobster_report/data/report_message_trace_coverage.lobster b/tests_system/lobster_report/data/report_message_trace_coverage.lobster new file mode 100644 index 00000000..360eb8e7 --- /dev/null +++ b/tests_system/lobster_report/data/report_message_trace_coverage.lobster @@ -0,0 +1,102 @@ +{ + "schema": "lobster-report", + "version": 2, + "generator": "lobster_report", + "levels": [ + { + "name": "Requirements", + "kind": "requirements", + "items": [ + { + "tag": "req example.adas_100", + "location": { + "kind": "file", + "file": "./demo.trlc", + "line": 3, + "column": 13 + }, + "name": "example.adas_100", + "messages": [], + "just_up": [], + "just_down": [], + "just_global": [], + "ref_up": [], + "ref_down": [ + "python software.Example" + ], + "tracing_status": "OK", + "framework": "TRLC", + "kind": "Requirement", + "text": "keep the vehicle in lane.", + "status": null + } + ], + "coverage": 100.0 + }, + { + "name": "Code", + "kind": "implementation", + "items": [ + { + "tag": "python software.Example", + "location": { + "kind": "file", + "file": "./software.py", + "line": 1, + "column": null + }, + "name": "software.Example", + "messages": [ + "trace" + ], + "just_up": [], + "just_down": [], + "just_global": [], + "ref_up": [ + "req example.adas_100" + ], + "ref_down": [], + "tracing_status": "PARTIAL", + "language": "Python", + "kind": "Function" + } + ], + "coverage": 0.0 + } + ], + "policy": { + "Requirements": { + "name": "Requirements", + "kind": "requirements", + "traces": [], + "source": [ + { + "file": "trlc_message_trace_coverage.lobster" + } + ], + "needs_tracing_up": false, + "needs_tracing_down": true, + "breakdown_requirements": [ + [ + "Code" + ] + ] + }, + "Code": { + "name": "Code", + "kind": "implementation", + "traces": [ + "Requirements" + ], + "source": [ + { + "file": "python_message_trace_coverage.lobster" + } + ], + "needs_tracing_up": true, + "needs_tracing_down": false, + "breakdown_requirements": [] + } + }, + "matrix": [] +} diff --git a/tests_system/lobster_report/data/trlc_message_trace_coverage.lobster b/tests_system/lobster_report/data/trlc_message_trace_coverage.lobster new file mode 100644 index 00000000..fcbe9d54 --- /dev/null +++ b/tests_system/lobster_report/data/trlc_message_trace_coverage.lobster @@ -0,0 +1,25 @@ +{ + "data": [ + { + "tag": "req example.adas_100", + "location": { + "kind": "file", + "file": ".\\demo.trlc", + "line": 3, + "column": 13 + }, + "name": "example.adas_100", + "messages": [], + "just_up": [], + "just_down": [], + "just_global": [], + "framework": "TRLC", + "kind": "Requirement", + "text": "keep the vehicle in lane.", + "status": null + } + ], + "generator": "lobster-trlc", + "schema": "lobster-req-trace", + "version": 4 +} diff --git a/tests_system/lobster_report/test_zero_items_coverage.py b/tests_system/lobster_report/test_items_coverage.py similarity index 53% rename from tests_system/lobster_report/test_zero_items_coverage.py rename to tests_system/lobster_report/test_items_coverage.py index 226bb55d..9844756d 100644 --- a/tests_system/lobster_report/test_zero_items_coverage.py +++ b/tests_system/lobster_report/test_items_coverage.py @@ -3,7 +3,7 @@ LobsterReportSystemTestCaseBase) -class ReportZeroItemsCoverageTest(LobsterReportSystemTestCaseBase): +class ReportItemsCoverageTest(LobsterReportSystemTestCaseBase): def setUp(self): super().setUp() self._test_runner = self.create_test_runner() @@ -30,3 +30,25 @@ def test_zero_items_coverage(self): asserter.assertNoStdOutText() asserter.assertExitCode(0) asserter.assertOutputFiles() + + def test_items_message_trace_coverage(self): + # lobster-trace: core_report_req.Message_Trace_Coverage + self._test_runner.declare_input_file(self._data_directory / + "message_trace_coverage.conf") + self._test_runner.declare_input_file(self._data_directory / + "python_message_trace_coverage.lobster") + self._test_runner.declare_input_file(self._data_directory / + "trlc_message_trace_coverage.lobster") + + out_file = "report_message_trace_coverage.lobster" + self._test_runner.cmd_args.lobster_config = "message_trace_coverage.conf" + self._test_runner.cmd_args.out = out_file + self._test_runner.declare_output_file(self._data_directory / out_file) + + completed_process = self._test_runner.run_tool_test() + + asserter = Asserter(self, completed_process, self._test_runner) + asserter.assertNoStdErrText() + asserter.assertNoStdOutText() + asserter.assertExitCode(0) + asserter.assertOutputFiles()