Fix flaky test#385
Conversation
268298b to
7e9975a
Compare
e3f2cdc to
15f4629
Compare
5201764 to
96a9ed1
Compare
445b759 to
20a0d63
Compare
| return proxy_wrapper; | ||
| } | ||
|
|
||
| ~ProxyWrapperClass() |
There was a problem hiding this comment.
This could actually be a scope exit so that ProxyWrapperClass can have defaulted destructor / move ops. We use ScopeExit in a few places, you can check some existing uses.
There was a problem hiding this comment.
Could you do the same thing for SkeletonWrapperClass?
There was a problem hiding this comment.
hmm.. okay i think we cannot use ScopeExit here,
why?
if we want to call the Unsubscribe inside the callback we pass in to scope exit,
something like ScopeExit guard_{[this]() { this->Unsubscribe(); }};
Then we have to capture "this",
then when we move the wrapper this stored inside the lambda would be invalidated and it crashes.
i think this approach worked in other places where we do not capture to this but we capture something that class in which this scopeexit object lives are captured.
| return std::move(proxy_result).value(); | ||
| } | ||
|
|
||
| GeneratedProxyUnsubscribeRaiiFixture& GivenAProxy() |
There was a problem hiding this comment.
Why do we need CreateProxy in addition to this function?
There was a problem hiding this comment.
ah right! this is no longer required since i do not have the move tests which had createProxy to create a second proxy, will remove now.
| }; | ||
|
|
||
| using GeneratedProxyDestructionFixture = GeneratedProxyUnsubscribeRaiiFixture; | ||
| TEST_F(GeneratedProxyDestructionFixture, CallsUnsubscribeOnDestructionOfOwnedProxy) |
There was a problem hiding this comment.
leftover from an earlier change where i had one test that compared owned vs moved-from proxies in the same body i split it into separate tests (DestroyingMovedToProxyCallsUnsubscribe, DestroyingMovedFromProxyDoesNotCallUnsubscribe), the "owned" here is redundant. will rename to CallsUnsubscribeOnDestruction.
| } | ||
|
|
||
| using GeneratedProxyMoveConstructionFixture = GeneratedProxyUnsubscribeRaiiFixture; | ||
| TEST_F(GeneratedProxyMoveConstructionFixture, MoveConstructingDoesNotCallUnsubscribe) |
There was a problem hiding this comment.
When you change ProxyWrapperClass to use ScopeExit then you can also remove the move tests (assuming that you add in a test like this one: https://github.com/KrishaDeshkool/communication/blob/ed71f9b487ae18305253dfb8367c0fe4590b3b9b/score/mw/com/impl/bindings/lola/messaging/method_subscription_registration_guard_test.cpp#L60)
There was a problem hiding this comment.
leaving it as is since scope exit does not work here (atleast not without lot of rework)
There was a problem hiding this comment.
This commit should be squashed with the previous one since tests should be merged alongside the changes.
There was a problem hiding this comment.
both commits would be merged at once anyway since this is one PR,
but if you are fine with all the things in one commit then i will do it like this,
usually ppl ask for separate commit for tests in the past. since you are reviewing it i will squash as you asked.
| EXPECT_CALL(proxy_event_mock_2, Unsubscribe()); | ||
| EXPECT_CALL(proxy_field_mock, Unsubscribe()); | ||
| // Times(2): once from the explicit call below, once from the RAII destructor in ~ProxyWrapperClass | ||
| EXPECT_CALL(proxy_field_mock, Unsubscribe()).Times(2); |
There was a problem hiding this comment.
We currently have nothing stopping Unsubscribe from being called multiple times or even from being called before subscribe: https://github.com/KrishaDeshkool/communication/blob/ed71f9b487ae18305253dfb8367c0fe4590b3b9b/score/mw/com/impl/proxy_event_base.cpp#L148. We have a requirement that says that in the latter case, nothing should happen (
There was a problem hiding this comment.
I guess that we should do similar checks on skeleton side / in all events / fields as described in point 3 of #385 (comment)
Proxy destruction raced with the skeleton's StopOfferService async notification: the lola Proxy's FindServiceGuard callback iterates event_bindings_ and proxy_methods_ while the proxy is mid-destruction, causing a use-after-free. Mirror the skeleton's StopOfferService chain on the proxy side. The wrapper destructor calls Unsubscribe(), which tells each event/field to unsubscribe and then dispatches to the binding to stop its async source (PrepareUnsubscribe) and then clear its registration maps (FinalizeUnsubscribe).
20a0d63 to
fb8e64a
Compare
Issue: #386