diff --git a/score/mw/com/design/skeleton_proxy/README.md b/score/mw/com/design/skeleton_proxy/README.md
index d8958e391..81d96241b 100644
--- a/score/mw/com/design/skeleton_proxy/README.md
+++ b/score/mw/com/design/skeleton_proxy/README.md
@@ -92,6 +92,12 @@ The following sequence shows the instantiation of a service class up to its serv
+On construction, the generated skeleton (`DummySkeleton`) checks that all the bindings of its contained service elements
+(events/fields/methods) are valid. This is done by calling the `AreBindingsValid()` on `SkeletonBase`. This will then
+iterate over the maps of references to its service elements described [below](#binding-independent-level-registration-of-skeleton-eventsfields-at-their-parent-skeleton)
+and check if each binding was successfully created. If this is not the case, the construction of the skeleton instance
+returns an error.
+
#### Binding independent level Registration of skeleton events/fields at their parent skeleton
Due to our architectural constraints, the `impl::SkeletonBase` (the base class of the generated skeleton/`DummySkeleton`)
@@ -168,23 +174,10 @@ On `ProxyBase` level we have two types of methods:
a generated proxy instance, to detect, whether the instance can be successfully returned from
`static Result ::Create()` or not.
-The implementation of the latter one contains some indirection – again due to our architectural constraints, which
-are the same at proxy and skeleton side and have been laid out
-[here on the skeleton side](#binding-independent-level-registration-of-skeleton-eventsfields-at-their-parent-skeleton).
-
-The indirection is that for `ProxyBase::AreBindingsValid()` to work, the binding independent `impl::ProxyEvent`s set
-the member of its semantic parent `ProxyBase::are_service_element_bindings_valid_` to `false` during their construction,
-if they detect, that they don't have a valid underlying `pImpl` member of type `ProxyEventBindingBase` to dispatch to.
-This is an indication, that the binding specific implementation of the `ProxyEvent` couldn't be successfully created by
-the proxy side factories.
-
-So, the binding independent `impl::ProxyBase` doesn't "know" its semantically aggregated `ProxyEvent`s.
-Although the `ProxyEvent`s get a reference to their parent `ProxyBase` during construction (and therefore "know" their
-parent in the context of their `ctor`), they don't store this reference (as it isn't really needed currently and
-would require additional logic to update this reference if the parent `impl::ProxyBase` gets moved).
-Instead, they only set once (see above) the `ProxyBase::are_service_element_bindings_valid_` member variable of their
-parent during construction as this is currently the only feedback needed between proxy and its proxy events on binding
-independent level.
+Similarly to the skeleton side, the `impl::SkeletonBase` doesn't "know" its event/field/method children. Therefore,
+the `impl::ProxyEventBase` registers itself with the `impl::ProxyBase` in the same way as `impl::SkeletonEventBase`
+(as explained
+[here on the skeleton side](#binding-independent-level-registration-of-skeleton-eventsfields-at-their-parent-skeleton).
#### Binding level Registration of proxy events/fields at their parent proxy
@@ -192,30 +185,19 @@ On the binding **specific** level things look different!
I.e. the binding specific proxy needs to interact with its dependent/child proxy events of type `ProxyEventBindingBase`
(at least the `LoLa`/shared-memory specific does, so we introduced it on the `ProxyBinding` interface level) .
-Therefore, `impl::ProxyBinding` has a method `RegisterEventBinding` (and `UnregisterEventBinding`) and our `LoLa`
-binding specific proxy `lola::Proxy`, which implements `impl::ProxyBinding`, has a member `event_bindings_` (a map
-containing its child proxy events), which it populates in its implementation of `RegisterEventBinding` with its
-dependent proxy events.
-
-The call to `RegisterEventBinding` happens during creation of a binding independent `impl::ProxyEvent` via an `RAII`
-style member `event_binding_registration_guard_` of type `EventBindingRegistrationGuard`, which the `impl::ProxyEvent`
-owns.
-This `EventBindingRegistrationGuard` takes over two functionalities:
-
-- setting `ProxyBase::are_service_element_bindings_valid_` member of its parent ProxyBase instance (see previous chapter)
-- calling `RegisterEventBinding` on the underlying `ProxyBinding` of the given `ProxyBase` on construction of the
- `EventBindingRegistrationGuard` and calling `UnregisterEventBinding` on destruction. Since
- `event_binding_registration_guard_` is owned by the `impl::ProxyEvent`, the registration / unregistration is done on
- construction / destruction of an `impl::ProxyEvent`.
+Therefore, when each `lola::ProxyEvent` gets created (as a member of the generated proxy class), it registers itself
+at its parent `lola::Proxy` via `lola::Proxy::RegisterEvent()`. The `lola::Proxy` stores the reference to each
+child `lola::ProxyEvent`s in a map which it can later use.
So **after** construction of user facing generated proxy class instance (`DummyProxy`), we have the following structure
in place:
1. Only an instance of the generated proxy class gets returned from the call to `::Create()` in case its
binding on proxy level (its `pImpl` target) implementing `ProxyBinding` could be constructed and also for **all** its
- aggregated events/fields their related `ProxyEventBinding`s (`pImpl` targets) could be constructed.
+ aggregated events/fields their related `ProxyEventBinding`s (`pImpl` targets) could be constructed. If this is not
+ the case, then an error will be retrurned from `::Create()`.
2. The `ProxyBinding` (`ProxyBase::proxy_binding_`) has complete access to all its child events/fields as
- `ProxyBinding::RegisterEventBinding` has been called for all contained events/fields.
+ `lola::Proxy::RegisterEvent()` has been called for all contained events/fields.
#### Extract type agnostic code
diff --git a/score/mw/com/impl/bindings/lola/generic_proxy_event.cpp b/score/mw/com/impl/bindings/lola/generic_proxy_event.cpp
index ca5a39903..46a7c2751 100644
--- a/score/mw/com/impl/bindings/lola/generic_proxy_event.cpp
+++ b/score/mw/com/impl/bindings/lola/generic_proxy_event.cpp
@@ -31,6 +31,7 @@ GenericProxyEvent::GenericProxyEvent(Proxy& parent, const ElementFqId element_fq
proxy_event_common_{parent, element_fq_id, event_name},
meta_info_{parent.GetEventMetaInfo(element_fq_id)}
{
+ parent.RegisterEvent(event_name, *this);
}
Result GenericProxyEvent::Subscribe(const std::size_t max_sample_count) noexcept
diff --git a/score/mw/com/impl/bindings/lola/proxy.cpp b/score/mw/com/impl/bindings/lola/proxy.cpp
index e8cb56091..6fee41ca7 100644
--- a/score/mw/com/impl/bindings/lola/proxy.cpp
+++ b/score/mw/com/impl/bindings/lola/proxy.cpp
@@ -639,32 +639,6 @@ bool Proxy::IsEventProvided(const std::string_view event_name) const noexcept
return event_exists;
}
-void Proxy::RegisterEventBinding(const std::string_view service_element_name,
- ProxyEventBindingBase& proxy_event_binding) noexcept
-{
- // Suppress Autosar C++14 A8-5-3 states that auto variables shall not be initialized using braced initialization.
- // This is a false positive, we don't use auto here
- // coverity[autosar_cpp14_a8_5_3_violation : FALSE]
- std::lock_guard lock{proxy_event_registration_mutex_};
- const auto insert_result = event_bindings_.emplace(service_element_name, proxy_event_binding);
- SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(insert_result.second,
- "Failed to insert proxy event binding into event binding map.");
- proxy_event_binding.NotifyServiceInstanceChangedAvailability(is_service_instance_available_, GetSourcePid());
-}
-
-void Proxy::UnregisterEventBinding(const std::string_view service_element_name) noexcept
-{
- // Suppress Autosar C++14 A8-5-3 states that auto variables shall not be initialized using braced initialization.
- // This is a false positive, we don't use auto here
- // coverity[autosar_cpp14_a8_5_3_violation : FALSE]
- std::lock_guard lock{proxy_event_registration_mutex_};
- const auto number_of_elements_removed = event_bindings_.erase(service_element_name);
- if (number_of_elements_removed == 0U)
- {
- score::mw::log::LogWarn("lola") << "UnregisterEventBinding that was never registered. Ignoring.";
- }
-}
-
score::Result Proxy::SetupMethods()
{
auto enabled_method_data = GetMethodIdAndQueueSizeForEnabledMethods();
@@ -921,6 +895,16 @@ pid_t Proxy::GetSourcePid() const noexcept
return service_data_storage.skeleton_pid_;
}
+void Proxy::RegisterEvent(const std::string_view service_element_name,
+ ProxyEventBindingBase& proxy_event_binding) noexcept
+{
+ std::lock_guard lock{proxy_event_registration_mutex_};
+ const auto insert_result = event_bindings_.emplace(service_element_name, proxy_event_binding);
+ SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(insert_result.second,
+ "Failed to insert proxy event binding into event binding map.");
+ proxy_event_binding.NotifyServiceInstanceChangedAvailability(is_service_instance_available_, GetSourcePid());
+}
+
void Proxy::RegisterMethod(const UniqueMethodIdentifier method_id, ProxyMethod& proxy_method) noexcept
{
std::lock_guard lock{proxy_method_registration_mutex_};
diff --git a/score/mw/com/impl/bindings/lola/proxy.h b/score/mw/com/impl/bindings/lola/proxy.h
index c4cca4320..5cc7b26d1 100644
--- a/score/mw/com/impl/bindings/lola/proxy.h
+++ b/score/mw/com/impl/bindings/lola/proxy.h
@@ -167,24 +167,6 @@ class Proxy : public ProxyBinding
/// \return True if the event name exists, otherwise, false
bool IsEventProvided(const std::string_view event_name) const noexcept override;
- /// \brief Adds a reference to a Proxy service element binding to an internal map
- ///
- /// Will insert the provided ProxyEventBindingBase& into a map stored within the class which will be used to call
- /// NotifyServiceInstanceChangedAvailability on all saved Proxy service elements by the FindServiceHandler of
- /// find_service_guard_. It will then call NotifyServiceInstanceChangedAvailability on the provided
- /// ProxyEventBindingBase. Since this function first locks proxy_event_registration_mutex_, it is ensured that the
- /// provided Proxy service element will be notified synchronously about the availability of the provider and will
- /// then be notified of any future changes via the callback, without missing any notifications.
- void RegisterEventBinding(const std::string_view service_element_name,
- ProxyEventBindingBase& proxy_event_binding) noexcept override;
-
- /// \brief Removes the reference to a Proxy service element binding from an internal map
- ///
- /// This must be called by a Proxy service element before destructing to ensure that the FindService handler in
- /// find_service_guard_ does not call NotifyServiceInstanceChangedAvailability on a Proxy service element after it's
- /// been destructed.
- void UnregisterEventBinding(const std::string_view service_element_name) noexcept override;
-
score::Result SetupMethods() override;
QualityType GetQualityType() const noexcept;
@@ -198,6 +180,8 @@ class Proxy : public ProxyBinding
return proxy_instance_identifier_;
}
+ void RegisterEvent(const std::string_view service_element_name,
+ ProxyEventBindingBase& proxy_event_binding) noexcept;
void RegisterMethod(const UniqueMethodIdentifier method_id, ProxyMethod& proxy_method) noexcept;
private:
@@ -231,7 +215,7 @@ class Proxy : public ProxyBinding
HandleType handle_;
std::unordered_map> event_bindings_;
- /// Mutex which synchronises registration of Proxy service elements via Proxy::RegisterEventBinding with the
+ /// Mutex which synchronises registration of Proxy service elements via Proxy::RegisterEvent with the
/// FindServiceHandler in find_service_guard_ which will call NotifyServiceInstanceChangedAvailability on all
/// currently registered Proxy service elements.
std::mutex proxy_event_registration_mutex_;
diff --git a/score/mw/com/impl/bindings/lola/proxy_event.h b/score/mw/com/impl/bindings/lola/proxy_event.h
index 73c3e4bc2..be37fc505 100644
--- a/score/mw/com/impl/bindings/lola/proxy_event.h
+++ b/score/mw/com/impl/bindings/lola/proxy_event.h
@@ -66,6 +66,7 @@ class ProxyEvent final : public ProxyEventBinding
proxy_event_common_{parent, element_fq_id, event_name},
samples_{parent.GetEventDataStorage(element_fq_id)}
{
+ parent.RegisterEvent(event_name, *this);
}
ProxyEvent(const ProxyEvent&) = delete;
diff --git a/score/mw/com/impl/bindings/lola/proxy_event_test.cpp b/score/mw/com/impl/bindings/lola/proxy_event_test.cpp
index 06aea0d11..9f9921134 100644
--- a/score/mw/com/impl/bindings/lola/proxy_event_test.cpp
+++ b/score/mw/com/impl/bindings/lola/proxy_event_test.cpp
@@ -32,6 +32,21 @@
namespace score::mw::com::impl::lola
{
+
+class ProxyTestAttorney
+{
+ public:
+ explicit ProxyTestAttorney(Proxy& proxy) : proxy_{proxy} {}
+
+ const std::unordered_map>& GetEvents() const
+ {
+ return proxy_.event_bindings_;
+ }
+
+ private:
+ Proxy& proxy_;
+};
+
namespace
{
@@ -152,6 +167,10 @@ class LolaProxyEventFixture : public LolaProxyEventResources
using MyTypes = ::testing::Types;
TYPED_TEST_SUITE(LolaProxyEventFixture, MyTypes, );
+template
+using LolaProxyEventConstructionFixture = LolaProxyEventFixture;
+TYPED_TEST_SUITE(LolaProxyEventConstructionFixture, MyTypes, );
+
template
using LolaProxyEventGetNewSamplesFixture = LolaProxyEventFixture;
TYPED_TEST_SUITE(LolaProxyEventGetNewSamplesFixture, MyTypes, );
@@ -164,6 +183,22 @@ template
using LolaProxyEventDeathTest = LolaProxyEventFixture;
TYPED_TEST_SUITE(LolaProxyEventDeathTest, MyTypes, );
+TYPED_TEST(LolaProxyEventConstructionFixture, ConstructingRegistersEventWithParent)
+{
+ // Given a proxy with an events map which is initially empty
+ auto& events_map = ProxyTestAttorney(*this->proxy_).GetEvents();
+ ASSERT_EQ(events_map.size(), 0U);
+
+ // When constructing a ProxyEvent
+ this->GivenAProxyEvent(this->element_fq_id_, this->event_name_);
+
+ // Then the event should have been registered in the parent Proxy's map of events
+ EXPECT_EQ(events_map.size(), 1U);
+ auto registered_event_it = events_map.find(this->event_name_);
+ EXPECT_NE(registered_event_it, events_map.end());
+ EXPECT_EQ(®istered_event_it->second.get(), &(*this->test_proxy_event_));
+}
+
TYPED_TEST(LolaProxyEventGetNewSamplesFixture, CallsReceiverForEachAccessibleSample)
{
this->RecordProperty("Verifies", "SCR-14035773, SCR-21350367, SCR-6225206");
diff --git a/score/mw/com/impl/bindings/lola/proxy_test.cpp b/score/mw/com/impl/bindings/lola/proxy_test.cpp
index aa48abea2..48e05cfbe 100644
--- a/score/mw/com/impl/bindings/lola/proxy_test.cpp
+++ b/score/mw/com/impl/bindings/lola/proxy_test.cpp
@@ -427,14 +427,14 @@ TEST_F(ProxyAutoReconnectFixture, WhenStopFindServiceReturnsErrorOnProxyDestruct
// Then the program does not terminate
}
-TEST_F(ProxyAutoReconnectFixture, RegisterEventBindingCallsNotifyOnEventWithFalseWhenProviderInitiallyDoesNotExist)
+TEST_F(ProxyAutoReconnectFixture, RegisterEventCallsNotifyOnEventWithFalseWhenProviderInitiallyDoesNotExist)
{
const auto valid_find_service_handle = make_FindServiceHandle(10U);
mock_binding::ProxyEvent proxy_event{};
// Expecting that StartFindService is called but the handler is not called since the provider does not exist
- ON_CALL(service_discovery_mock_, StartFindService(_, EnrichedInstanceIdentifier{identifier_}))
- .WillByDefault(Return(valid_find_service_handle));
+ EXPECT_CALL(service_discovery_mock_, StartFindService(_, EnrichedInstanceIdentifier{identifier_}))
+ .WillOnce(Return(valid_find_service_handle));
// Then expecting that NotifyServiceInstanceChangedAvailability is called on the event with is_available false
const bool is_available{false};
@@ -445,10 +445,10 @@ TEST_F(ProxyAutoReconnectFixture, RegisterEventBindingCallsNotifyOnEventWithFals
EXPECT_NE(proxy_, nullptr);
// and the ProxyEvent registers itself with the Proxy
- proxy_->RegisterEventBinding("Event0", proxy_event);
+ proxy_->RegisterEvent("Event0", proxy_event);
}
-TEST_F(ProxyAutoReconnectFixture, RegisterEventBindingCallsNotifyOnEventWithTrueWhenProviderInitiallyExists)
+TEST_F(ProxyAutoReconnectFixture, RegisterEventCallsNotifyOnEventWithTrueWhenProviderInitiallyExists)
{
const auto valid_find_service_handle = make_FindServiceHandle(10U);
mock_binding::ProxyEvent proxy_event{};
@@ -470,10 +470,10 @@ TEST_F(ProxyAutoReconnectFixture, RegisterEventBindingCallsNotifyOnEventWithTrue
EXPECT_NE(proxy_, nullptr);
// and the ProxyEvent registers itself with the Proxy
- proxy_->RegisterEventBinding("Event0", proxy_event);
+ proxy_->RegisterEvent("Event0", proxy_event);
}
-TEST_F(ProxyAutoReconnectFixture, RegisterEventBindingCallsNotifyOnEventWithLatestValueFromFindServiceHandler)
+TEST_F(ProxyAutoReconnectFixture, RegisterEventCallsNotifyOnEventWithLatestValueFromFindServiceHandler)
{
const auto valid_find_service_handle = make_FindServiceHandle(10U);
mock_binding::ProxyEvent proxy_event_0{};
@@ -523,14 +523,14 @@ TEST_F(ProxyAutoReconnectFixture, RegisterEventBindingCallsNotifyOnEventWithLate
EXPECT_NE(proxy_, nullptr);
// and the first ProxyEvent registers itself with the Proxy
- proxy_->RegisterEventBinding("Event0", proxy_event_0);
+ proxy_->RegisterEvent("Event0", proxy_event_0);
// And then the FindService handler is called with an empty service handle container
ServiceHandleContainer empty_service_handle_container{};
saved_find_service_handler(empty_service_handle_container, valid_find_service_handle);
// and the second ProxyEvent registers itself with the Proxy
- proxy_->RegisterEventBinding("Event1", proxy_event_1);
+ proxy_->RegisterEvent("Event1", proxy_event_1);
// And then the FindService handler is called again with a non-empty service handle container
ServiceHandleContainer filled_service_handle_container{make_HandleType(identifier_)};
@@ -562,8 +562,8 @@ TEST_F(ProxyEventBindingFixture, RegisteringEventBindingWillCallNotifyServiceIns
// Expecting that NotifyServiceInstanceChangedAvailability will be called on the binding
EXPECT_CALL(mock_proxy_event_base_binding, NotifyServiceInstanceChangedAvailability(_, _));
- // When calling RegisterEventBinding
- proxy_->RegisterEventBinding(kDummyEventName, mock_proxy_event_base_binding);
+ // When calling RegisterEvent
+ proxy_->RegisterEvent(kDummyEventName, mock_proxy_event_base_binding);
}
TEST_F(ProxyEventBindingFixture,
@@ -582,47 +582,14 @@ TEST_F(ProxyEventBindingFixture,
InitialiseProxyWithCreate(identifier_);
// and that two bindings are registered
- proxy_->RegisterEventBinding(kDummyEventName, mock_proxy_event_base_binding);
- proxy_->RegisterEventBinding("some_other_event", mock_proxy_event_base_binding_2);
-
- // When the find service handler is called
- const auto find_service_handler = find_service_handler_promise_.get_future().get();
- find_service_handler(ServiceHandleContainer{}, kDummyFindServiceHandle);
-}
-
-TEST_F(ProxyEventBindingFixture,
- UnregisteringEventBindingAfterRegisteringWillMakeBindingUnavailableToServiceAvailabilityChangeHandler)
-{
- mock_binding::ProxyEventBase mock_proxy_event_base_binding{};
-
- // Expecting that NotifyServiceInstanceChangedAvailability will only be called on the binding once when it's
- // registered and not again when the find service handler is called
- EXPECT_CALL(mock_proxy_event_base_binding, NotifyServiceInstanceChangedAvailability(_, _));
-
- // Given a constructed Proxy which registered an event binding
- WhichCapturesFindServiceHandler(identifier_);
- InitialiseProxyWithCreate(identifier_);
- proxy_->RegisterEventBinding(kDummyEventName, mock_proxy_event_base_binding);
-
- // and then unregistered the event binding
- proxy_->UnregisterEventBinding(kDummyEventName);
+ proxy_->RegisterEvent(kDummyEventName, mock_proxy_event_base_binding);
+ proxy_->RegisterEvent("some_other_event", mock_proxy_event_base_binding_2);
// When the find service handler is called
const auto find_service_handler = find_service_handler_promise_.get_future().get();
find_service_handler(ServiceHandleContainer{}, kDummyFindServiceHandle);
}
-TEST_F(ProxyEventBindingFixture, UnregisteringEventBindingBeforeRegisteringWillNotTerminate)
-{
- // Given a constructed Proxy
- InitialiseProxyWithCreate(identifier_);
-
- // When calling UnregisterEventBinding when RegisterEventBinding was never called
- proxy_->UnregisterEventBinding(kDummyEventName);
-
- // Then we don't terminate
-}
-
using ProxyGetEventMetaInfoFixture = ProxyMockedMemoryFixture;
TEST_F(ProxyGetEventMetaInfoFixture, GetEventMetaInfoWillReturnDataForEventThatWasCreatedBySkeleton)
{
diff --git a/score/mw/com/impl/bindings/lola/test/proxy_event_test_resources.cpp b/score/mw/com/impl/bindings/lola/test/proxy_event_test_resources.cpp
index 884d739c8..795c46311 100644
--- a/score/mw/com/impl/bindings/lola/test/proxy_event_test_resources.cpp
+++ b/score/mw/com/impl/bindings/lola/test/proxy_event_test_resources.cpp
@@ -13,6 +13,7 @@
#include "score/mw/com/impl/bindings/lola/test/proxy_event_test_resources.h"
#include "score/memory/shared/memory_resource_registry.h"
+#include "score/mw/com/impl/find_service_handle.h"
#include
#include
@@ -95,7 +96,18 @@ void ProxyMockedMemoryFixture::InitialiseProxyWithConstructor(const InstanceIden
{
EnrichedInstanceIdentifier enriched_instance_identifier{instance_identifier};
ON_CALL(service_discovery_mock_, StartFindService(_, enriched_instance_identifier))
- .WillByDefault(Return(make_FindServiceHandle(10U)));
+ .WillByDefault(
+ testing::WithArg<0>(testing::Invoke([this](auto find_service_handler) -> Result {
+ // In practice, if a service is available at the point in time when the Proxy is created then the find
+ // service handler will be called synchronously in the StartFindService call. We simulate this here by
+ // calling the handler with a handle.
+ auto find_service_handle = make_FindServiceHandle(10U);
+ auto handle = make_HandleType(identifier_);
+ auto found_service_handle_container = ServiceHandleContainer{handle};
+
+ std::invoke(find_service_handler, found_service_handle_container, find_service_handle);
+ return find_service_handle;
+ })));
Proxy::EventNameToElementFqIdConverter event_name_to_element_fq_id_converter{lola_service_deployment_,
lola_service_instance_id_.GetId()};
diff --git a/score/mw/com/impl/bindings/mock_binding/proxy.h b/score/mw/com/impl/bindings/mock_binding/proxy.h
index 812581d18..69a358950 100644
--- a/score/mw/com/impl/bindings/mock_binding/proxy.h
+++ b/score/mw/com/impl/bindings/mock_binding/proxy.h
@@ -29,8 +29,6 @@ class Proxy : public ProxyBinding
~Proxy() override = default;
MOCK_METHOD(bool, IsEventProvided, (const std::string_view), (const, noexcept, override));
- MOCK_METHOD(void, RegisterEventBinding, (std::string_view, ProxyEventBindingBase&), (noexcept, override));
- MOCK_METHOD(void, UnregisterEventBinding, (std::string_view), (noexcept, override));
MOCK_METHOD(Result, SetupMethods, (), (override));
};
@@ -45,17 +43,6 @@ class ProxyFacade : public ProxyBinding
return proxy_.IsEventProvided(event_name);
}
- void RegisterEventBinding(const std::string_view service_element_name,
- ProxyEventBindingBase& proxy_event_binding) noexcept override
- {
- proxy_.RegisterEventBinding(service_element_name, proxy_event_binding);
- }
-
- void UnregisterEventBinding(const std::string_view service_element_name) noexcept override
- {
- proxy_.UnregisterEventBinding(service_element_name);
- }
-
Result SetupMethods() override
{
return proxy_.SetupMethods();
@@ -64,6 +51,7 @@ class ProxyFacade : public ProxyBinding
private:
Proxy& proxy_;
};
+
} // namespace score::mw::com::impl::mock_binding
#endif // SCORE_MW_COM_IMPL_BINDINGS_MOCK_BINDING_PROXY_H
diff --git a/score/mw/com/impl/generic_proxy.cpp b/score/mw/com/impl/generic_proxy.cpp
index 3e2091287..a76e5610c 100644
--- a/score/mw/com/impl/generic_proxy.cpp
+++ b/score/mw/com/impl/generic_proxy.cpp
@@ -77,7 +77,12 @@ Result GenericProxy::Create(HandleType instance_handle) noexcept
const auto& instance_identifier = generic_proxy.handle_.GetInstanceIdentifier();
const auto event_names = GetEventNameList(instance_identifier);
generic_proxy.FillEventMap(event_names);
- if (!generic_proxy.AreBindingsValid())
+ auto& generic_proxy_events = generic_proxy.GetEvents();
+ const bool are_event_bindings_valid =
+ std::all_of(generic_proxy_events.cbegin(), generic_proxy_events.cend(), [](const auto& element) {
+ return ProxyEventBaseView{element.second}.GetBinding() != nullptr;
+ });
+ if (!are_event_bindings_valid)
{
::score::mw::log::LogError("lola") << "Could not create GenericProxy as binding is invalid.";
return MakeUnexpected(ComErrc::kBindingFailure);
diff --git a/score/mw/com/impl/generic_proxy_event.cpp b/score/mw/com/impl/generic_proxy_event.cpp
index da5499356..68ad3318b 100644
--- a/score/mw/com/impl/generic_proxy_event.cpp
+++ b/score/mw/com/impl/generic_proxy_event.cpp
@@ -25,12 +25,6 @@ GenericProxyEvent::GenericProxyEvent(ProxyBase& base, const std::string_view eve
GenericProxyEventBindingFactory::Create(base, event_name),
event_name}
{
- ProxyBaseView proxy_base_view{base};
- if (!binding_base_)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
GenericProxyEvent::GenericProxyEvent(ProxyBase& base,
@@ -38,12 +32,6 @@ GenericProxyEvent::GenericProxyEvent(ProxyBase& base,
const std::string_view event_name)
: ProxyEventBase{base, ProxyBaseView{base}.GetBinding(), std::move(proxy_binding), event_name}
{
- ProxyBaseView proxy_base_view{base};
- if (!binding_base_)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
std::size_t GenericProxyEvent::GetSampleSize() const noexcept
diff --git a/score/mw/com/impl/methods/proxy_method_base.h b/score/mw/com/impl/methods/proxy_method_base.h
index 5e194bf00..86091ada6 100644
--- a/score/mw/com/impl/methods/proxy_method_base.h
+++ b/score/mw/com/impl/methods/proxy_method_base.h
@@ -27,9 +27,15 @@ namespace score::mw::com::impl
{
class ProxyBase;
+class ProxyMethodBaseView;
class ProxyMethodBase
{
+ // Suppress "AUTOSAR C++14 A11-3-1", The rule states: "Friend declarations shall not be used".
+ // Design decision. This class provides a view to the private members of this class.
+ // coverity[autosar_cpp14_a11_3_1_violation]
+ friend class ProxyMethodBaseView;
+
public:
ProxyMethodBase(ProxyBase& proxy_base,
std::unique_ptr proxy_method_binding,
@@ -97,6 +103,20 @@ class ProxyMethodBase
std::unique_ptr binding_;
};
+class ProxyMethodBaseView
+{
+ public:
+ explicit ProxyMethodBaseView(const ProxyMethodBase& base) : base_{base} {}
+
+ const ProxyMethodBinding* GetMethodBinding() const noexcept
+ {
+ return base_.binding_.get();
+ }
+
+ private:
+ const ProxyMethodBase& base_;
+};
+
} // namespace score::mw::com::impl
#endif // SCORE_MW_COM_IMPL_METHODS_PROXY_METHOD_BASE_H
diff --git a/score/mw/com/impl/methods/proxy_method_with_in_args.h b/score/mw/com/impl/methods/proxy_method_with_in_args.h
index 113b7e8d9..da608454d 100644
--- a/score/mw/com/impl/methods/proxy_method_with_in_args.h
+++ b/score/mw/com/impl/methods/proxy_method_with_in_args.h
@@ -68,11 +68,6 @@ class ProxyMethod final : public ProxyMethodBase
{
auto proxy_base_view = ProxyBaseView{proxy_base};
proxy_base_view.RegisterMethod(method_name_, *this);
- if (binding_ == nullptr)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
~ProxyMethod() final = default;
diff --git a/score/mw/com/impl/methods/proxy_method_with_in_args_and_return.h b/score/mw/com/impl/methods/proxy_method_with_in_args_and_return.h
index fcfb3bcf5..78ef90eef 100644
--- a/score/mw/com/impl/methods/proxy_method_with_in_args_and_return.h
+++ b/score/mw/com/impl/methods/proxy_method_with_in_args_and_return.h
@@ -78,11 +78,6 @@ class ProxyMethod final : public ProxyMethodBase
{
auto proxy_base_view = ProxyBaseView{proxy_base};
proxy_base_view.RegisterMethod(method_name_, *this);
- if (binding_ == nullptr)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
ProxyMethod(ProxyBase& proxy_base,
@@ -93,11 +88,6 @@ class ProxyMethod final : public ProxyMethodBase
{
auto proxy_base_view = ProxyBaseView{proxy_base};
proxy_base_view.RegisterMethod(method_name_, *this);
- if (binding_ == nullptr)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
ProxyMethod(ProxyBase& proxy_base,
@@ -107,12 +97,6 @@ class ProxyMethod final : public ProxyMethodBase
: ProxyMethodBase(proxy_base, std::move(proxy_method_binding), method_name, MethodType::kSet),
are_in_arg_ptrs_active_(kCallQueueSize)
{
- auto proxy_base_view = ProxyBaseView{proxy_base};
- if (binding_ == nullptr)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
~ProxyMethod() final = default;
diff --git a/score/mw/com/impl/methods/proxy_method_with_return_type.h b/score/mw/com/impl/methods/proxy_method_with_return_type.h
index edeea7b8c..c39fcfca7 100644
--- a/score/mw/com/impl/methods/proxy_method_with_return_type.h
+++ b/score/mw/com/impl/methods/proxy_method_with_return_type.h
@@ -70,11 +70,6 @@ class ProxyMethod final : public ProxyMethodBase
{
auto proxy_base_view = ProxyBaseView{proxy_base};
proxy_base_view.RegisterMethod(method_name_, *this);
- if (binding_ == nullptr)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
ProxyMethod(ProxyBase& proxy_base,
@@ -84,11 +79,6 @@ class ProxyMethod final : public ProxyMethodBase
{
auto proxy_base_view = ProxyBaseView{proxy_base};
proxy_base_view.RegisterMethod(method_name_, *this);
- if (binding_ == nullptr)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
ProxyMethod(ProxyBase& proxy_base,
@@ -97,12 +87,6 @@ class ProxyMethod final : public ProxyMethodBase
FieldOnlyConstructorEnabler) noexcept
: ProxyMethodBase(proxy_base, std::move(proxy_method_binding), method_name, MethodType::kGet)
{
- auto proxy_base_view = ProxyBaseView{proxy_base};
- if (binding_ == nullptr)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
~ProxyMethod() final = default;
diff --git a/score/mw/com/impl/methods/proxy_method_without_in_args_or_return.h b/score/mw/com/impl/methods/proxy_method_without_in_args_or_return.h
index e9a36fd28..7f82a0e5c 100644
--- a/score/mw/com/impl/methods/proxy_method_without_in_args_or_return.h
+++ b/score/mw/com/impl/methods/proxy_method_without_in_args_or_return.h
@@ -55,11 +55,6 @@ class ProxyMethod final : public ProxyMethodBase
{
auto proxy_base_view = ProxyBaseView{proxy_base};
proxy_base_view.RegisterMethod(method_name_, *this);
- if (binding_ == nullptr)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
ProxyMethod(ProxyBase& proxy_base,
@@ -69,11 +64,6 @@ class ProxyMethod final : public ProxyMethodBase
{
auto proxy_base_view = ProxyBaseView{proxy_base};
proxy_base_view.RegisterMethod(method_name_, *this);
- if (binding_ == nullptr)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
~ProxyMethod() final = default;
diff --git a/score/mw/com/impl/proxy_base.cpp b/score/mw/com/impl/proxy_base.cpp
index 26209a6b3..159d4819c 100644
--- a/score/mw/com/impl/proxy_base.cpp
+++ b/score/mw/com/impl/proxy_base.cpp
@@ -28,19 +28,13 @@ namespace score::mw::com::impl
{
ProxyBase::ProxyBase(std::unique_ptr proxy_binding, HandleType handle)
- : proxy_binding_{std::move(proxy_binding)},
- handle_{std::move(handle)},
- are_service_element_bindings_valid_{true},
- events_{},
- fields_{},
- methods_{}
+ : proxy_binding_{std::move(proxy_binding)}, handle_{std::move(handle)}, events_{}, fields_{}, methods_{}
{
}
ProxyBase::ProxyBase(ProxyBase&& other) noexcept
: proxy_binding_(std::move(other.proxy_binding_)),
handle_(std::move(other.handle_)),
- are_service_element_bindings_valid_(other.are_service_element_bindings_valid_),
events_(std::move(other.events_)),
fields_(std::move(other.fields_)),
methods_(std::move(other.methods_))
@@ -72,7 +66,6 @@ ProxyBase& ProxyBase::operator=(ProxyBase&& other) noexcept
proxy_binding_ = std::move(other.proxy_binding_);
handle_ = std::move(other.handle_);
- are_service_element_bindings_valid_ = other.are_service_element_bindings_valid_;
events_ = std::move(other.events_);
fields_ = std::move(other.fields_);
methods_ = std::move(other.methods_);
@@ -158,6 +151,23 @@ score::Result ProxyBase::StopFindService(const FindServiceHandle handle) n
return stop_find_service_result;
}
+bool ProxyBase::AreBindingsValid() const noexcept
+{
+ const bool is_proxy_binding_valid{proxy_binding_ != nullptr};
+
+ const bool are_event_bindings_valid = std::all_of(events_.begin(), events_.end(), [](const auto& element) {
+ return ProxyEventBaseView{element.second.get()}.GetBinding() != nullptr;
+ });
+ const bool are_field_bindings_valid = std::all_of(fields_.begin(), fields_.end(), [](const auto& element) {
+ return ProxyFieldBaseView{element.second.get()}.GetEventBinding() != nullptr;
+ });
+ const bool are_method_bindings_valid = std::all_of(methods_.begin(), methods_.end(), [](const auto& element) {
+ return ProxyMethodBaseView{element.second.get()}.GetMethodBinding() != nullptr;
+ });
+
+ return is_proxy_binding_valid && are_event_bindings_valid && are_field_bindings_valid && are_method_bindings_valid;
+}
+
Result ProxyBase::SetupMethods()
{
const auto result = proxy_binding_->SetupMethods();
@@ -186,11 +196,6 @@ const HandleType& ProxyBaseView::GetAssociatedHandleType() const noexcept
return proxy_base_.handle_;
}
-void ProxyBaseView::MarkServiceElementBindingInvalid() noexcept
-{
- proxy_base_.are_service_element_bindings_valid_ = false;
-}
-
void ProxyBaseView::RegisterEvent(const std::string_view event_name, ProxyEventBase& event)
{
const auto result = proxy_base_.events_.emplace(event_name, event);
diff --git a/score/mw/com/impl/proxy_base.h b/score/mw/com/impl/proxy_base.h
index 60e608832..db1c95d99 100644
--- a/score/mw/com/impl/proxy_base.h
+++ b/score/mw/com/impl/proxy_base.h
@@ -131,11 +131,7 @@ class ProxyBase
ProxyBase(ProxyBase&& other) noexcept;
ProxyBase& operator=(ProxyBase&& other) noexcept;
- bool AreBindingsValid() const noexcept
- {
- const bool is_proxy_binding_valid{proxy_binding_ != nullptr};
- return is_proxy_binding_valid && are_service_element_bindings_valid_;
- }
+ bool AreBindingsValid() const noexcept;
Result SetupMethods();
@@ -147,8 +143,6 @@ class ProxyBase
std::unique_ptr proxy_binding_;
// coverity[autosar_cpp14_m11_0_1_violation]
HandleType handle_;
- // coverity[autosar_cpp14_m11_0_1_violation]
- bool are_service_element_bindings_valid_;
ProxyEvents events_;
ProxyFields fields_;
@@ -170,8 +164,6 @@ class ProxyBaseView final
const HandleType& GetAssociatedHandleType() const noexcept;
- void MarkServiceElementBindingInvalid() noexcept;
-
void RegisterEvent(const std::string_view event_name, ProxyEventBase& event);
void RegisterField(const std::string_view field_name, ProxyFieldBase& field);
diff --git a/score/mw/com/impl/proxy_binding.h b/score/mw/com/impl/proxy_binding.h
index c24524d36..cd5d50977 100644
--- a/score/mw/com/impl/proxy_binding.h
+++ b/score/mw/com/impl/proxy_binding.h
@@ -54,13 +54,6 @@ class ProxyBinding
/// \return True if the event name exists, otherwise, false
virtual bool IsEventProvided(const std::string_view event_name) const noexcept = 0;
- /// Registers a ProxyEvent binding with its parent proxy
- virtual void RegisterEventBinding(const std::string_view service_element_name,
- ProxyEventBindingBase& proxy_event_binding) noexcept = 0;
-
- /// Unregisters a ProxyEvent binding with its parent proxy
- virtual void UnregisterEventBinding(const std::string_view service_element_name) noexcept = 0;
-
virtual Result SetupMethods() = 0;
};
diff --git a/score/mw/com/impl/proxy_binding_test.cpp b/score/mw/com/impl/proxy_binding_test.cpp
index fd7ba4dd2..b5cd4dc2c 100644
--- a/score/mw/com/impl/proxy_binding_test.cpp
+++ b/score/mw/com/impl/proxy_binding_test.cpp
@@ -29,8 +29,6 @@ class MyProxy final : public ProxyBinding
{
return true;
}
- void RegisterEventBinding(std::string_view, ProxyEventBindingBase&) noexcept override {}
- void UnregisterEventBinding(std::string_view) noexcept override {}
Result SetupMethods() override
{
return {};
diff --git a/score/mw/com/impl/proxy_event.h b/score/mw/com/impl/proxy_event.h
index 38160790d..83b68a8fe 100644
--- a/score/mw/com/impl/proxy_event.h
+++ b/score/mw/com/impl/proxy_event.h
@@ -75,8 +75,7 @@ class ProxyEvent final : public ProxyEventBase
/// Constructor which is dispatched to by the other public constructors.
///
- /// Instantiates the base class and members of ProxyEvent and MarkServiceElementBindingInvalid() if the binding is
- /// invalid. Should only be called directly in tests.
+ /// Instantiates the base class and members of ProxyEvent. Should only be called directly in tests.
///
/// \param proxy_binding The binding that shall be associated with this proxy.
ProxyEvent(ProxyBase& base,
@@ -148,22 +147,16 @@ ProxyEvent::ProxyEvent(ProxyBase& base,
: ProxyEventBase{base, ProxyBaseView{base}.GetBinding(), std::move(proxy_event_binding), event_name},
proxy_event_mock_{nullptr}
{
- ProxyBaseView proxy_base_view{base};
- if (!binding_base_)
- {
- proxy_base_view.MarkServiceElementBindingInvalid();
- return;
- }
}
template
ProxyEvent::ProxyEvent(ProxyBase& base, const std::string_view event_name)
: ProxyEvent{base, ProxyEventBindingFactory::Create(base, event_name), event_name}
{
+ ProxyBaseView proxy_base_view{base};
+ proxy_base_view.RegisterEvent(event_name, *this);
if (GetTypedEventBinding() != nullptr)
{
- ProxyBaseView proxy_base_view{base};
- proxy_base_view.RegisterEvent(event_name, *this);
const auto& instance_identifier = proxy_base_view.GetAssociatedHandleType().GetInstanceIdentifier();
tracing_data_ = tracing::GenerateProxyTracingStructFromEventConfig(instance_identifier, event_name);
}
diff --git a/score/mw/com/impl/proxy_event_base.cpp b/score/mw/com/impl/proxy_event_base.cpp
index faa9f8650..e32ce61dd 100644
--- a/score/mw/com/impl/proxy_event_base.cpp
+++ b/score/mw/com/impl/proxy_event_base.cpp
@@ -33,45 +33,6 @@ namespace score::mw::com::impl
// Initialization of static thread_local variables!
thread_local bool ProxyEventBase::is_in_receive_handler_context = false;
-/// \brief Helper class which registers the ProxyEventBindingBase with its parent proxy (ProxyBinding) and unregisters
-/// on destruction
-///
-/// Since ProxyBase is moveable, we must ensure that this class does not store a reference or pointer to it. As if the
-/// Proxy is moved, then the pointer or reference would be invalidated. However, the ProxyBinding is not moveable, so
-/// storing a pointer to the ProxyBinding is safe.
-class EventBindingRegistrationGuard final
-{
- public:
- EventBindingRegistrationGuard(ProxyBinding* proxy_binding,
- ProxyEventBindingBase* proxy_event_binding_base,
- std::string_view event_name) noexcept
- : proxy_binding_{proxy_binding}, proxy_event_binding_base_{proxy_event_binding_base}, event_name_{event_name}
- {
- if ((proxy_binding_ != nullptr) && (proxy_event_binding_base_ != nullptr))
- {
- proxy_binding_->RegisterEventBinding(event_name, *proxy_event_binding_base);
- }
- }
-
- ~EventBindingRegistrationGuard() noexcept
- {
- if ((proxy_binding_ != nullptr) && (proxy_event_binding_base_ != nullptr))
- {
- proxy_binding_->UnregisterEventBinding(event_name_);
- }
- }
-
- EventBindingRegistrationGuard(const EventBindingRegistrationGuard&) = delete;
- EventBindingRegistrationGuard& operator=(const EventBindingRegistrationGuard&) = delete;
- EventBindingRegistrationGuard(EventBindingRegistrationGuard&& other) = delete;
- EventBindingRegistrationGuard& operator=(EventBindingRegistrationGuard&& other) = delete;
-
- private:
- ProxyBinding* proxy_binding_;
- ProxyEventBindingBase* proxy_event_binding_base_;
- std::string_view event_name_;
-};
-
// Suppress "AUTOSAR C++14 A3-1-1", The rule states: "It shall be possible to include any header file
// in multiple translation units without violating the One Definition Rule."
// This is false positive. Function is declared only once.
@@ -85,8 +46,6 @@ ProxyEventBase::ProxyEventBase(ProxyBase& proxy_base,
event_name_{event_name},
tracker_{std::make_unique()},
tracing_data_{},
- event_binding_registration_guard_{
- std::make_unique(proxy_binding_ptr, binding_base_.get(), event_name)},
proxy_event_base_mock_{nullptr},
receive_handler_scope_{}
{
diff --git a/score/mw/com/impl/proxy_event_base.h b/score/mw/com/impl/proxy_event_base.h
index 55ebcb83a..07483faf9 100644
--- a/score/mw/com/impl/proxy_event_base.h
+++ b/score/mw/com/impl/proxy_event_base.h
@@ -33,8 +33,8 @@
namespace score::mw::com::impl
{
-class EventBindingRegistrationGuard;
class ProxyBase;
+class ProxyEventBaseView;
/// \brief This is the user-visible class of an event that is part of a proxy. It contains ProxyEvent functionality that
/// is agnostic of the data type that is transferred by the event.
@@ -49,6 +49,11 @@ class ProxyEventBase
// coverity[autosar_cpp14_a11_3_1_violation]
friend class ProxyEventBaseAttorney;
+ // Suppress "AUTOSAR C++14 A11-3-1", The rule states: "Friend declarations shall not be used".
+ // Design decision. This class provides a view to the private members of this class.
+ // coverity[autosar_cpp14_a11_3_1_violation]
+ friend ProxyEventBaseView;
+
public:
/// \brief Constructs a ProxyEventBase with the given proxy event binding.
/// \param proxy_base The parent proxy of this event. ProxyEventBase just stores a reference to it and allows the
@@ -210,8 +215,6 @@ class ProxyEventBase
std::unique_ptr tracker_;
// coverity[autosar_cpp14_m11_0_1_violation]
tracing::ProxyEventTracingData tracing_data_;
- // coverity[autosar_cpp14_m11_0_1_violation]
- std::unique_ptr event_binding_registration_guard_;
IProxyEventBase* proxy_event_base_mock_;
@@ -238,6 +241,20 @@ class ProxyEventBase
static thread_local bool is_in_receive_handler_context;
};
+class ProxyEventBaseView
+{
+ public:
+ explicit ProxyEventBaseView(const ProxyEventBase& proxy_event_base) : proxy_event_base_{proxy_event_base} {}
+
+ const ProxyEventBindingBase* GetBinding() const
+ {
+ return proxy_event_base_.binding_base_.get();
+ }
+
+ private:
+ const ProxyEventBase& proxy_event_base_;
+};
+
} // namespace score::mw::com::impl
#endif // SCORE_MW_COM_IMPL_PROXY_EVENT_BASE_H
diff --git a/score/mw/com/impl/proxy_event_base_test.cpp b/score/mw/com/impl/proxy_event_base_test.cpp
index 6ec683ec8..9e80e2d7c 100644
--- a/score/mw/com/impl/proxy_event_base_test.cpp
+++ b/score/mw/com/impl/proxy_event_base_test.cpp
@@ -171,84 +171,6 @@ TYPED_TEST(ProxyEventBaseCreationFixture, CreatingServiceElementWithValidEventBi
EXPECT_TRUE(dummy_proxy.AreBindingsValid());
}
-TYPED_TEST(ProxyEventBaseCreationFixture, CreatingServiceElementWithInvalidEventBindingMarksProxyBindingInvalid)
-{
- // Given a proxy with a valid binding
- DummyProxy dummy_proxy(std::make_unique(),
- make_HandleType(make_InstanceIdentifier(kEmptyInstanceDeployment, kEmptyTypeDeployment)));
-
- // When creating a ProxyEvent with an invalid binding
- auto service_element = std::make_unique::ServiceElementType>(
- dummy_proxy,
- std::unique_ptr::MockServiceElementType>(nullptr),
- kEventName);
-
- // Then the proxy should report that all bindings are not valid
- EXPECT_FALSE(dummy_proxy.AreBindingsValid());
-}
-
-TYPED_TEST(ProxyEventBaseCreationFixture, CreatingServiceElementWithInvalidProxyBindingMarksProxyBindingInvalid)
-{
- auto valid_proxy_event_binding =
- std::make_unique::MockServiceElementType>();
-
- // Given a proxy with a valid binding
- DummyProxy dummy_proxy(nullptr,
- make_HandleType(make_InstanceIdentifier(kEmptyInstanceDeployment, kEmptyTypeDeployment)));
-
- // When creating a ProxyEvent with a valid binding
- auto service_element = std::make_unique::ServiceElementType>(
- dummy_proxy, std::move(valid_proxy_event_binding), kEventName);
-
- // Then the proxy should report that all bindings are not valid
- EXPECT_FALSE(dummy_proxy.AreBindingsValid());
-}
-
-TYPED_TEST(ProxyEventBaseCreationFixture,
- CreatingServiceElementWithValidProxyEventBindingWillRegisterAndUnregisterEventBinding)
-{
- auto valid_proxy_binding = std::make_unique();
- auto valid_proxy_event_binding =
- std::make_unique::MockServiceElementType>();
-
- auto* const mock_proxy_binding = valid_proxy_binding.get();
- ProxyEventBindingBase* const mock_proxy_event_binding = valid_proxy_event_binding.get();
-
- // Expecting that the ProxyEvent will register and unregister itself with the parent Proxy
- EXPECT_CALL(*mock_proxy_binding, RegisterEventBinding(kEventName, Ref(*mock_proxy_event_binding)));
- EXPECT_CALL(*mock_proxy_binding, UnregisterEventBinding(kEventName));
-
- // Given a proxy with a valid binding
- DummyProxy dummy_proxy(std::move(valid_proxy_binding),
- make_HandleType(make_InstanceIdentifier(kEmptyInstanceDeployment, kEmptyTypeDeployment)));
-
- // When creating a ProxyEvent with a valid binding
- auto service_element = std::make_unique::ServiceElementType>(
- dummy_proxy, std::move(valid_proxy_event_binding), kEventName);
-}
-
-TYPED_TEST(ProxyEventBaseCreationFixture,
- CreatingServiceElementWithInvalidProxyEventBindingWillNotRegisterOrUnregisterEventBinding)
-{
- auto valid_proxy_binding = std::make_unique();
-
- auto* const mock_proxy_binding = valid_proxy_binding.get();
-
- // Expecting that the ProxyEvent will not register itself with the parent Proxy
- EXPECT_CALL(*mock_proxy_binding, RegisterEventBinding(_, _)).Times(0);
- EXPECT_CALL(*mock_proxy_binding, UnregisterEventBinding(_)).Times(0);
-
- // Given a proxy with a valid binding
- DummyProxy dummy_proxy(std::move(valid_proxy_binding),
- make_HandleType(make_InstanceIdentifier(kEmptyInstanceDeployment, kEmptyTypeDeployment)));
-
- // When creating a ProxyEvent with an invalid binding
- auto service_element = std::make_unique::ServiceElementType>(
- dummy_proxy,
- std::unique_ptr::MockServiceElementType>(nullptr),
- kEventName);
-}
-
TYPED_TEST(ProxyEventBaseUnsubscribeFixture, CallingUnsubscribeWhileSubscribedCallsUnsubscribeOnBinding)
{
this->RecordProperty("Verifies", "SCR-14033377, SCR-17292399, SCR-14137271, SCR-21286218");
diff --git a/score/mw/com/impl/proxy_field_base.h b/score/mw/com/impl/proxy_field_base.h
index 88068b96e..c4473a12d 100644
--- a/score/mw/com/impl/proxy_field_base.h
+++ b/score/mw/com/impl/proxy_field_base.h
@@ -15,6 +15,7 @@
#include "score/mw/com/impl/proxy_event_base.h"
+#include "score/mw/com/impl/proxy_event_binding_base.h"
#include "score/result/result.h"
#include
@@ -27,8 +28,15 @@
namespace score::mw::com::impl
{
+class ProxyFieldBaseView;
+
class ProxyFieldBase
{
+ // Suppress "AUTOSAR C++14 A11-3-1", The rule states: "Friend declarations shall not be used".
+ // Design decision. This class provides a view to the private members of this class.
+ // coverity[autosar_cpp14_a11_3_1_violation]
+ friend ProxyFieldBaseView;
+
public:
ProxyFieldBase(ProxyBase& proxy_base, ProxyEventBase* proxy_event_base_dispatch, std::string_view field_name)
: proxy_base_{proxy_base}, proxy_event_base_dispatch_{proxy_event_base_dispatch}, field_name_{field_name}
@@ -169,6 +177,24 @@ class ProxyFieldBase
std::string_view field_name_;
};
+class ProxyFieldBaseView
+{
+ public:
+ explicit ProxyFieldBaseView(const ProxyFieldBase& proxy_field_base) : proxy_field_base_{proxy_field_base} {}
+
+ const ProxyEventBindingBase* GetEventBinding() const noexcept
+ {
+ if (proxy_field_base_.proxy_event_base_dispatch_ == nullptr)
+ {
+ return nullptr;
+ }
+ return ProxyEventBaseView{*proxy_field_base_.proxy_event_base_dispatch_}.GetBinding();
+ }
+
+ private:
+ const ProxyFieldBase& proxy_field_base_;
+};
+
} // namespace score::mw::com::impl
#endif // SCORE_MW_COM_IMPL_PROXY_FIELD_BASE_H