+ savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryTest, ChangeNotificationFromSentinel)
+{
+ InSequence dummy;
+ setStateChangedCbExpectsBeforeMasterInquiry();
+ dispatcherConnectAck();
+ expectMasterIquiryReply();
+ expectStateChangedCb(someHost, somePort);
+ savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
+ expectNotificationReply();
+ expectStateChangedCb(someOtherHost, someOtherPort);
+ savedSubscriberCommandCb(std::error_code(), notificationReplyMock);
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeTest, SubscribeCommandErrorTriggersRetry)
+{
+ InSequence dummy;
+ expectSubscribeRetryTimer();
+ savedSubscriberCommandCb(getWellKnownErrorCode(), subscribeReplyMock);
+ expectSubscribeNotifications();
+ savedSubscribeRetryTimerCallback();
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidReplyType)
+{
+ InSequence dummy;
+ ON_CALL(notificationReplyMock, getType())
+ .WillByDefault(Return(Reply::Type::NIL));
+ EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidKindElementType)
+{
+ InSequence dummy;
+ setDefaultResponsesForNotificationReplyParsing();
+ ON_CALL(*notificationReplyArrayElement0, getType())
+ .WillByDefault(Return(Reply::Type::NIL));
+ EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidKind)
+{
+ InSequence dummy;
+ setDefaultResponsesForNotificationReplyParsing();
+ std::string invalidKind("invalidKind");
+ Reply::DataItem invalidKindDataItem({invalidKind,ReplyStringLength(invalidKind.length())});
+ ON_CALL(*notificationReplyArrayElement0, getString())
+ .WillByDefault(Return(&invalidKindDataItem));
+ EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidMessageElementType)
+{
+ InSequence dummy;
+ setDefaultResponsesForNotificationReplyParsing();
+ ON_CALL(*notificationReplyArrayElement2, getType())
+ .WillByDefault(Return(Reply::Type::NIL));
+ EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidMessageStructure)
+{
+ InSequence dummy;
+ setDefaultResponsesForNotificationReplyParsing();
+ std::string invalidMessage("mymaster oldHost 1234 5678");
+ auto invalidMessageDataItem(Reply::DataItem({invalidMessage, ReplyStringLength(invalidMessage.length())}));
+ ON_CALL(*notificationReplyArrayElement2, getString())
+ .WillByDefault(Return(&invalidMessageDataItem));
+ EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*Notification message parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidPort)
+{
+ InSequence dummy;
+ setDefaultResponsesForNotificationReplyParsing();
+ std::string invalidMessage("mymaster oldHost 1234 newHost invalidPort");
+ auto invalidMessageDataItem(Reply::DataItem({invalidMessage, ReplyStringLength(invalidMessage.length())}));
+ ON_CALL(*notificationReplyArrayElement2, getString())
+ .WillByDefault(Return(&invalidMessageDataItem));
+ EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*Notification message parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeTest, SubscriberDisconnectCallbackTriggersSubscriptionRenewal)
+{
+ InSequence dummy;
+ expectSubscriberWaitConnectedAsync();
+ subscriberDisconnectCb();
+ expectSubscribeNotifications();
+ subscriberConnectAck();
+ expectSubscribeReply();
+ expectDispatcherWaitConnectedAsync();
+ savedSubscriberCommandCb(std::error_code(), subscribeReplyMock);
+ expectMasterInquiry();
+ dispatcherConnectAck();
+ expectMasterIquiryReply();
+ expectStateChangedCb(someHost, somePort);
+ savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);