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 HostAndPort(someHost, somePort),
369 std::bind(&AsyncSentinelDatabaseDiscoveryBaseTest::asyncCommandDispatcherCreator,
371 contentsBuilderMock));
374 ~AsyncSentinelDatabaseDiscoveryTest()
376 EXPECT_CALL(*subscriberMock, disableCommandCallbacks())
378 EXPECT_CALL(*dispatcherMock, disableCommandCallbacks())
383 class AsyncSentinelDatabaseDiscoveryInListeningModeTest: public AsyncSentinelDatabaseDiscoveryTest
386 AsyncSentinelDatabaseDiscoveryInListeningModeTest()
389 setStateChangedCbExpectsBeforeMasterInquiry();
390 dispatcherConnectAck();
391 expectMasterIquiryReply();
392 expectStateChangedCb(someHost, somePort);
393 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
397 using AsyncSentinelDatabaseDiscoveryDeathTest = AsyncSentinelDatabaseDiscoveryTest;
399 using AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest = AsyncSentinelDatabaseDiscoveryInListeningModeTest;
402 TEST_F(AsyncSentinelDatabaseDiscoveryBaseTest, IsNotCopyable)
405 EXPECT_FALSE(std::is_copy_constructible<AsyncSentinelDatabaseDiscovery>::value);
406 EXPECT_FALSE(std::is_copy_assignable<AsyncSentinelDatabaseDiscovery>::value);
409 TEST_F(AsyncSentinelDatabaseDiscoveryBaseTest, ImplementsAsyncDatabaseDiscovery)
412 EXPECT_TRUE((std::is_base_of<AsyncDatabaseDiscovery, AsyncSentinelDatabaseDiscovery>::value));
415 TEST_F(AsyncSentinelDatabaseDiscoveryTest, SettingChangedCallbackTriggersSentinelNotificationsSubscriptionAndMasterInquiry)
418 setStateChangedCbExpectsBeforeMasterInquiry();
419 dispatcherConnectAck();
420 expectMasterIquiryReply();
421 expectStateChangedCb(someHost, somePort);
422 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
425 TEST_F(AsyncSentinelDatabaseDiscoveryTest, MasterInquiryErrorTriggersRetry)
428 setStateChangedCbExpectsBeforeMasterInquiry();
429 dispatcherConnectAck();
430 expectMasterInquiryRetryTimer();
431 savedDispatcherCommandCb(getWellKnownErrorCode(), masterInquiryReplyMock);
432 expectMasterInquiry();
433 savedMasterInquiryRetryTimerCallback();
434 expectMasterIquiryReply();
435 expectStateChangedCb(someHost, somePort);
436 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
439 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidReplyType)
442 setStateChangedCbExpectsBeforeMasterInquiry();
443 dispatcherConnectAck();
444 ON_CALL(masterInquiryReplyMock, getType())
445 .WillByDefault(Return(Reply::Type::NIL));
446 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
449 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidHostElementType)
452 setStateChangedCbExpectsBeforeMasterInquiry();
453 dispatcherConnectAck();
454 setDefaultResponsesForMasterInquiryReplyParsing();
455 ON_CALL(*masterInquiryReplyHost, getType())
456 .WillByDefault(Return(Reply::Type::NIL));
457 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
460 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidPortElementType)
463 setStateChangedCbExpectsBeforeMasterInquiry();
464 dispatcherConnectAck();
465 setDefaultResponsesForMasterInquiryReplyParsing();
466 ON_CALL(*masterInquiryReplyPort, getType())
467 .WillByDefault(Return(Reply::Type::NIL));
468 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
471 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_PortCantBeCastedToInt)
474 setStateChangedCbExpectsBeforeMasterInquiry();
475 dispatcherConnectAck();
476 setDefaultResponsesForMasterInquiryReplyParsing();
477 std::string invalidPort("invalidPort");
478 Reply::DataItem invalidPortDataItem({invalidPort,ReplyStringLength(invalidPort.length())});
479 ON_CALL(*masterInquiryReplyPort, getString())
480 .WillByDefault(Return(&invalidPortDataItem));
481 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
484 TEST_F(AsyncSentinelDatabaseDiscoveryTest, CallbackIsNotCalledAfterCleared)
487 setStateChangedCbExpectsBeforeMasterInquiry();
488 dispatcherConnectAck();
489 expectMasterInquiryRetryTimer();
490 savedDispatcherCommandCb(getWellKnownErrorCode(), masterInquiryReplyMock);
491 expectMasterInquiry();
492 savedMasterInquiryRetryTimerCallback();
493 expectMasterIquiryReply();
494 asyncSentinelDatabaseDiscovery->clearStateChangedCb();
495 EXPECT_CALL(*this, stateChangedCb(_))
497 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
500 TEST_F(AsyncSentinelDatabaseDiscoveryTest, ChangeNotificationFromSentinel)
503 setStateChangedCbExpectsBeforeMasterInquiry();
504 dispatcherConnectAck();
505 expectMasterIquiryReply();
506 expectStateChangedCb(someHost, somePort);
507 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
508 expectNotificationReply();
509 expectStateChangedCb(someOtherHost, someOtherPort);
510 savedSubscriberCommandCb(std::error_code(), notificationReplyMock);
513 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeTest, SubscribeCommandErrorTriggersRetry)
516 expectSubscribeRetryTimer();
517 savedSubscriberCommandCb(getWellKnownErrorCode(), subscribeReplyMock);
518 expectSubscribeNotifications();
519 savedSubscribeRetryTimerCallback();
522 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidReplyType)
525 ON_CALL(notificationReplyMock, getType())
526 .WillByDefault(Return(Reply::Type::NIL));
527 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
530 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidKindElementType)
533 setDefaultResponsesForNotificationReplyParsing();
534 ON_CALL(*notificationReplyArrayElement0, getType())
535 .WillByDefault(Return(Reply::Type::NIL));
536 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
539 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidKind)
542 setDefaultResponsesForNotificationReplyParsing();
543 std::string invalidKind("invalidKind");
544 Reply::DataItem invalidKindDataItem({invalidKind,ReplyStringLength(invalidKind.length())});
545 ON_CALL(*notificationReplyArrayElement0, getString())
546 .WillByDefault(Return(&invalidKindDataItem));
547 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
550 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidMessageElementType)
553 setDefaultResponsesForNotificationReplyParsing();
554 ON_CALL(*notificationReplyArrayElement2, getType())
555 .WillByDefault(Return(Reply::Type::NIL));
556 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
559 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidMessageStructure)
562 setDefaultResponsesForNotificationReplyParsing();
563 std::string invalidMessage("mymaster oldHost 1234 5678");
564 auto invalidMessageDataItem(Reply::DataItem({invalidMessage, ReplyStringLength(invalidMessage.length())}));
565 ON_CALL(*notificationReplyArrayElement2, getString())
566 .WillByDefault(Return(&invalidMessageDataItem));
567 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*Notification message parsing error");
570 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidPort)
573 setDefaultResponsesForNotificationReplyParsing();
574 std::string invalidMessage("mymaster oldHost 1234 newHost invalidPort");
575 auto invalidMessageDataItem(Reply::DataItem({invalidMessage, ReplyStringLength(invalidMessage.length())}));
576 ON_CALL(*notificationReplyArrayElement2, getString())
577 .WillByDefault(Return(&invalidMessageDataItem));
578 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*Notification message parsing error");
581 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeTest, SubscriberDisconnectCallbackTriggersSubscriptionRenewal)
584 expectSubscriberWaitConnectedAsync();
585 subscriberDisconnectCb();
586 expectSubscribeNotifications();
587 subscriberConnectAck();
588 expectSubscribeReply();
589 expectDispatcherWaitConnectedAsync();
590 savedSubscriberCommandCb(std::error_code(), subscribeReplyMock);
591 expectMasterInquiry();
592 dispatcherConnectAck();
593 expectMasterIquiryReply();
594 expectStateChangedCb(someHost, somePort);
595 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);