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.
18 * This source code is part of the near-RT RIC (RAN Intelligent Controller)
19 * platform project (RICP).
22 #include <gtest/gtest.h>
23 #include <arpa/inet.h>
25 #include <sdl/asyncstorage.hpp>
26 #include "private/createlogger.hpp"
27 #include "private/hostandport.hpp"
28 #include "private/timer.hpp"
29 #include "private/redis/asyncsentineldatabasediscovery.hpp"
30 #include "private/tst/asynccommanddispatchermock.hpp"
31 #include "private/tst/contentsbuildermock.hpp"
32 #include "private/tst/enginemock.hpp"
33 #include "private/tst/replymock.hpp"
34 #include "private/tst/wellknownerrorcode.hpp"
36 using namespace shareddatalayer;
37 using namespace shareddatalayer::redis;
38 using namespace shareddatalayer::tst;
39 using namespace testing;
43 class AsyncSentinelDatabaseDiscoveryBaseTest: public testing::Test
46 std::unique_ptr<AsyncSentinelDatabaseDiscovery> asyncSentinelDatabaseDiscovery;
47 std::shared_ptr<StrictMock<EngineMock>> engineMock;
48 std::shared_ptr<StrictMock<AsyncCommandDispatcherMock>> subscriberMock;
49 std::shared_ptr<StrictMock<AsyncCommandDispatcherMock>> dispatcherMock;
50 std::shared_ptr<StrictMock<ContentsBuilderMock>> contentsBuilderMock;
51 std::shared_ptr<Logger> logger;
53 AsyncCommandDispatcher::ConnectAck subscriberConnectAck;
54 AsyncCommandDispatcher::DisconnectCb subscriberDisconnectCb;
55 AsyncCommandDispatcher::ConnectAck dispatcherConnectAck;
56 AsyncCommandDispatcher::CommandCb savedSubscriberCommandCb;
57 AsyncCommandDispatcher::CommandCb savedDispatcherCommandCb;
58 ReplyMock masterInquiryReplyMock;
61 std::string someOtherHost;
62 uint16_t someOtherPort;
63 Reply::DataItem hostDataItem;
64 Reply::DataItem portDataItem;
65 std::shared_ptr<ReplyMock> masterInquiryReplyHost;
66 std::shared_ptr<ReplyMock> masterInquiryReplyPort;
67 Reply::ReplyVector masterInquiryReply;
68 Timer::Duration expectedMasterInquiryRetryTimerDuration;
69 Timer::Callback savedMasterInquiryRetryTimerCallback;
70 // Mocks for SUBSCRIBE command replies are a bit complicated, because reply might have several
71 // meanings/structures: https://redis.io/topics/pubsub#format-of-pushed-messages
72 ReplyMock subscribeReplyMock;
73 std::shared_ptr<ReplyMock> subscribeReplyArrayElement0;
74 std::shared_ptr<ReplyMock> subscribeReplyArrayElement1;
75 std::shared_ptr<ReplyMock> subscribeReplyArrayElement2;
76 Reply::ReplyVector subscribeReplyVector;
77 Reply::DataItem subscribeDataItem;
78 ReplyMock notificationReplyMock;
79 std::shared_ptr<ReplyMock> notificationReplyArrayElement0;
80 std::shared_ptr<ReplyMock> notificationReplyArrayElement1;
81 std::shared_ptr<ReplyMock> notificationReplyArrayElement2;
82 Reply::ReplyVector notificationReplyVector;
83 Reply::DataItem notificationDataItem;
84 std::string notificationMessage;
85 Reply::DataItem notificationMessageDataItem;
86 Timer::Duration expectedSubscribeRetryTimerDuration;
87 Timer::Callback savedSubscribeRetryTimerCallback;
89 AsyncSentinelDatabaseDiscoveryBaseTest():
90 engineMock(std::make_shared<StrictMock<EngineMock>>()),
91 contentsBuilderMock(std::make_shared<StrictMock<ContentsBuilderMock>>(AsyncStorage::SEPARATOR)),
92 logger(createLogger(SDL_LOG_PREFIX)),
93 contents({{"aaa","bbb"},{3,3}}),
96 someOtherHost("someotherhost"),
98 hostDataItem({someHost,ReplyStringLength(someHost.length())}),
99 portDataItem({std::to_string(somePort),ReplyStringLength(std::to_string(somePort).length())}),
100 masterInquiryReplyHost(std::make_shared<ReplyMock>()),
101 masterInquiryReplyPort(std::make_shared<ReplyMock>()),
102 expectedMasterInquiryRetryTimerDuration(std::chrono::seconds(1)),
103 subscribeReplyArrayElement0(std::make_shared<ReplyMock>()),
104 subscribeReplyArrayElement1(std::make_shared<ReplyMock>()),
105 subscribeReplyArrayElement2(std::make_shared<ReplyMock>()),
106 subscribeDataItem({"subscribe",9}),
107 notificationReplyArrayElement0(std::make_shared<ReplyMock>()),
108 notificationReplyArrayElement1(std::make_shared<ReplyMock>()),
109 notificationReplyArrayElement2(std::make_shared<ReplyMock>()),
110 notificationDataItem({"message",7}),
111 notificationMessage("mymaster " + someHost + " " + std::to_string(somePort) + " " + someOtherHost + " " + std::to_string(someOtherPort)),
112 notificationMessageDataItem({notificationMessage, ReplyStringLength(notificationMessage.length())}),
113 expectedSubscribeRetryTimerDuration(std::chrono::seconds(1))
115 masterInquiryReply.push_back(masterInquiryReplyHost);
116 masterInquiryReply.push_back(masterInquiryReplyPort);
117 subscribeReplyVector.push_back(subscribeReplyArrayElement0);
118 subscribeReplyVector.push_back(subscribeReplyArrayElement1);
119 subscribeReplyVector.push_back(subscribeReplyArrayElement2);
120 notificationReplyVector.push_back(notificationReplyArrayElement0);
121 notificationReplyVector.push_back(notificationReplyArrayElement1);
122 notificationReplyVector.push_back(notificationReplyArrayElement2);
125 virtual ~AsyncSentinelDatabaseDiscoveryBaseTest()
129 std::shared_ptr<AsyncCommandDispatcher> asyncCommandDispatcherCreator()
131 // @TODO Add database info checking when configuration support for sentinel is added.
134 subscriberMock = std::make_shared<StrictMock<AsyncCommandDispatcherMock>>();
135 newDispatcherCreated();
136 return subscriberMock;
140 dispatcherMock = std::make_shared<StrictMock<AsyncCommandDispatcherMock>>();
141 newDispatcherCreated();
142 return dispatcherMock;
147 MOCK_METHOD0(newDispatcherCreated, void());
149 void expectDispatchersCreated()
151 EXPECT_CALL(*this, newDispatcherCreated())
155 void expectSubscriberWaitConnectedAsync()
157 EXPECT_CALL(*subscriberMock, waitConnectedAsync(_))
159 .WillOnce(Invoke([this](const AsyncCommandDispatcher::ConnectAck& connectAck)
161 subscriberConnectAck = connectAck;
165 void expectSubscriberRegisterDisconnectCb()
167 EXPECT_CALL(*subscriberMock, registerDisconnectCb(_))
169 .WillOnce(Invoke([this](const AsyncCommandDispatcher::DisconnectCb& disconnectCb)
171 subscriberDisconnectCb = disconnectCb;
175 void expectDispatcherWaitConnectedAsync()
177 EXPECT_CALL(*dispatcherMock, waitConnectedAsync(_))
179 .WillOnce(Invoke([this](const AsyncCommandDispatcher::ConnectAck& connectAck)
181 dispatcherConnectAck = connectAck;
185 void expectContentsBuild(const std::string& string,
186 const std::string& string2)
188 EXPECT_CALL(*contentsBuilderMock, build(string, string2))
190 .WillOnce(Return(contents));
193 void expectContentsBuild(const std::string& string,
194 const std::string& string2,
195 const std::string& string3)
197 EXPECT_CALL(*contentsBuilderMock, build(string, string2, string3))
199 .WillOnce(Return(contents));
202 void expectSubscriberDispatchAsync()
204 EXPECT_CALL(*subscriberMock, dispatchAsync(_, _, contents))
206 .WillOnce(SaveArg<0>(&savedSubscriberCommandCb));
209 void expectDispatcherDispatchAsync()
211 EXPECT_CALL(*dispatcherMock, dispatchAsync(_, _, contents))
213 .WillOnce(SaveArg<0>(&savedDispatcherCommandCb));
216 void expectSubscribeNotifications()
218 expectContentsBuild("SUBSCRIBE", "+switch-master");
219 expectSubscriberDispatchAsync();
222 void expectMasterInquiry()
224 expectContentsBuild("SENTINEL", "get-master-addr-by-name", "mymaster");
225 expectDispatcherDispatchAsync();
228 MOCK_METHOD1(stateChangedCb, void(const DatabaseInfo&));
230 void expectStateChangedCb(const std::string& host, uint16_t port)
232 EXPECT_CALL(*this, stateChangedCb(_))
234 .WillOnce(Invoke([this, host, port](const DatabaseInfo& databaseInfo)
236 EXPECT_THAT(DatabaseConfiguration::Addresses({ HostAndPort(host, htons(port)) }),
237 ContainerEq(databaseInfo.hosts));
238 EXPECT_EQ(DatabaseInfo::Type::SINGLE, databaseInfo.type);
239 EXPECT_EQ(boost::none, databaseInfo.ns);
240 EXPECT_EQ(DatabaseInfo::Discovery::SENTINEL, databaseInfo.discovery);
244 void expectMasterIquiryReply()
246 expectGetType(masterInquiryReplyMock, Reply::Type::ARRAY);
247 expectGetArray(masterInquiryReplyMock, masterInquiryReply);
248 expectGetType(*masterInquiryReplyHost, Reply::Type::STRING);
249 expectGetString(*masterInquiryReplyHost, hostDataItem);
250 expectGetType(*masterInquiryReplyPort, Reply::Type::STRING);
251 expectGetString(*masterInquiryReplyPort, portDataItem);
254 void expectMasterInquiryRetryTimer()
256 EXPECT_CALL(*engineMock, armTimer(_, expectedMasterInquiryRetryTimerDuration, _))
258 .WillOnce(SaveArg<2>(&savedMasterInquiryRetryTimerCallback));
261 void expectSubscribeRetryTimer()
263 EXPECT_CALL(*engineMock, armTimer(_, expectedSubscribeRetryTimerDuration, _))
265 .WillOnce(SaveArg<2>(&savedSubscribeRetryTimerCallback));
268 void setStateChangedCbExpectsBeforeMasterInquiry()
270 expectSubscriberRegisterDisconnectCb();
271 expectSubscriberWaitConnectedAsync();
272 asyncSentinelDatabaseDiscovery->setStateChangedCb(std::bind(&AsyncSentinelDatabaseDiscoveryBaseTest::stateChangedCb,
274 std::placeholders::_1));
275 expectSubscribeNotifications();
276 subscriberConnectAck();
277 expectSubscribeReply();
278 expectDispatcherWaitConnectedAsync();
279 savedSubscriberCommandCb(std::error_code(), subscribeReplyMock);
280 expectMasterInquiry();
283 void setDefaultResponsesForMasterInquiryReplyParsing()
285 ON_CALL(masterInquiryReplyMock, getType())
286 .WillByDefault(Return(Reply::Type::ARRAY));
287 ON_CALL(masterInquiryReplyMock, getArray())
288 .WillByDefault(Return(&masterInquiryReply));
289 ON_CALL(*masterInquiryReplyHost, getType())
290 .WillByDefault(Return(Reply::Type::STRING));
291 ON_CALL(*masterInquiryReplyHost, getString())
292 .WillByDefault(Return(&hostDataItem));
293 ON_CALL(*masterInquiryReplyPort, getType())
294 .WillByDefault(Return(Reply::Type::STRING));
295 ON_CALL(*masterInquiryReplyHost, getString())
296 .WillByDefault(Return(&portDataItem));
299 void expectGetType(ReplyMock& mock, const Reply::Type& type)
301 EXPECT_CALL(mock, getType())
303 .WillOnce(Return(type));
306 void expectGetString(ReplyMock& mock, const Reply::DataItem& item)
308 EXPECT_CALL(mock, getString())
310 .WillOnce(Return(&item));
313 void expectGetInteger(ReplyMock& mock, int value)
315 EXPECT_CALL(mock, getInteger())
317 .WillOnce(Return(value));
320 void expectGetArray(ReplyMock& mock, Reply::ReplyVector& replyVector)
322 EXPECT_CALL(mock, getArray())
324 .WillOnce(Return(&replyVector));
327 void expectSubscribeReply()
329 expectGetType(subscribeReplyMock, Reply::Type::ARRAY);
330 expectGetArray(subscribeReplyMock, subscribeReplyVector);
331 expectGetType(*subscribeReplyArrayElement0, Reply::Type::STRING);
332 expectGetString(*subscribeReplyArrayElement0, subscribeDataItem);
335 void expectNotificationReply()
337 expectGetType(notificationReplyMock, Reply::Type::ARRAY);
338 expectGetArray(notificationReplyMock, notificationReplyVector);
339 expectGetType(*notificationReplyArrayElement0, Reply::Type::STRING);
340 expectGetString(*notificationReplyArrayElement0, notificationDataItem);
341 expectGetType(*notificationReplyArrayElement2, Reply::Type::STRING);
342 expectGetString(*notificationReplyArrayElement2, notificationMessageDataItem);
345 void setDefaultResponsesForNotificationReplyParsing()
347 ON_CALL(notificationReplyMock, getType())
348 .WillByDefault(Return(Reply::Type::ARRAY));
349 ON_CALL(notificationReplyMock, getArray())
350 .WillByDefault(Return(¬ificationReplyVector));
351 ON_CALL(*notificationReplyArrayElement0, getType())
352 .WillByDefault(Return(Reply::Type::STRING));
353 ON_CALL(*notificationReplyArrayElement0, getString())
354 .WillByDefault(Return(¬ificationDataItem));
355 ON_CALL(*notificationReplyArrayElement2, getType())
356 .WillByDefault(Return(Reply::Type::STRING));
357 ON_CALL(*notificationReplyArrayElement2, getString())
358 .WillByDefault(Return(¬ificationMessageDataItem));
362 class AsyncSentinelDatabaseDiscoveryTest: public AsyncSentinelDatabaseDiscoveryBaseTest
365 AsyncSentinelDatabaseDiscoveryTest()
367 expectDispatchersCreated();
368 asyncSentinelDatabaseDiscovery.reset(
369 new AsyncSentinelDatabaseDiscovery(
372 HostAndPort(someHost, somePort),
374 std::bind(&AsyncSentinelDatabaseDiscoveryBaseTest::asyncCommandDispatcherCreator,
376 contentsBuilderMock));
379 ~AsyncSentinelDatabaseDiscoveryTest()
381 EXPECT_CALL(*subscriberMock, disableCommandCallbacks())
383 EXPECT_CALL(*dispatcherMock, disableCommandCallbacks())
388 class AsyncSentinelDatabaseDiscoveryInListeningModeTest: public AsyncSentinelDatabaseDiscoveryTest
391 AsyncSentinelDatabaseDiscoveryInListeningModeTest()
394 setStateChangedCbExpectsBeforeMasterInquiry();
395 dispatcherConnectAck();
396 expectMasterIquiryReply();
397 expectStateChangedCb(someHost, somePort);
398 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
402 using AsyncSentinelDatabaseDiscoveryDeathTest = AsyncSentinelDatabaseDiscoveryTest;
404 using AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest = AsyncSentinelDatabaseDiscoveryInListeningModeTest;
407 TEST_F(AsyncSentinelDatabaseDiscoveryBaseTest, IsNotCopyable)
410 EXPECT_FALSE(std::is_copy_constructible<AsyncSentinelDatabaseDiscovery>::value);
411 EXPECT_FALSE(std::is_copy_assignable<AsyncSentinelDatabaseDiscovery>::value);
414 TEST_F(AsyncSentinelDatabaseDiscoveryBaseTest, ImplementsAsyncDatabaseDiscovery)
417 EXPECT_TRUE((std::is_base_of<AsyncDatabaseDiscovery, AsyncSentinelDatabaseDiscovery>::value));
420 TEST_F(AsyncSentinelDatabaseDiscoveryTest, SettingChangedCallbackTriggersSentinelNotificationsSubscriptionAndMasterInquiry)
423 setStateChangedCbExpectsBeforeMasterInquiry();
424 dispatcherConnectAck();
425 expectMasterIquiryReply();
426 expectStateChangedCb(someHost, somePort);
427 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
430 TEST_F(AsyncSentinelDatabaseDiscoveryTest, MasterInquiryErrorTriggersRetry)
433 setStateChangedCbExpectsBeforeMasterInquiry();
434 dispatcherConnectAck();
435 expectMasterInquiryRetryTimer();
436 savedDispatcherCommandCb(getWellKnownErrorCode(), masterInquiryReplyMock);
437 expectMasterInquiry();
438 savedMasterInquiryRetryTimerCallback();
439 expectMasterIquiryReply();
440 expectStateChangedCb(someHost, somePort);
441 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
444 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidReplyType)
447 setStateChangedCbExpectsBeforeMasterInquiry();
448 dispatcherConnectAck();
449 ON_CALL(masterInquiryReplyMock, getType())
450 .WillByDefault(Return(Reply::Type::NIL));
451 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
454 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidHostElementType)
457 setStateChangedCbExpectsBeforeMasterInquiry();
458 dispatcherConnectAck();
459 setDefaultResponsesForMasterInquiryReplyParsing();
460 ON_CALL(*masterInquiryReplyHost, getType())
461 .WillByDefault(Return(Reply::Type::NIL));
462 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
465 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidPortElementType)
468 setStateChangedCbExpectsBeforeMasterInquiry();
469 dispatcherConnectAck();
470 setDefaultResponsesForMasterInquiryReplyParsing();
471 ON_CALL(*masterInquiryReplyPort, getType())
472 .WillByDefault(Return(Reply::Type::NIL));
473 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
476 TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_PortCantBeCastedToInt)
479 setStateChangedCbExpectsBeforeMasterInquiry();
480 dispatcherConnectAck();
481 setDefaultResponsesForMasterInquiryReplyParsing();
482 std::string invalidPort("invalidPort");
483 Reply::DataItem invalidPortDataItem({invalidPort,ReplyStringLength(invalidPort.length())});
484 ON_CALL(*masterInquiryReplyPort, getString())
485 .WillByDefault(Return(&invalidPortDataItem));
486 EXPECT_EXIT(savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
489 TEST_F(AsyncSentinelDatabaseDiscoveryTest, CallbackIsNotCalledAfterCleared)
492 setStateChangedCbExpectsBeforeMasterInquiry();
493 dispatcherConnectAck();
494 expectMasterInquiryRetryTimer();
495 savedDispatcherCommandCb(getWellKnownErrorCode(), masterInquiryReplyMock);
496 expectMasterInquiry();
497 savedMasterInquiryRetryTimerCallback();
498 expectMasterIquiryReply();
499 asyncSentinelDatabaseDiscovery->clearStateChangedCb();
500 EXPECT_CALL(*this, stateChangedCb(_))
502 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
505 TEST_F(AsyncSentinelDatabaseDiscoveryTest, ChangeNotificationFromSentinel)
508 setStateChangedCbExpectsBeforeMasterInquiry();
509 dispatcherConnectAck();
510 expectMasterIquiryReply();
511 expectStateChangedCb(someHost, somePort);
512 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);
513 expectNotificationReply();
514 expectStateChangedCb(someOtherHost, someOtherPort);
515 savedSubscriberCommandCb(std::error_code(), notificationReplyMock);
518 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeTest, SubscribeCommandErrorTriggersRetry)
521 expectSubscribeRetryTimer();
522 savedSubscriberCommandCb(getWellKnownErrorCode(), subscribeReplyMock);
523 expectSubscribeNotifications();
524 savedSubscribeRetryTimerCallback();
527 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidReplyType)
530 ON_CALL(notificationReplyMock, getType())
531 .WillByDefault(Return(Reply::Type::NIL));
532 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
535 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidKindElementType)
538 setDefaultResponsesForNotificationReplyParsing();
539 ON_CALL(*notificationReplyArrayElement0, getType())
540 .WillByDefault(Return(Reply::Type::NIL));
541 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
544 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidKind)
547 setDefaultResponsesForNotificationReplyParsing();
548 std::string invalidKind("invalidKind");
549 Reply::DataItem invalidKindDataItem({invalidKind,ReplyStringLength(invalidKind.length())});
550 ON_CALL(*notificationReplyArrayElement0, getString())
551 .WillByDefault(Return(&invalidKindDataItem));
552 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
555 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidMessageElementType)
558 setDefaultResponsesForNotificationReplyParsing();
559 ON_CALL(*notificationReplyArrayElement2, getType())
560 .WillByDefault(Return(Reply::Type::NIL));
561 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*SUBSCRIBE command reply parsing error");
564 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidMessageStructure)
567 setDefaultResponsesForNotificationReplyParsing();
568 std::string invalidMessage("mymaster oldHost 1234 5678");
569 auto invalidMessageDataItem(Reply::DataItem({invalidMessage, ReplyStringLength(invalidMessage.length())}));
570 ON_CALL(*notificationReplyArrayElement2, getString())
571 .WillByDefault(Return(&invalidMessageDataItem));
572 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*Notification message parsing error");
575 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeDeathTest, SubscribeReplyParsingErrorAborts_InvalidPort)
578 setDefaultResponsesForNotificationReplyParsing();
579 std::string invalidMessage("mymaster oldHost 1234 newHost invalidPort");
580 auto invalidMessageDataItem(Reply::DataItem({invalidMessage, ReplyStringLength(invalidMessage.length())}));
581 ON_CALL(*notificationReplyArrayElement2, getString())
582 .WillByDefault(Return(&invalidMessageDataItem));
583 EXPECT_EXIT(savedSubscriberCommandCb(std::error_code(), notificationReplyMock), KilledBySignal(SIGABRT), ".*Notification message parsing error");
586 TEST_F(AsyncSentinelDatabaseDiscoveryInListeningModeTest, SubscriberDisconnectCallbackTriggersSubscriptionRenewal)
589 expectSubscriberWaitConnectedAsync();
590 subscriberDisconnectCb();
591 expectSubscribeNotifications();
592 subscriberConnectAck();
593 expectSubscribeReply();
594 expectDispatcherWaitConnectedAsync();
595 savedSubscriberCommandCb(std::error_code(), subscribeReplyMock);
596 expectMasterInquiry();
597 dispatcherConnectAck();
598 expectMasterIquiryReply();
599 expectStateChangedCb(someHost, somePort);
600 savedDispatcherCommandCb(std::error_code(), masterInquiryReplyMock);