diff --git a/docs/components/datarouter/detailed_design/_assets/activity_watchdog_session_lifecycle.puml b/docs/components/datarouter/detailed_design/_assets/activity_watchdog_session_lifecycle.puml new file mode 120000 index 000000000..d20c1ee2a --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/activity_watchdog_session_lifecycle.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/activity_watchdog_session_lifecycle.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/client_session_interaction_sequence.puml b/docs/components/datarouter/detailed_design/_assets/client_session_interaction_sequence.puml new file mode 120000 index 000000000..dda0385b6 --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/client_session_interaction_sequence.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/client_session_interaction_sequence.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/context-ecu.puml b/docs/components/datarouter/detailed_design/_assets/context-ecu.puml new file mode 120000 index 000000000..9f36b07eb --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/context-ecu.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/context-ecu.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/context-highlevel.puml b/docs/components/datarouter/detailed_design/_assets/context-highlevel.puml new file mode 120000 index 000000000..bc106c006 --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/context-highlevel.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/context-highlevel.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/context-sw-units.puml b/docs/components/datarouter/detailed_design/_assets/context-sw-units.puml new file mode 120000 index 000000000..317f4c492 --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/context-sw-units.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/context-sw-units.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/datarouter_units.puml b/docs/components/datarouter/detailed_design/_assets/datarouter_units.puml new file mode 120000 index 000000000..331f284af --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/datarouter_units.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/datarouter_units.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/detail-ipc.puml b/docs/components/datarouter/detailed_design/_assets/detail-ipc.puml new file mode 120000 index 000000000..d3c7a061b --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/detail-ipc.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/detail-ipc.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/dlt_message_filtering_backend.puml b/docs/components/datarouter/detailed_design/_assets/dlt_message_filtering_backend.puml new file mode 120000 index 000000000..3fba0fd9e --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/dlt_message_filtering_backend.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/dlt_message_filtering_backend.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/dlt_message_filtering_frontend.puml b/docs/components/datarouter/detailed_design/_assets/dlt_message_filtering_frontend.puml new file mode 120000 index 000000000..8711734d7 --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/dlt_message_filtering_frontend.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/dlt_message_filtering_frontend.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/file_transfer_feature_class_diagram.puml b/docs/components/datarouter/detailed_design/_assets/file_transfer_feature_class_diagram.puml new file mode 120000 index 000000000..95d734c3a --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/file_transfer_feature_class_diagram.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/file_transfer_feature_class_diagram.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/package-datarouter.puml b/docs/components/datarouter/detailed_design/_assets/package-datarouter.puml new file mode 120000 index 000000000..4949fee57 --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/package-datarouter.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/package-datarouter.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/seq-trace.puml b/docs/components/datarouter/detailed_design/_assets/seq-trace.puml new file mode 120000 index 000000000..757bff5ed --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/seq-trace.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/seq-trace.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/seq_kvs_threads_sequence_diagram.puml b/docs/components/datarouter/detailed_design/_assets/seq_kvs_threads_sequence_diagram.puml new file mode 120000 index 000000000..9ad8e315d --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/seq_kvs_threads_sequence_diagram.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/seq_kvs_threads_sequence_diagram.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/_assets/sequence_early_disconnect_race.puml b/docs/components/datarouter/detailed_design/_assets/sequence_early_disconnect_race.puml new file mode 120000 index 000000000..da9e98e7f --- /dev/null +++ b/docs/components/datarouter/detailed_design/_assets/sequence_early_disconnect_race.puml @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/design/uml/sequence_early_disconnect_race.puml \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/chklst_impl_inspection.rst b/docs/components/datarouter/detailed_design/chklst_impl_inspection.rst new file mode 100644 index 000000000..aab8a96ec --- /dev/null +++ b/docs/components/datarouter/detailed_design/chklst_impl_inspection.rst @@ -0,0 +1,272 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. document:: Datarouter Implementation Inspection Checklist + :id: doc__datarouter_impl_inspection + :status: draft + :version: 1 + :safety: QM + :security: YES + :realizes: wp__sw_implementation_inspection + +Implementation Inspection Checklist +=================================== + +Purpose +------- + +The purpose of this checklist is to collect the topics to be checked during implementation, +i.e. in the detailed design and the source code of the units. + +The checklist shall be agnostic to which programming language is used. Differences shall be treated +by linking to C++ or Rust specific documentation. + +Conduct +------- + +As described in the concept :need:`doc_concept__wp_inspections` the following "inspection roles" are expected to be filled: + +- content responsible (author): +- reviewer: +- moderator: + +Checklist +--------- + +It is mandatory to fill in the "passed" column with "yes" or "no" for each checklist item and additionally to add in the remarks why it is passed or not passed. +In case of "no" an issue link to the issue tracking system has to be added in the last column (if not solved in the same issue). +See also :need:`doc_concept__wp_inspections` for further information about reviews in general and inspection in particular. + +Scope: this checklist covers the Datarouter daemon (:need:`comp__datarouter`, ``score/datarouter``). +The parts of :doc:`logging_architecture` about ``mw::log`` are context and were not compared with the code. + +.. list-table:: Implementation Checklist + :header-rows: 1 + :widths: 10,25,30,6,35,20 + + * - Review ID + - Acceptance Criteria + - Guidance + - Passed + - Remarks + - Issue link + * - IMPL_01_01 + - Is the design according to guidelines? + - see :need:`gd_temp__detailed_design` and :need:`doc_concept__imp_concept` + (e.g. are the views done with the proposed UML diagrams) + - yes + - Detailed design structure and UML views were reviewed against the template. + The diagrams pass the ``architectural_design`` target + ``//score/datarouter/doc/design:datarouter_architectural_design``. + Sources remain in ``score/datarouter/doc/design`` and are included through + symlinks. + - + * - IMPL_01_02 + - Is the implementation according to specification? + - Check if the linked component requirements are fulfilled + and detailed design also matches architecture description. + - no + - The detailed design matches the component architecture (units, interfaces, + see :doc:`index`). Component requirements without a test link were linked + to existing tests. + + Following issues need to be addressed: + + - Nothing tests that messages are dropped when a source exceeds its quota + (:need:`comp_req__data_router__dlt_quota_bw_reduction`). + ``DataRouter::SourceSession`` has no unit test. + - Close remaining requirement-to-test traceability gaps: `#319 `_ + - Requirement tests: `#319 `_. + Other points: To be added. + * - IMPL_01_03 + - Are the design decisions and constraints documented? + - Check also for plausibility of these. + - no + - The decisions and constraints in :doc:`index` were inspected against the + code and refer to diagrams. + + Following issues need to be addressed: + + - Constraints that are only visible in the code and in no diagram. Show + them in the diagrams: + + - Watchdog values (1000 ms deadline, 3 misses): `watchdog defaults in AcquireWatchdogConfig`_ + - Tick of the worker thread (100 ms): `kTimeoutInMs in RunWorkerThread`_ + - Statistics period (10 s): `kStatisticsLogPeriodUs in socketserver.cpp`_ + - Order of the filters: `FilterAndCall in dlt_log_server.h`_ + - Build flags: `flags in build_configuration_flags/BUILD`_ + - Path of ``log-channels.json``: `kLogChannelsPath in socketserver.cpp`_ + - Handling of ``ENOBUFS``: `ENOBUFS check in NotifyAcquireRequest`_ + - Input from clients is untrusted: `unsupported message types in message_passing_server.cpp`_ + - No diagram shows the bandwidth quota per source: `CheckAndSetQuotaEnforcement in data_router.cpp`_ + - :doc:`shm_apis` describes a POSIX mutex and a Datarouter that modifies + the shared memory. The code uses wait-free alternating buffers and a + read-only mapping. Correct the text. + - To be added + * - IMPL_01_04 + - Are all external libraries used by the component specified in the detailed design? + - Check the automated dependency analysis. + Also make sure ASIL rated units also only use ASIL rated libraries. + - no + - Dependency and FFI metadata are maintained in Bazel. The direct + dependencies outside of ``//score/datarouter`` are listed with:: + + bazel query 'let l = kind(".*_library", //score/datarouter/...) except attr(testonly, 1, //score/datarouter/...) in labels(deps, $l) except //score/datarouter/...' --keep_going --output=label_kind + + Those without the ``FFI`` tag are listed with:: + + bazel query 'let l = kind(".*_library", //score/datarouter/...) except attr(testonly, 1, //score/datarouter/...) in (labels(deps, $l) except //score/datarouter/...) except attr(tags, FFI, labels(deps, $l))' --keep_going --output=label + + The Datarouter is QM, the rule "ASIL units only use ASIL-rated + libraries" does not apply to it. + + Dependency/configuration findings remain: + + - Correct the unresolved ``//score/mw/log/detail/dlt_trace`` + dependency (``mw::log`` backend, see the ``mw::log`` checklist). + - Replace the deprecated ``//score/mw/log:log`` target (removal in + v0.8, used by 9 non-test targets) with + ``@score_baselibs//score/mw/log``. Example: + `datarouter_lib dependencies in BUILD`_ + - Migrate uses of the deprecated ``high_resolution_steady_clock`` + target to the supported replacement after compatibility review. Used + in `HighResolutionSteadyClock in data_router.cpp`_ + - Remove the declared but unused dependencies ``string_literal`` + (`string_literal dependency in error/BUILD`_) and + ``static_reflection_with_serialization/visitor`` + (`visitor dependency in BUILD`_), if confirmed unused for all + affected configurations. + - Mark the mock libraries (``*_mock``) ``testonly``, for example the + `mock targets in BUILD`_. + - Remove ``visibility`` entries of packages that do not exist here + (``//platform/aas/...``, ``//pqr/...``): `visibility in BUILD`_, + `visibility in dlt_filetransfer_trigger_lib/BUILD`_ and + `visibility in test/ut/etc/BUILD`_. + - Get the safety ratings of ``score_communication`` ``message_passing``, + ``rapidjson``, ``score_baselibs`` ``result`` and ``string_manipulation`` + confirmed. + - To be added + * - IMPL_02_01 + - Are the static and dynamic code analysis reports verified for violations? + - All violations in ASIL related code must be justified. This includes the checks of coding guidelines. + - no + - Refer to the generated :doc:`verification report ` + and revision-specific CI results. A host run (Linux x86_64) of the unit + tests, clang-tidy, ASan/UBSan/LSan, TSan and Memcheck shows no findings. + Line and branch coverage are 82.6 % and 76.1 %. The QNX tests were not run. + + Following issues need to be addressed: + + - Resolve or justify coverage gaps (target 100 %), including the missing + unit tests of ``DataRouter`` and ``SourceSession`` see: `#318 `_ + - Integrate and verify the required CodeQL analysis see: `#336 `_. + - 9 of 159 suppressions have no justification and 94 use AUTOSAR C++14 + ids instead of MISRA C++:2023 (list in #318). + - Memcheck is not part of CI. + - + - Coverage: `#318 `_. + - CodeQL `#336 `_. + - Other points: To be added. + * - IMPL_02_02 + - Do manual checks, that are derived from the coding guideline, find no safety critical error? + - Check this for the programming language used (e.g. C++ , Rust ) + - no + - The manual MISRA C++:2023 checks are not done yet. The Datarouter has no + Rust code. + + Following issues found in `C++ guideline `_: + + - The coding guideline asks to avoid the prefix ``I`` for interfaces + (``IPersistentDictionary``, ``ISession``, ``ILogParser``, + ``ILogParserFactory``, ``IDiagnosticJobHandler``, ``IDltLogServer``). + Decide whether this is an accepted coding-guideline deviation. + - To be added + * - IMPL_03_01 + - Do the UID of the interface in component documentation match the implemented interface names of the unit? + - Compare interface UIDs (which contains the interface name) in component architecture/detailed design documentation + with public interfaces in source code (e.g. API headers, traits, public types/functions). + - no + - The detailed design maps each architecture interface to its source code + interface (:doc:`index`). + + Following issues found: + + - The names in the code do not match the UIDs, the mapping exists only in + the detailed design. Examples: :need:`logic_arc_int__logging__shm` is + implemented by ``ISharedMemoryReader`` (``score/mw/log``), + :need:`logic_arc_int__logging__session_ctrl_channel` by + ``MessagePassingServer``, ``ISession`` and ``ISessionHandle``. + - The DLT output (UDP multicast) and the configuration socket + (``UnixDomainServer``) have no UID in the architecture. + + Action: decide whether to adapt the UIDs, rename the interfaces or accept + the mapping as a documented deviation. + - To be added + * - IMPL_03_02 + - Are detailed design and source code consistent and is the respective traceability established ? + - Check if available static and dynamic design diagrams and the textual descriptions match the code + (e.g. naming of interfaces, units, functions/operations/messages, data types). + Check if the folder/file names of the units and its source code matches the intended functionality. + For example if a unit is named "communication" it should not contain code for "data processing". + - no + - The texts of :doc:`logging_architecture` and :doc:`shm_apis`, the README, + the units table and the diagrams were compared with the code. The session, + watchdog, early disconnect and configuration session diagrams match. + + Following issues found: + + - :doc:`logging_architecture` says that after the first quota violation all + further records of the source are dropped and the flag is not reset. The + code clears the flag with the statistics report every 10 s + (``DataRouter::SourceSession``). Decide which is intended and change that + one. + - ``file_transfer_feature_class_diagram.puml`` shows handler factories + that only tests use. In the code ``DltLogServer`` owns the handler + (``fthandler_``). + - ``package-datarouter.puml`` lists classes that do not exist + (``AraPerPersistentDictionary``, ``SysedrHandler`` and others). + - ``dlt_message_filtering_backend.puml`` is incomplete and names the wrong + file for the defaults (see ``DltLogServer::FilterAndCall``). + - The persistent logging diagrams (``persistent_logging_*``, + ``persistent-cleanup-*``) describe classes that are not in this + repository. Remove them or move them to the repository with the + implementation. + - ``ipc_status_quo.puml``, ``context-details.puml``, + ``seq-tracing-startup.puml`` and ``remote_logging.plantuml`` are used in + no document and were not compared with the code. + - The parts about ``mw::log`` (``seq-trace.puml``, + ``dlt_message_filtering_frontend.puml``) belong to the ``mw::log`` + frontend: `#327 `_ + - The README statistics example misses the fields ``rate``, ``quota rate``, + ``quota enforcement`` and ``IPC count``. + - ``mw::log`` context: `#327 `_. + Other points: To be added. + +.. _watchdog defaults in AcquireWatchdogConfig: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/include/daemon/message_passing_server.h#L66-L67 +.. _kTimeoutInMs in RunWorkerThread: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/src/daemon/message_passing_server.cpp#L224 +.. _kStatisticsLogPeriodUs in socketserver.cpp: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/src/daemon/socketserver.cpp#L56 +.. _FilterAndCall in dlt_log_server.h: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/include/daemon/dlt_log_server.h#L210-L235 +.. _flags in build_configuration_flags/BUILD: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/build_configuration_flags/BUILD +.. _kLogChannelsPath in socketserver.cpp: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/src/daemon/socketserver.cpp#L54 +.. _ENOBUFS check in NotifyAcquireRequest: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/src/daemon/message_passing_server.cpp#L579-L585 +.. _unsupported message types in message_passing_server.cpp: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/src/daemon/message_passing_server.cpp#L409-L412 +.. _CheckAndSetQuotaEnforcement in data_router.cpp: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/datarouter/data_router.cpp#L413-L443 +.. _datarouter_lib dependencies in BUILD: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/BUILD#L389 +.. _HighResolutionSteadyClock in data_router.cpp: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/datarouter/data_router.cpp#L170 +.. _string_literal dependency in error/BUILD: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/error/BUILD#L29 +.. _visitor dependency in BUILD: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/BUILD#L309 +.. _mock targets in BUILD: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/BUILD#L911-L983 +.. _visibility in BUILD: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/BUILD#L75 +.. _visibility in dlt_filetransfer_trigger_lib/BUILD: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/dlt_filetransfer_trigger_lib/BUILD#L30-L32 +.. _visibility in test/ut/etc/BUILD: https://github.com/eclipse-score/logging/blob/359df78e36f6bf1a3a0830cb61525302b0bd3460/score/datarouter/test/ut/etc/BUILD#L26 diff --git a/docs/components/datarouter/detailed_design/index.rst b/docs/components/datarouter/detailed_design/index.rst index efb80d272..c77843115 100644 --- a/docs/components/datarouter/detailed_design/index.rst +++ b/docs/components/datarouter/detailed_design/index.rst @@ -23,9 +23,185 @@ Detailed Design :security: NO :realizes: wp__sw_implementation[version==1] +Description +=========== + +The Datarouter (:need:`comp__datarouter`) is the DLT daemon. It reads the log +records of the clients from shared memory, filters them, and sends them as DLT +messages over UDP multicast. A client (``mw::log``) connects through a message +passing channel. The Datarouter asks the client to hand over a buffer by a +notification and reads it from the shared memory. It never blocks on a client. + +The design documents and PlantUML diagrams are in ``score/datarouter/doc/design``. +This folder links them by symbolic links, so that the files stay at their place in +the source tree. The source code is in ``score/datarouter``. Paths in this document +are relative to this directory unless noted otherwise. + +Design Decisions +---------------- + +The diagrams show how the design addresses the requirements and concerns. + +.. list-table:: + :header-rows: 1 + :widths: 45 55 + + * - Requirement or concern + - Diagram + * - Freedom from interference: the Datarouter is a separate process and only + reads the shared memory of the clients + - ``detail-ipc.puml`` and ``context-highlevel.puml`` in + :doc:`logging_architecture` + * - A client that does not answer must not stall the other clients + - ``client_session_interaction_sequence.puml`` in + `Dynamic Diagrams for Unit Interactions`_ + * - Stale sessions are cleaned up without losing readable data + - ``activity_watchdog_session_lifecycle.puml`` in + :doc:`logging_architecture` + * - A client that crashes while its session is created + - ``sequence_early_disconnect_race.puml`` in :doc:`logging_architecture` + * - Reduce the traffic early, own level per channel + - ``dlt_message_filtering_backend.puml`` in :doc:`logging_architecture` + * - Bandwidth quota per source + (:need:`comp_req__data_router__dlt_quota_bw_reduction`) + - No diagram shows the quota, see IMPL_01_03 in + :doc:`chklst_impl_inspection` + * - One code base for different deployments, stubs keep the interfaces + - ``file_transfer_feature_class_diagram.puml`` in + :doc:`logging_architecture` and ``package-datarouter.puml`` in + `Static Diagrams for Unit Interactions`_ + * - Deployment-specific configuration without a rebuild + (:need:`comp_req__data_router__dlt_multiple_channels`) + - ``dlt_message_filtering_backend.puml`` in :doc:`logging_architecture` and + ``seq_kvs_threads_sequence_diagram.puml`` in + `Dynamic Diagrams for Unit Interactions`_ + * - The persistent storage is provided by the platform + - ``seq_kvs_threads_sequence_diagram.puml`` in + `Dynamic Diagrams for Unit Interactions`_ + +Design Constraints +------------------ + +All requirements of the component apply, see :need:`doc__data_router_requirements`. +The diagrams show the constraints per building block. + +.. list-table:: + :header-rows: 1 + :widths: 20 40 40 + + * - Building block + - Constraint + - Diagram + * - DLT output + - UDP multicast only (:need:`comp_req__data_router__dlt_server`) + - ``context-highlevel.puml`` in :doc:`logging_architecture` + * - Configuration + - ``log-channels.json`` is mandatory, ``class-id.json`` is optional + - ``dlt_message_filtering_backend.puml`` in :doc:`logging_architecture` + * - Sessions + - One worker thread serves all sessions, the notification is non-blocking + - ``client_session_interaction_sequence.puml`` in + `Dynamic Diagrams for Unit Interactions`_ + * - Watchdog + - A session is removed after a limited number of missed acquire deadlines + - ``activity_watchdog_session_lifecycle.puml`` in + :doc:`logging_architecture` + * - Configuration sessions + - Changes are not persistent in this repository (stub dictionary) + - ``seq_kvs_threads_sequence_diagram.puml`` in + `Dynamic Diagrams for Unit Interactions`_ + +External Dependencies +--------------------- + +External dependencies and their relationships are defined in the Bazel BUILD +targets. The dependency analysis and its findings are part of the checklist item +IMPL_01_04 in :doc:`chklst_impl_inspection`. + +Rationale Behind Decomposition into Units +----------------------------------------- + +The component is split by responsibility so that each unit can be tested and +replaced independently. The units and their relations are shown in +``datarouter_units.puml`` and ``package-datarouter.puml`` in +`Static Diagrams for Unit Interactions`_. + +Static Diagrams for Unit Interactions +===================================== + +.. uml:: _assets/package-datarouter.puml + +.. uml:: _assets/context-sw-units.puml + +The units that appear in the sequence diagrams and their bindings: + +.. uml:: _assets/datarouter_units.puml + +The diagrams are validated by the ``architectural_design`` target +``//score/datarouter/doc/design:datarouter_architectural_design``. The interface +names in the unit diagram follow the convention of the validator (``I``) +and are not interfaces of the code. + +Further static diagrams are part of :doc:`logging_architecture`. + +Dynamic Diagrams for Unit Interactions +====================================== + +The session handling between a client and the Datarouter: + +.. uml:: _assets/client_session_interaction_sequence.puml + +The configuration session: + +.. uml:: _assets/seq_kvs_threads_sequence_diagram.puml + +Further dynamic diagrams (early disconnect, watchdog, filtering) are part of +:doc:`logging_architecture`. + +Units within the Component +========================== + +The decomposition into units is given by the directory and file structure; a unit +belongs to this component through its location. Attributes, behavior and the +interfaces of a unit are documented in the source code (public headers). Paths are +relative to ``score/datarouter`` of this repository. + +Interfaces of the Component +--------------------------- + +The interfaces of the component architecture and the external interfaces are +realized by the following source code interfaces. The interface documentation is +part of the headers. + +.. list-table:: + :header-rows: 1 + :widths: 30 35 35 + + * - Architecture interface + - Source code interface + - Realizing units + * - :need:`logic_arc_int__logging__shm` + - ``ISharedMemoryReader`` (``score_logging`` ``score/mw/log``), used by + ``SourceSession`` + - Data router core + * - :need:`logic_arc_int__logging__session_ctrl_channel` + - ``MessagePassingServer`` with ``MessagePassingServer::ISession`` and + ``ISessionHandle``, messages in ``data_router_messages.h`` + - Message passing server, data router core + * - DLT over UDP multicast (:need:`comp_req__data_router__dlt_server`) + - ``UdpStreamOutput``, ``DltLogChannel`` + - DLT server and channels + * - Configuration client (Unix domain socket) + - ``UnixDomainServer::ISession``, ``IDiagnosticJobHandler`` + - Unix domain server, configuration + * - Command line (``-c``, ``-C``) + - ``Options`` + - Configuration + .. toctree:: :titlesonly: :maxdepth: 1 logging_architecture shm_apis + chklst_impl_inspection diff --git a/score/datarouter/doc/design/BUILD b/score/datarouter/doc/design/BUILD new file mode 100644 index 000000000..998255f7b --- /dev/null +++ b/score/datarouter/doc/design/BUILD @@ -0,0 +1,33 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "architectural_design", +) + +architectural_design( + name = "datarouter_architectural_design", + dynamic = [ + "uml/client_session_interaction_sequence.puml", + "uml/sequence_early_disconnect_race.puml", + "uml/seq_kvs_threads_sequence_diagram.puml", + ], + static = [ + "uml/context-sw-units.puml", + "uml/datarouter_units.puml", + "uml/detail-ipc.puml", + "uml/file_transfer_feature_class_diagram.puml", + "uml/package-datarouter.puml", + ], + visibility = ["//visibility:public"], +) diff --git a/score/datarouter/doc/design/logging_architecture.md b/score/datarouter/doc/design/logging_architecture.md index d0fe584bc..9c00eb601 100644 --- a/score/datarouter/doc/design/logging_architecture.md +++ b/score/datarouter/doc/design/logging_architecture.md @@ -63,7 +63,8 @@ The following constraints influenced the logging infrastructure design: ## Context The diagram below illustrates the logging framework context: -CONTEXT_ECU +```{uml} _assets/context-ecu.puml +``` Applications write log data through logging interfaces. @@ -79,7 +80,8 @@ The logging framework transmits data to the following sinks: ### Process structure -CONTEXT_HIGHLEVEL +```{uml} _assets/context-highlevel.puml +``` The logging framework implements multiple components to meet system goals: @@ -130,7 +132,16 @@ On the first call for a given type `T`, `LogEntry::Instance()` (a Meyers sing The diagram below illustrates the high-level class structure of the datarouter component. -PACKAGE_DATAROUTER +```{uml} _assets/package-datarouter.puml +``` + +The next diagram shows the software units of the datarouter, the shared memory and the two IPC paths: the message passing channel to the clients and, if the build flag `enable_dynamic_configuration` is set, the Unix domain server for configuration clients. + +```{uml} _assets/context-sw-units.puml +``` + +```{uml} _assets/detail-ipc.puml +``` ## Runtime view @@ -140,12 +151,14 @@ Applications access logging functionality through `mw::log`. Initialization stage 1 executes when the first log request occurs. This may occur in global object constructors before the `main()` function executes, causing implicit initialization that creates necessary singletons automatically. The activity diagram below depicts the first-run process: -SEQ_TRACE +```{uml} _assets/seq-trace.puml +``` ### mw::log implementation The `mw::log` implementation creates log records and commits them atomically to shared memory on flush. -DLT_MESSAGE_FILTERING_FRONTEND +```{uml} _assets/dlt_message_filtering_frontend.puml +``` ### Ring buffer and linear allocator buffer @@ -158,19 +171,28 @@ The Datarouter-Client Session uses [message_passing](https://github.com/eclipse- The main idea is to keep clients independent, so that one non-responsive client should not stall the datarouter. This matters because the datarouter serves all clients from a single thread, one after another on each periodic tick, so a single blocking call would hold up every other client. To avoid this, the datarouter asks for buffers (to read) using non-blocking QNX pulses (`IServerConnection::Notify()`), which return right away and never wait on the client. So if a client is slow or stuck, its pulse simply stays unanswered while the healthy clients keep getting served. See below for the full flow. -CLIENT_SESSION_INTERACTION_SEQUENCE +```{uml} _assets/client_session_interaction_sequence.puml +``` However, with such a design there are risks of stale sessions. A small per-session watchdog limits how long the datarouter waits for an acquire response. If a client keeps missing its deadline, the watchdog cleans up the stale session, but first it does a best-effort read of the client's last buffer so no logs are lost unnecessarily. See below. -ACTIVITY_WATCHDOG_SESSION_LIFECYCLE +```{uml} _assets/activity_watchdog_session_lifecycle.puml +``` The setup also handles an early-disconnect race, wherein if a client crashes while the datarouter is still building its session, the connect and disconnect paths work together to throw away the half-built session instead of keeping a dangling connection pointer. The client can then reconnect cleanly afterwards. See below. -SEQUENCE_EARLY_DISCONNECT_RACE +```{uml} _assets/sequence_early_disconnect_race.puml +``` ### datarouter -DLT_MESSAGE_FILTERING_BACKEND +```{uml} _assets/dlt_message_filtering_backend.puml +``` + +### File transfer + +```{uml} _assets/file_transfer_feature_class_diagram.puml +``` ### Application-side library configuration diff --git a/score/datarouter/doc/design/uml/context-sw-units.puml b/score/datarouter/doc/design/uml/context-sw-units.puml index 950e07c0e..47851f66e 100644 --- a/score/datarouter/doc/design/uml/context-sw-units.puml +++ b/score/datarouter/doc/design/uml/context-sw-units.puml @@ -16,7 +16,7 @@ frame ApplicationProcess { node AdaptiveApplication { component ApplicationLogic - component "score::mw::log" { + component "score::mw::log" as mwlog { component log_entry component "logging_serializer" as serializer component logger { @@ -42,7 +42,7 @@ frame ApplicationProcess { ConfigReader ..> LogConfig - ApplicationLogic --> "score::mw::log" : verbose + ApplicationLogic --> mwlog : verbose ApplicationLogic --> TRACE : non-verbose } diff --git a/score/datarouter/doc/design/uml/datarouter_units.puml b/score/datarouter/doc/design/uml/datarouter_units.puml new file mode 100644 index 000000000..c130de04c --- /dev/null +++ b/score/datarouter/doc/design/uml/datarouter_units.puml @@ -0,0 +1,129 @@ +' ******************************************************************************* +' Copyright (c) 2026 Contributors to the Eclipse Foundation +' +' See the NOTICE file(s) distributed with this work for additional +' information regarding copyright ownership. +' +' This program and the accompanying materials are made available under the +' terms of the Apache License Version 2.0 which is available at +' https://www.apache.org/licenses/LICENSE-2.0 +' +' SPDX-License-Identifier: Apache-2.0 +' ******************************************************************************* + +' Unit diagram required by the architectural_design validation: every participant +' of a sequence diagram is a unit here, and every connected pair of units calls +' each other in a sequence diagram. The interface names (caller and callee) follow +' the convention of the validator and are not code interfaces. + +@startuml component_diagram + +skinparam componentStyle rectangle +left to right direction + +title Units and unit bindings of the sequence diagrams of the datarouter + +package "Client session and datarouter" as pkg_session { + component "User Threads (Client A)" as UTA <> + component "SharedMemoryWriter (Client A)" as SHMA <> + component "QnxDispatchEngine (Client A)" as AE <> + component "QnxDispatchEngine (Client X)" as XE <> + component "Server Engine" as SE <> + component "MessagePassingServer worker thread" as MW <> + component "Watchdog Timer" as WD <> + component "DLT output" as DLT <> + component "Client (connecting)" as MC <> + component "OnConnectRequest" as OC <> + component "disconnect_callback" as DC <> +} + +package "Configuration session" as pkg_config { + component "DataRouterConfigurator App (outside this repository)" as DRConf <> + component "DiagnosticManager" as DiagM <> + component "DataRouterConfiguratorService" as DRConfService <> + component "UnixDomainClient" as UDC <> + component "UnixDomainServer" as UDS <> + component "UnixDomainSocket" as Socket <> + component "ConfigSession" as ConfigSession <> + component "DltLogServer" as DLTS <> + component "PersistentDictionary" as PD <> +} + +interface "IUTAAE" as IUTAAE +interface "IAESE" as IAESE +interface "IMWSE" as IMWSE +interface "IAESHMA" as IAESHMA +interface "IMWSHMA" as IMWSHMA +interface "IMWDLT" as IMWDLT +interface "IMWWD" as IMWWD +interface "IMCSE" as IMCSE +interface "ISEOC" as ISEOC +interface "ISEDC" as ISEDC +interface "IDiagMDRConfService" as IDiagMDRConfService +interface "IDRConfServiceUDC" as IDRConfServiceUDC +interface "IUDCUDS" as IUDCUDS +interface "IUDSSocket" as IUDSSocket +interface "IUDSConfigSession" as IUDSConfigSession +interface "IConfigSessionDLTS" as IConfigSessionDLTS +interface "IDLTSPD" as IDLTSPD +interface "IConfigSessionSocket" as IConfigSessionSocket +interface "IDRConfServiceDRConf" as IDRConfServiceDRConf + +UTA -( IUTAAE +AE )- IUTAAE + +AE -( IAESE +SE )- IAESE + +MW -( IMWSE +SE )- IMWSE + +AE -( IAESHMA +SHMA )- IAESHMA + +MW -( IMWSHMA +SHMA )- IMWSHMA + +MW -( IMWDLT +DLT )- IMWDLT + +MW -( IMWWD +WD )- IMWWD + +MC -( IMCSE +SE )- IMCSE + +SE -( ISEOC +OC )- ISEOC + +SE -( ISEDC +DC )- ISEDC + +DiagM -( IDiagMDRConfService +DRConfService )- IDiagMDRConfService + +DRConfService -( IDRConfServiceUDC +UDC )- IDRConfServiceUDC + +UDC -( IUDCUDS +UDS )- IUDCUDS + +UDS -( IUDSSocket +Socket )- IUDSSocket + +UDS -( IUDSConfigSession +ConfigSession )- IUDSConfigSession + +ConfigSession -( IConfigSessionDLTS +DLTS )- IConfigSessionDLTS + +DLTS -( IDLTSPD +PD )- IDLTSPD + +ConfigSession -( IConfigSessionSocket +Socket )- IConfigSessionSocket + +DRConfService -( IDRConfServiceDRConf +DRConf )- IDRConfServiceDRConf + +@enduml diff --git a/score/datarouter/doc/design/uml/detail-ipc.puml b/score/datarouter/doc/design/uml/detail-ipc.puml index 8d789c244..49d2ca6db 100644 --- a/score/datarouter/doc/design/uml/detail-ipc.puml +++ b/score/datarouter/doc/design/uml/detail-ipc.puml @@ -28,10 +28,7 @@ node "DatarouterConf" { } queue "SourceBuffer: MWSR buffer" as RB1 -note top of RB1 - Shared memory - allocated by Application -end note +note top of RB1 : Shared memory allocated by Application app -> msg_server : connect() config_client -> UnixDomainServer : connect() diff --git a/score/datarouter/doc/design/uml/file_transfer_feature_class_diagram.puml b/score/datarouter/doc/design/uml/file_transfer_feature_class_diagram.puml index c48a1423c..de99e5655 100644 --- a/score/datarouter/doc/design/uml/file_transfer_feature_class_diagram.puml +++ b/score/datarouter/doc/design/uml/file_transfer_feature_class_diagram.puml @@ -26,9 +26,7 @@ class StubFileTransferStreamHandler { } interface "StubFileTransferStreamHandler::IOutput" as StubIOutput { - + sendFTVerbose(score::cpp::span, - mw::log::LogLevel, dltid_t, dltid_t, - uint8_t, uint32_t): void + + sendFTVerbose(score::cpp::span, mw::log::LogLevel, dltid_t, dltid_t, uint8_t, uint32_t): void } class FileTransferStreamHandler { @@ -57,29 +55,22 @@ class FileTransferStreamHandler { } interface "FileTransferStreamHandler::IOutput" as FileIOutput { - + sendFTVerbose(score::cpp::span, - mw::log::LogLevel, dltid_t, dltid_t, - uint8_t, uint32_t): void + + sendFTVerbose(score::cpp::span, mw::log::LogLevel, dltid_t, dltid_t, uint8_t, uint32_t): void } class "dltserver::Output (Mock)" as MockOutput { + ~Output() - + MOCK_METHOD(sendFTVerbose, - (score::cpp::span, - mw::log::LogLevel, dltid_t, dltid_t, - uint8_t, uint32_t), (override)) + + sendFTVerbose(score::cpp::span, mw::log::LogLevel, dltid_t, dltid_t, uint8_t, uint32_t): void } class "dltserver::Output" as Output { + ~Output() - + sendFTVerbose(score::cpp::span, - mw::log::LogLevel, dltid_t, dltid_t, - uint8_t, uint32_t): void + + sendFTVerbose(score::cpp::span, mw::log::LogLevel, dltid_t, dltid_t, uint8_t, uint32_t): void } class "FileTransferHandlerFactory" as Factory { + create(): std::unique_ptr - # FileTransferHandlerFactory() = default + # FileTransferHandlerFactory() } class StubFileTransferHandlerFactory { @@ -97,8 +88,7 @@ class FileTransferStreamHandlerFactory { } class DltLogServer { - + createFileTransferHandler(): - std::unique_ptr + + createFileTransferHandler(): std::unique_ptr } class "score::logging::FileTransferEntry" as FileTransferEntry { @@ -109,26 +99,18 @@ class "score::logging::FileTransferEntry" as FileTransferEntry { } interface "score::logging::IFileTransfer" as IFileTransfer { - + TransferFile(const std::string& file_name, - const bool delete_file): void + + TransferFile(const std::string& file_name, const bool delete_file): void } class "score::logging::FileTransfer" as FileTransfer { - appid_: std::string - ctxid_: std::string -- - + FileTransfer(const std::string& appid, - const std::string& ctxid) + + FileTransfer(const std::string& appid, const std::string& ctxid) + TransferFile(const std::string&, bool): void } -note bottom of StubFileTransferHandlerFactory -#if defined(ENABLE_FILETRANSFER_FEATURE) - using HandlerType = FileTransferStreamHandlerFactory; -#else - using HandlerType = StubFileTransferHandlerFactory; -#endif -end note +note bottom of StubFileTransferHandlerFactory : HandlerType is FileTransferStreamHandlerFactory if ENABLE_FILETRANSFER_FEATURE is defined, otherwise StubFileTransferHandlerFactory TypeHandler <|.. StubFileTransferStreamHandler TypeHandler <|.. FileTransferStreamHandler diff --git a/score/datarouter/doc/design/uml/seq_kvs_threads_sequence_diagram.puml b/score/datarouter/doc/design/uml/seq_kvs_threads_sequence_diagram.puml index c26dc20a0..867dba2ab 100644 --- a/score/datarouter/doc/design/uml/seq_kvs_threads_sequence_diagram.puml +++ b/score/datarouter/doc/design/uml/seq_kvs_threads_sequence_diagram.puml @@ -16,8 +16,8 @@ participant "DataRouterConfigurator App" as DRConf participant "DiagnosticManager" as DiagM participant "DataRouterConfiguratorService" as DRConfService -participant "UnixDomainClient" as Client -participant "UnixDomainServer" as Server +participant "UnixDomainClient" as UDC +participant "UnixDomainServer" as UDS participant "UnixDomainSocket" as Socket participant "ConfigSession" as ConfigSession participant "DltLogServer" as DLTS @@ -39,16 +39,16 @@ note over DRConfService Initializes runtime environment for diagnostic jobs. end note -DRConfService -> Client: send_dlt_config_command +DRConfService -> UDC: send_dlt_config_command note over Client The server creates a ConfigSession to process client commands and maintains the session for communication. end note -Client -> Server: send_dlt_config_command -Server -> Socket: receive_dlt_config_command -Socket -> Server: forward_dlt_config_command -Server -> ConfigSession: process_dlt_config_command +UDC -> UDS: send_dlt_config_command +UDS -> Socket: receive_dlt_config_command +Socket -> UDS: forward_dlt_config_command +UDS -> ConfigSession: process_dlt_config_command ConfigSession -> DLTS: Process command note over DLTS @@ -66,15 +66,15 @@ end note DLTS -> ConfigSession: Return diagnostic job response ConfigSession -> Socket: forward_diag_job_response -Socket -> Server: forward_diag_job_response -Server -> Client: diag_job_response +Socket -> UDS: forward_diag_job_response +UDS -> UDC: diag_job_response -Client -> DRConfService: diag_job_response +UDC -> DRConfService: diag_job_response DRConfService -> DRConf: diag_job_result deactivate DRConf deactivate DRConfService -deactivate Server +deactivate UDS deactivate Socket deactivate ConfigSession deactivate DLTS diff --git a/score/datarouter/doc/design/uml/sequence_early_disconnect_race.puml b/score/datarouter/doc/design/uml/sequence_early_disconnect_race.puml index 4362a6366..5448d18bb 100644 --- a/score/datarouter/doc/design/uml/sequence_early_disconnect_race.puml +++ b/score/datarouter/doc/design/uml/sequence_early_disconnect_race.puml @@ -19,7 +19,7 @@ skinparam sequenceMessageAlign center skinparam responseMessageBelowArrow true box "Client Process" #LightBlue - participant "Client" as C + participant "Client" as MC end box box "Datarouter Process" #LightGreen @@ -30,7 +30,7 @@ end box == Client sends kConnect, then crashes == -C -> SE : kConnect(appid, uid, pid) +MC -> SE : kConnect(appid, uid, pid) SE -> OC : MessageCallback → OnConnectRequest() note over OC @@ -41,7 +41,7 @@ end note OC -> OC : Release mutex_\nCall factory_(pid, conn, ...) -C -[#red]x C : **Client crashes / exits** +MC -[#red]> MC : **Client crashes / exits** SE -> DC : disconnect_callback(pid) diff --git a/score/datarouter/test/ut/ut_logging/test_dltserver.cpp b/score/datarouter/test/ut/ut_logging/test_dltserver.cpp index 8c72c7ba4..bb49f7f2d 100644 --- a/score/datarouter/test/ut/ut_logging/test_dltserver.cpp +++ b/score/datarouter/test/ut/ut_logging/test_dltserver.cpp @@ -172,12 +172,22 @@ TEST_F(DltServerCreatedWithoutConfigFixture, IsOutputEnabledReflectsDltEnabled) } TEST_F(DltServerCreatedWithoutConfigFixture, QuotaEnforcementEnabledExpectFalse) { + RecordProperty("PartiallyVerifies", "comp_req__data_router__dlt_quota_bw_reduction"); + RecordProperty("Description", "Check that the quota enforcement of the DLT server is off if it is not configured."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "requirements-analysis"); + DltLogServer dlt_server(s_config, read_callback.AsStdFunction(), write_callback.AsStdFunction(), true); EXPECT_FALSE(dlt_server.GetQuotaEnforcementEnabled()); } TEST_F(DltServerCreatedWithoutConfigFixture, QuotaEnforcementEnabledExpectTrue) { + RecordProperty("PartiallyVerifies", "comp_req__data_router__dlt_quota_bw_reduction"); + RecordProperty("Description", "Check that the DLT server takes over the configured quota enforcement."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "requirements-analysis"); + s_config.quota_enforcement_enabled = true; DltLogServer dlt_server(s_config, read_callback.AsStdFunction(), write_callback.AsStdFunction(), true); EXPECT_TRUE(dlt_server.GetQuotaEnforcementEnabled()); diff --git a/score/datarouter/test/ut/ut_logging/test_socketserver_config.cpp b/score/datarouter/test/ut/ut_logging/test_socketserver_config.cpp index e806e3612..fe1bae381 100644 --- a/score/datarouter/test/ut/ut_logging/test_socketserver_config.cpp +++ b/score/datarouter/test/ut/ut_logging/test_socketserver_config.cpp @@ -49,6 +49,13 @@ std::string PrepareLogChannelsPath(const std::string& file_name) TEST(SocketserverConfigTest, ReadCorrectLogChannelsNoErrorsExpected) { + RecordProperty("PartiallyVerifies", + "comp_req__data_router__dlt_multiple_channels, comp_req__data_router__dlt_message_filtering"); + RecordProperty("Description", + "Check that channels, assignments, thresholds and the filtering state are read from the file."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "requirements-analysis"); + const auto result = ReadStaticDlt(PrepareLogChannelsPath("log-channels.json").c_str()); EXPECT_TRUE(result.has_value()); EXPECT_THAT(result.value().channels, SizeIs(3)); @@ -83,6 +90,11 @@ TEST(SocketserverConfigTest, JsonEmptyChannelsErrorExpected) TEST(SocketserverConfigTest, JsonFilteringEnabledExpectConfigFilterTrue) { + RecordProperty("PartiallyVerifies", "comp_req__data_router__dlt_message_filtering"); + RecordProperty("Description", "Check that the filtering state is read from the channel configuration file."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "requirements-analysis"); + const auto result = ReadStaticDlt(PrepareLogChannelsPath("log-channels-filtering-enabled.json").c_str()); EXPECT_TRUE(result.has_value()); EXPECT_TRUE(result.value().filtering_enabled); @@ -90,6 +102,12 @@ TEST(SocketserverConfigTest, JsonFilteringEnabledExpectConfigFilterTrue) TEST(SocketserverConfigTest, JsonQuotasEnabledExpectConfigFilterTrue) { + RecordProperty("PartiallyVerifies", "comp_req__data_router__dlt_bw_quota_config"); + RecordProperty("Description", + "Check that the overall and per-application bandwidth quotas are read from the file."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "requirements-analysis"); + const auto result = ReadStaticDlt(PrepareLogChannelsPath("log-channels-quotas.json").c_str()); ASSERT_TRUE(result.has_value()); EXPECT_EQ(result.value().throughput.overall_mbps, 100); @@ -99,6 +117,12 @@ TEST(SocketserverConfigTest, JsonQuotasEnabledExpectConfigFilterTrue) TEST(SocketserverConfigTest, JsonQuotasEnabledActivated) { + RecordProperty("PartiallyVerifies", "comp_req__data_router__dlt_quota_bw_reduction"); + RecordProperty("Description", + "Check that the quota enforcement can be activated by the quota configuration attribute."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "requirements-analysis"); + const auto result = ReadStaticDlt(PrepareLogChannelsPath("log-channels-quotas-activated.json").c_str()); ASSERT_TRUE(result.has_value()); EXPECT_TRUE(result.value().quota_enforcement_enabled); @@ -106,6 +130,12 @@ TEST(SocketserverConfigTest, JsonQuotasEnabledActivated) TEST(SocketserverConfigTest, JsonQuotasEnabledDeactivated) { + RecordProperty("PartiallyVerifies", "comp_req__data_router__dlt_quota_bw_reduction"); + RecordProperty("Description", + "Check that the quota enforcement can be deactivated by the quota configuration attribute."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "requirements-analysis"); + const auto result = ReadStaticDlt(PrepareLogChannelsPath("log-channels-quotas-deactivated.json").c_str()); ASSERT_TRUE(result.has_value()); EXPECT_FALSE(result.value().quota_enforcement_enabled); diff --git a/score/datarouter/test/ut/ut_logging/test_udp_stream_output.cpp b/score/datarouter/test/ut/ut_logging/test_udp_stream_output.cpp index 59477e442..f42055107 100644 --- a/score/datarouter/test/ut/ut_logging/test_udp_stream_output.cpp +++ b/score/datarouter/test/ut/ut_logging/test_udp_stream_output.cpp @@ -164,6 +164,11 @@ TEST_F(UdpStreamOutputFixture, SendMethodShallFailIfSendmmsgFailed) TEST_F(UdpStreamOutputFixture, SendMethodShallSucceedIfSendmmsgSucceeded) { + RecordProperty("PartiallyVerifies", "comp_req__data_router__dlt_server"); + RecordProperty("Description", "Check that DLT messages are sent over the UDP socket output."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "requirements-analysis"); + // When mocking socket's sendmmsg to return error. EXPECT_CALL(*sock_mock_, sendmmsg(_, _, _, _)) .Times(Exactly(1))