2 Copyright (c) 2018-2019 Nokia.
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
17 #include <gtest/gtest.h>
18 #include <arpa/inet.h>
20 #include <sdl/asyncstorage.hpp>
21 #include "private/createlogger.hpp"
22 #include "private/hostandport.hpp"
23 #include "private/timer.hpp"
24 #include "private/redis/asyncsentineldatabasediscovery.hpp"
25 #include "private/tst/asynccommanddispatchermock.hpp"
26 #include "private/tst/contentsbuildermock.hpp"
27 #include "private/tst/enginemock.hpp"
28 #include "private/tst/replymock.hpp"
29 #include "private/tst/wellknownerrorcode.hpp"
31 using namespace shareddatalayer;
32 using namespace shareddatalayer::redis;
33 using namespace shareddatalayer::tst;
34 using namespace testing;
38 class AsyncSentinelDatabaseDiscoveryBaseTest: public testing::Test
41 std::unique_ptr<AsyncSentinelDatabaseDiscovery> asyncSentinelDatabaseDiscovery;
42 std::shared_ptr<StrictMock<EngineMock>> engineMock;
43 std::shared_ptr<StrictMock<AsyncCommandDispatcherMock>> subscriberMock;
44 std::shared_ptr<StrictMock<AsyncCommandDispatcherMock>> dispatcherMock;
45 std::shared_ptr<StrictMock<ContentsBuilderMock>> contentsBuilderMock;
46 std::shared_ptr<Logger> logger;
48 AsyncCommandDispatcher::ConnectAck subscriberConnectAck;
49 AsyncCommandDispatcher::DisconnectCb subscriberDisconnectCb;
50 AsyncCommandDispatcher::ConnectAck dispatcherConnectAck;
51 AsyncCommandDispatcher::CommandCb savedSubscriberCommandCb;
52 AsyncCommandDispatcher::CommandCb savedDispatcherCommandCb;
53 ReplyMock masterInquiryReplyMock;
56 std::string someOtherHost;
57 uint16_t someOtherPort;
58 Reply::DataItem hostDataItem;
59 Reply::DataItem portDataItem;
60 std::shared_ptr<ReplyMock> masterInquiryReplyHost;
61 std::shared_ptr<ReplyMock> masterInquiryReplyPort;
62 Reply::ReplyVector masterInquiryReply;
63 Timer::Duration expectedMasterInquiryRetryTimerDuration;
64 Timer::Callback savedMasterInquiryRetryTimerCallback;
65 // Mocks for SUBSCRIBE command replies are a bit complicated, because reply might have several
66 // meanings/structures: https://redis.io/topics/pubsub#format-of-pushed-messages
67 ReplyMock subscribeReplyMock;
68 std::shared_ptr<ReplyMock> subscribeReplyArrayElement0;
69 std::shared_ptr<ReplyMock> subscribeReplyArrayElement1;
70 std::shared_ptr<ReplyMock> subscribeReplyArrayElement2;
71 Reply::ReplyVector subscribeReplyVector;
72 Reply::DataItem subscribeDataItem;
73 ReplyMock notificationReplyMock;
74 std::shared_ptr<ReplyMock> notificationReplyArrayElement0;
75 std::shared_ptr<ReplyMock> notificationReplyArrayElement1;
76 std::shared_ptr<ReplyMock> notificationReplyArrayElement2;
77 Reply::ReplyVector notificationReplyVector;
78 Reply::DataItem notificationDataItem;
79 std::string notificationMessage;
80 Reply::DataItem notificationMessageDataItem;
81 Timer::Duration expectedSubscribeRetryTimerDuration;
82 Timer::Callback savedSubscribeRetryTimerCallback;
84 AsyncSentinelDatabaseDiscoveryBaseTest():
85 engineMock(std::make_shared<StrictMock<EngineMock>>()),
86 contentsBuilderMock(std::make_shared<StrictMock<ContentsBuilderMock>>(AsyncStorage::SEPARATOR)),
87 logger(createLogger(SDL_LOG_PREFIX)),
88 contents({{"aaa","bbb"},{3,3}}),
91 someOtherHost("someotherhost"),
93 hostDataItem({someHost,ReplyStringLength(someHost.length())}),
94 portDataItem({std::to_string(somePort),ReplyStringLength(std::to_string(somePort).length())}),
95 masterInquiryReplyHost(std::make_shared<ReplyMock>()),
96 masterInquiryReplyPort(std::make_shared<ReplyMock>()),
97 expectedMasterInquiryRetryTimerDuration(std::chrono::seconds(1)),
98 subscribeReplyArrayElement0(std::make_shared<ReplyMock>()),
99 subscribeReplyArrayElement1(std::make_shared<ReplyMock>()),
100 subscribeReplyArrayElement2(std::make_shared<ReplyMock>()),
101 subscribeDataItem({"subscribe",9}),
102 notificationReplyArrayElement0(std::make_shared<ReplyMock>()),
103 notificationReplyArrayElement1(std::make_shared<ReplyMock>()),
104 notificationReplyArrayElement2(std::make_shared<ReplyMock>()),
105 notificationDataItem({"message",7}),
106 notificationMessage("mymaster " + someHost + " " + std::to_string(somePort) + " " + someOtherHost + " " + std::to_string(someOtherPort)),
107 notificationMessageDataItem({notificationMessage, ReplyStringLength(notificationMessage.length())}),
108 expectedSubscribeRetryTimerDuration(std::chrono::seconds(1))
110 masterInquiryReply.push_back(masterInquiryReplyHost);
111 masterInquiryReply.push_back(masterInquiryReplyPort);
112 subscribeReplyVector.push_back(subscribeReplyArrayElement0);
113 subscribeReplyVector.push_back(subscribeReplyArrayElement1);
114 subscribeReplyVector.push_back(subscribeReplyArrayElement2);
115 notificationReplyVector.push_back(notificationReplyArrayElement0);
116 notificationReplyVector.push_back(notificationReplyArrayElement1);
117 notificationReplyVector.push_back(notificationReplyArrayElement2);
120 virtual ~AsyncSentinelDatabaseDiscoveryBaseTest()
124 std::shared_ptr<AsyncCommandDispatcher> asyncCommandDispatcherCreator()
126 // @TODO Add database info checking when configuration support for sentinel is added.
129 subscriberMock = std::make_shared<StrictMock<AsyncCommandDispatcherMock>>();
130 newDispatcherCreated();
131 return subscriberMock;
135 dispatcherMock = std::make_shared<StrictMock<AsyncCommandDispatcherMock>>();
136 newDispatcherCreated();
137 return dispatcherMock;
142 MOCK_METHOD0(newDispatcherCreated, void());
144 void expectDispatchersCreated()
146 EXPECT_CALL(*this, newDispatcherCreated())
150 void expectSubscriberWaitConnectedAsync()
152 EXPECT_CALL(*subscriberMock, waitConnectedAsync(_))
154 .WillOnce(Invoke([this](const AsyncCommandDispatcher::ConnectAck& connectAck)
156 subscriberConnectAck = connectAck;
160 void expectSubscriberRegisterDisconnectCb()
162 EXPECT_CALL(*subscriberMock, registerDisconnectCb(_))
164 .WillOnce(Invoke([this](const AsyncCommandDispatcher::DisconnectCb& disconnectCb)
166 subscriberDisconnectCb = disconnectCb;
170 void expectDispatcherWaitConnectedAsync()
172 EXPECT_CALL(*dispatcherMock, waitConnectedAsync(_))
174 .WillOnce(Invoke([this](const AsyncCommandDispatcher::ConnectAck& connectAck)
176 dispatcherConnectAck = connectAck;
180 void expectContentsBuild(const std::string& string,
181 const std::string& string2)
183 EXPECT_CALL(*contentsBuilderMock, build(string, string2))
185 .WillOnce(Return(contents));
188 void expectContentsBuild(const std::string& string,
189 const std::string& string2,
190 const std::string& string3)
192 EXPECT_CALL(*contentsBuilderMock, build(string, string2, string3))
194 .WillOnce(Return(contents));
197 void expectSubscriberDispatchAsync()
199 EXPECT_CALL(*subscriberMock, dispatchAsync(_, _, contents))
201 .WillOnce(SaveArg<0>(&savedSubscriberCommandCb));
204 void expectDispatcherDispatchAsync()
206 EXPECT_CALL(*dispatcherMock, dispatchAsync(_, _, contents))
208 .WillOnce(SaveArg<0>(&savedDispatcherCommandCb));
211 void expectSubscribeNotifications()
213 expectContentsBuild("SUBSCRIBE", "+switch-master");
214 expectSubscriberDispatchAsync();
217 void expectMasterInquiry()
219 expectContentsBuild("SENTINEL", "get-master-addr-by-name", "mymaster");
220 expectDispatcherDispatchAsync();
223 MOCK_METHOD1(stateChangedCb, void(const DatabaseInfo&));
225 void expectStateChangedCb(const std::string& host, uint16_t port)
227 EXPECT_CALL(*this, stateChangedCb(_))
229 .WillOnce(Invoke([this, host, port](const DatabaseInfo& databaseInfo)
231 EXPECT_THAT(DatabaseConfiguration::Addresses({ HostAndPort(host, htons(port)) }),
232 ContainerEq(databaseInfo.hosts));
233 EXPECT_EQ(DatabaseInfo::Type::SINGLE, databaseInfo.type);
234 EXPECT_EQ(boost::none, databaseInfo.ns);
235 EXPECT_EQ(DatabaseInfo::Discovery::SENTINEL, databaseInfo.discovery);
239 void expectMasterIquiryReply()
241 expectGetType(masterInquiryReplyMock, Reply::Type::ARRAY);
242 expectGetArray(masterInquiryReplyMock, masterInquiryReply);
243 expectGetType(*masterInquiryReplyHost, Reply::Type::STRING);
244 expectGetString(*masterInquiryReplyHost, hostDataItem);
245 expectGetType(*masterInquiryReplyPort, Reply::Type::STRING);
246 expectGetString(*masterInquiryReplyPort, portDataItem);
249 void expectMasterInquiryRetryTimer()
251 EXPECT_CALL(*engineMock, armTimer(_, expectedMasterInquiryRetryTimerDuration, _))
253 .WillOnce(SaveArg<2>(&savedMasterInquiryRetryTimerCallback));
256 void expectSubscribeRetryTimer()
258 EXPECT_CALL(*engineMock, armTimer(_, expectedSubscribeRetryTimerDuration, _))
260 .WillOnce(SaveArg<2>(&savedSubscribeRetryTimerCallback));
263 void setStateChangedCbExpectsBeforeMasterInquiry()
265 expectSubscriberRegisterDisconnectCb();
266 expectSubscriberWaitConnectedAsync();
267 asyncSentinelDatabaseDiscovery->setStateChangedCb(std::bind(&AsyncSentinelDatabaseDiscoveryBaseTest::stateChangedCb,
269 std::placeholders::_1));
270 expectSubscribeNotifications();
271 subscriberConnectAck();
272 expectSubscribeReply();
273 expectDispatcherWaitConnectedAsync();
274 savedSubscriberCommandCb(std::error_code(), subscribeReplyMock);
275 expectMasterInquiry();
278 void setDefaultResponsesForMasterInquiryReplyParsing()
280 ON_CALL(masterInquiryReplyMock, getType())
281 .WillByDefault(Return(Reply::Type::ARRAY));
282 ON_CALL(masterInquiryReplyMock, getArray())
283 .WillByDefault(Return(&masterInquiryReply));
284 ON_CALL(*masterInquiryReplyHost, getType())
285 .WillByDefault(Return(Reply::Type::STRING));
286 ON_CALL(*masterInquiryReplyHost, getString())
287 .WillByDefault(Return(&hostDataItem));
288 ON_CALL(*masterInquiryReplyPort, getType())
289 .WillByDefault(Return(Reply::Type::STRING));
290 ON_CALL(*masterInquiryReplyHost, getString())
291 .WillByDefault(Return(&portDataItem));
294 void expectGetType(ReplyMock& mock, const Reply::Type& type)
296 EXPECT_CALL(mock, getType())
298 .WillOnce(Return(type));
301 void expectGetString(ReplyMock& mock, const Reply::DataItem& item)
303 EXPECT_CALL(mock, getString())
305 .WillOnce(Return(&item));
308 void expectGetInteger(ReplyMock& mock, int value)
310 EXPECT_CALL(mock, getInteger())
312 .WillOnce(Return(value));
315 void expectGetArray(ReplyMock& mock, Reply::ReplyVector& replyVector)
317 EXPECT_CALL(mock, getArray())
319 .WillOnce(Return(&replyVector));
322 void expectSubscribeReply()
324 expectGetType(subscribeReplyMock, Reply::Type::ARRAY);
325 expectGetArray(subscribeReplyMock, subscribeReplyVector);
326 expectGetType(*subscribeReplyArrayElement0, Reply::Type::STRING);
327 expectGetString(*subscribeReplyArrayElement0, subscribeDataItem);
330 void expectNotificationReply()
332 expectGetType(notificationReplyMock, Reply::Type::ARRAY);
333 expectGetArray(notificationReplyMock, notificationReplyVector);
334 expectGetType(*notificationReplyArrayElement0, Reply::Type::STRING);
335 expectGetString(*notificationReplyArrayElement0, notificationDataItem);
336 expectGetType(*notificationReplyArrayElement2, Reply::Type::STRING);
337 expectGetString(*notificationReplyArrayElement2, notificationMessageDataItem);
340 void setDefaultResponsesForNotificationReplyParsing()
342 ON_CALL(notificationReplyMock, getType())
343 .WillByDefault(Return(Reply::Type::ARRAY));
344 ON_CALL(notificationReplyMock, getArray())
345 .WillByDefault(Return(¬ificationReplyVector));
346 ON_CALL(*notificationReplyArrayElement0, getType())
347 .WillByDefault(Return(Reply::Type::STRING));
348 ON_CALL(*notificationReplyArrayElement0, getString())
349 .WillByDefault(Return(¬ificationDataItem));
350 ON_CALL(*notificationReplyArrayElement2, getType())
351 .WillByDefault(Return(Reply::Type::STRING));
352 ON_CALL(*notificationReplyArrayElement2, getString())
353 .WillByDefault(Return(¬ificationMessageDataItem));
357 class AsyncSentinelDatabaseDiscoveryTest: public AsyncSentinelDatabaseDiscoveryBaseTest
360 AsyncSentinelDatabaseDiscoveryTest()
362 expectDispatchersCreated();
363 asyncSentinelDatabaseDiscovery.reset(
364 new AsyncSentinelDatabaseDiscovery(
367 std::bind(&AsyncSentinelDatabaseDiscoveryBaseTest::asyncCommandDispatcherCreator,
369 contentsBuilderMock));
372 ~AsyncSentinelDatabaseDiscoveryTest()
374 EXPECT_CALL(*subscriberMock, disableCommandCallbacks())
376 EXPECT_CALL(*dispatcherMock, disableCommandCallbacks())
381 class AsyncSentinelDatabaseDiscoveryInListeningModeTest: public AsyncSentinelDatabaseDiscoveryTest
384 AsyncSentinelDatabaseDiscoveryInListeningModeTest()
387 setStateChangedCbExpectsBeforeMasterInquiry();
388 dispatcherConnectAck();
389 expectMasterIquiryReply();
390 expectStateChangedCb(someHost, somePort);
391 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
395 using AsyncSentinelDatabaseDiscoveryDeathTest = AsyncSentinelDatabaseDiscoveryTest;
397 using AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest = AsyncSentinelDatabaseDiscoveryInListeningModeTest;
400 TEST_F(AsyncSentinelDatabaseDiscoveryBaseTest, IsNotCopyable)
403 EXPECT_FALSE(std::is_copy_constructible<AsyncSentinelDatabaseDiscovery>::value);
404 EXPECT_FALSE(std::is_copy_assignable<AsyncSentinelDatabaseDiscovery>::value);
407 TEST_F(AsyncSentinelDatabaseDiscoveryBaseTest, ImplementsAsyncDatabaseDiscovery)
410 EXPECT_TRUE((std::is_base_of<AsyncDatabaseDiscovery, AsyncSentinelDatabaseDiscovery>::value));
413 TEST_F(AsyncSentinelDatabaseDiscoveryTest, SettingChangedCallbackTriggersSentinelNotificationsSubscriptionAndMasterInquiry)
416 setStateChangedCbExpectsBeforeMasterInquiry();
417 dispatcherConnectAck();
418 expectMasterIquiryReply();
419 expectStateChangedCb(someHost, somePort);
420 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
423 TEST_F(AsyncSentinelDatabaseDiscoveryTest, MasterInquiryErrorTriggersRetry)
426 setStateChangedCbExpectsBeforeMasterInquiry();
427 dispatcherConnectAck();
428 expectMasterInquiryRetryTimer();
429 savedDispatcherCommandCb(getWellKnownErrorCode(), masterInquiryReplyMock);
430 expectMasterInquiry();
431 savedMasterInquiryRetryTimerCallback();
432 expectMasterIquiryReply();
433 expectStateChangedCb(someHost, somePort);
434 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
437 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidReplyType)
440 setStateChangedCbExpectsBeforeMasterInquiry();
441 dispatcherConnectAck();
442 ON_CALL(masterInquiryReplyMock, getType())
443 .WillByDefault(Return(Reply::Type::NIL));
444 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
447 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidHostElementType)
450 setStateChangedCbExpectsBeforeMasterInquiry();
451 dispatcherConnectAck();
452 setDefaultResponsesForMasterInquiryReplyParsing();
453 ON_CALL(*masterInquiryReplyHost, getType())
454 .WillByDefault(Return(Reply::Type::NIL));
455 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
458 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidPortElementType)
461 setStateChangedCbExpectsBeforeMasterInquiry();
462 dispatcherConnectAck();
463 setDefaultResponsesForMasterInquiryReplyParsing();
464 ON_CALL(*masterInquiryReplyPort, getType())
465 .WillByDefault(Return(Reply::Type::NIL));
466 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
469 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_PortCantBeCastedToInt)
472 setStateChangedCbExpectsBeforeMasterInquiry();
473 dispatcherConnectAck();
474 setDefaultResponsesForMasterInquiryReplyParsing();
475 std::string invalidPort("invalidPort");
476 Reply::DataItem invalidPortDataItem({invalidPort,ReplyStringLength(invalidPort.length())});
477 ON_CALL(*masterInquiryReplyPort, getString())
478 .WillByDefault(Return(&invalidPortDataItem));
479 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
482 TEST_F(AsyncSentinelDatabaseDiscoveryTest, CallbackIsNotCalledAfterCleared)
485 setStateChangedCbExpectsBeforeMasterInquiry();
486 dispatcherConnectAck();
487 expectMasterInquiryRetryTimer();
488 savedDispatcherCommandCb(getWellKnownErrorCode(), masterInquiryReplyMock);
489 expectMasterInquiry();
490 savedMasterInquiryRetryTimerCallback();
491 expectMasterIquiryReply();
492 asyncSentinelDatabaseDiscovery->clearStateChangedCb();
493 EXPECT_CALL(*this, stateChangedCb(_))
495 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
498 TEST_F(AsyncSentinelDatabaseDiscoveryTest, ChangeNotificationFromSentinel)
501 setStateChangedCbExpectsBeforeMasterInquiry();
502 dispatcherConnectAck();
503 expectMasterIquiryReply();
504 expectStateChangedCb(someHost, somePort);
505 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
506 expectNotificationReply();
507 expectStateChangedCb(someOtherHost, someOtherPort);
508 savedSubscriberCommandCb(std::error_code(), notificationReplyMock);
511 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeTest, SubscribeCommandErrorTriggersRetry)
514 expectSubscribeRetryTimer();
515 savedSubscriberCommandCb(getWellKnownErrorCode(), subscribeReplyMock);
516 expectSubscribeNotifications();
517 savedSubscribeRetryTimerCallback();
520 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidReplyType)
523 ON_CALL(notificationReplyMock, getType())
524 .WillByDefault(Return(Reply::Type::NIL));
525 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
528 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidKindElementType)
531 setDefaultResponsesForNotificationReplyParsing();
532 ON_CALL(*notificationReplyArrayElement0, getType())
533 .WillByDefault(Return(Reply::Type::NIL));
534 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
537 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidKind)
540 setDefaultResponsesForNotificationReplyParsing();
541 std::string invalidKind("invalidKind");
542 Reply::DataItem invalidKindDataItem({invalidKind,ReplyStringLength(invalidKind.length())});
543 ON_CALL(*notificationReplyArrayElement0, getString())
544 .WillByDefault(Return(&invalidKindDataItem));
545 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
548 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidMessageElementType)
551 setDefaultResponsesForNotificationReplyParsing();
552 ON_CALL(*notificationReplyArrayElement2, getType())
553 .WillByDefault(Return(Reply::Type::NIL));
554 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
557 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidMessageStructure)
560 setDefaultResponsesForNotificationReplyParsing();
561 std::string invalidMessage("mymaster oldHost 1234 5678");
562 auto invalidMessageDataItem(Reply::DataItem({invalidMessage, ReplyStringLength(invalidMessage.length())}));
563 ON_CALL(*notificationReplyArrayElement2, getString())
564 .WillByDefault(Return(&invalidMessageDataItem));
565 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*Notification message parsing error");
568 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidPort)
571 setDefaultResponsesForNotificationReplyParsing();
572 std::string invalidMessage("mymaster oldHost 1234 newHost invalidPort");
573 auto invalidMessageDataItem(Reply::DataItem({invalidMessage, ReplyStringLength(invalidMessage.length())}));
574 ON_CALL(*notificationReplyArrayElement2, getString())
575 .WillByDefault(Return(&invalidMessageDataItem));
576 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*Notification message parsing error");
579 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeTest, SubscriberDisconnectCallbackTriggersSubscriptionRenewal)
582 expectSubscriberWaitConnectedAsync();
583 subscriberDisconnectCb();
584 expectSubscribeNotifications();
585 subscriberConnectAck();
586 expectSubscribeReply();
587 expectDispatcherWaitConnectedAsync();
588 savedSubscriberCommandCb(std::error_code(), subscribeReplyMock);
589 expectMasterInquiry();
590 dispatcherConnectAck();
591 expectMasterIquiryReply();
592 expectStateChangedCb(someHost, somePort);
593 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);