diff --git a/tst/asyncsentineldatabasediscovery_test.cpp b/tst/asyncsentineldatabasediscovery_test.cpp
new file mode 100644
index 0000000..dcf35c7
--- /dev/null
+++ b/tst/asyncsentineldatabasediscovery_test.cpp
@@ -0,0 +1,347 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <gtest/gtest.h>
+#include <arpa/inet.h>
+#include <sdl/asyncstorage.hpp>
+#include "private/createlogger.hpp"
+#include "private/hostandport.hpp"
+#include "private/timer.hpp"
+#include "private/redis/asyncsentineldatabasediscovery.hpp"
+#include "private/tst/asynccommanddispatchermock.hpp"
+#include "private/tst/contentsbuildermock.hpp"
+#include "private/tst/enginemock.hpp"
+#include "private/tst/replymock.hpp"
+#include "private/tst/wellknownerrorcode.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+using namespace shareddatalayer::tst;
+using namespace testing;
+
+namespace
+{
+    class AsyncSentinelDatabaseDiscoveryBaseTest: public testing::Test
+    {
+    public:
+        std::unique_ptr<AsyncSentinelDatabaseDiscovery> asyncSentinelDatabaseDiscovery;
+        std::shared_ptr<StrictMock<EngineMock>> engineMock;
+        std::shared_ptr<StrictMock<AsyncCommandDispatcherMock>> dispatcherMock;
+        std::shared_ptr<StrictMock<ContentsBuilderMock>> contentsBuilderMock;
+        std::shared_ptr<Logger> logger;
+        Contents contents;
+        AsyncCommandDispatcher::ConnectAck dispatcherConnectAck;
+        AsyncCommandDispatcher::CommandCb savedCommandCb;
+        ReplyMock replyMock;
+        std::string someHost;
+        uint16_t somePort;
+        Reply::DataItem hostDataItem;
+        Reply::DataItem portDataItem;
+        std::shared_ptr<ReplyMock> masterInquiryReplyHost;
+        std::shared_ptr<ReplyMock> masterInquiryReplyPort;
+        Reply::ReplyVector masterInquiryReply;
+        Timer::Duration expectedMasterInquiryRetryTimerDuration;
+        Timer::Callback savedConnectionRetryTimerCallback;
+
+        AsyncSentinelDatabaseDiscoveryBaseTest():
+            engineMock(std::make_shared<StrictMock<EngineMock>>()),
+            dispatcherMock(std::make_shared<StrictMock<AsyncCommandDispatcherMock>>()),
+            contentsBuilderMock(std::make_shared<StrictMock<ContentsBuilderMock>>(AsyncStorage::SEPARATOR)),
+            logger(createLogger(SDL_LOG_PREFIX)),
+            contents({{"aaa","bbb"},{3,3}}),
+            someHost("somehost"),
+            somePort(1234),
+            hostDataItem({someHost,ReplyStringLength(someHost.length())}),
+            portDataItem({std::to_string(somePort),ReplyStringLength(std::to_string(somePort).length())}),
+            masterInquiryReplyHost(std::make_shared<ReplyMock>()),
+            masterInquiryReplyPort(std::make_shared<ReplyMock>()),
+            expectedMasterInquiryRetryTimerDuration(std::chrono::seconds(1))
+        {
+            masterInquiryReply.push_back(masterInquiryReplyHost);
+            masterInquiryReply.push_back(masterInquiryReplyPort);
+        }
+
+        virtual ~AsyncSentinelDatabaseDiscoveryBaseTest()
+        {
+        }
+
+        std::shared_ptr<AsyncCommandDispatcher> asyncCommandDispatcherCreator(Engine&,
+                                                                              const DatabaseInfo&,
+                                                                              std::shared_ptr<ContentsBuilder>)
+        {
+            // @TODO Add database info checking when configuration support for sentinel is added.
+            newDispatcherCreated();
+            return dispatcherMock;
+        }
+
+        MOCK_METHOD0(newDispatcherCreated, void());
+
+        void expectNewDispatcherCreated()
+        {
+            EXPECT_CALL(*this, newDispatcherCreated())
+                .Times(1);
+        }
+
+        void expectDispatcherWaitConnectedAsync()
+        {
+            EXPECT_CALL(*dispatcherMock, waitConnectedAsync(_))
+                .Times(1)
+                .WillOnce(Invoke([this](const AsyncCommandDispatcher::ConnectAck& connectAck)
+                        {
+                            dispatcherConnectAck = connectAck;
+                        }));
+        }
+
+        void expectContentsBuild(const std::string& string,
+                                 const std::string& string2,
+                                 const std::string& string3)
+        {
+            EXPECT_CALL(*contentsBuilderMock, build(string, string2, string3))
+                .Times(1)
+                .WillOnce(Return(contents));
+        }
+
+        void expectDispatchAsync()
+        {
+            EXPECT_CALL(*dispatcherMock, dispatchAsync(_, _, contents))
+                .Times(1)
+                .WillOnce(SaveArg<0>(&savedCommandCb));
+        }
+
+        void expectMasterInquiry()
+        {
+            expectContentsBuild("SENTINEL", "get-master-addr-by-name", "mymaster");
+            expectDispatchAsync();
+        }
+
+        MOCK_METHOD1(stateChangedCb, void(const DatabaseInfo&));
+
+        void expectStateChangedCb()
+        {
+            EXPECT_CALL(*this, stateChangedCb(_))
+                .Times(1)
+                .WillOnce(Invoke([this](const DatabaseInfo& databaseInfo)
+                                 {
+                                     EXPECT_THAT(DatabaseConfiguration::Addresses({ HostAndPort(someHost, htons(somePort)) }),
+                                                 ContainerEq(databaseInfo.hosts));
+                                     EXPECT_EQ(DatabaseInfo::Type::SINGLE, databaseInfo.type);
+                                     EXPECT_EQ(boost::none, databaseInfo.ns);
+                                     EXPECT_EQ(DatabaseInfo::Discovery::SENTINEL, databaseInfo.discovery);
+                                 }));
+        }
+
+        void expectGetReplyType(ReplyMock& mock, const Reply::Type& type)
+        {
+            EXPECT_CALL(mock, getType())
+                .Times(1)
+                .WillOnce(Return(type));
+        }
+
+        void expectGetReplyArray_ReturnMasterInquiryReply()
+        {
+            EXPECT_CALL(replyMock, getArray())
+                .Times(1)
+                .WillOnce(Return(&masterInquiryReply));
+        }
+
+        void expectGetReplyString(ReplyMock& mock, const Reply::DataItem& item)
+        {
+            EXPECT_CALL(mock, getString())
+                .Times(1)
+                .WillOnce(Return(&item));
+        }
+
+        void expectMasterIquiryReply()
+        {
+            expectGetReplyType(replyMock, Reply::Type::ARRAY);
+            expectGetReplyArray_ReturnMasterInquiryReply();
+            expectGetReplyType(*masterInquiryReplyHost, Reply::Type::STRING);
+            expectGetReplyString(*masterInquiryReplyHost, hostDataItem);
+            expectGetReplyType(*masterInquiryReplyPort, Reply::Type::STRING);
+            expectGetReplyString(*masterInquiryReplyPort, portDataItem);
+        }
+
+        void expectMasterInquiryRetryTimer()
+        {
+            EXPECT_CALL(*engineMock, armTimer(_, expectedMasterInquiryRetryTimerDuration, _))
+                .Times(1)
+                .WillOnce(SaveArg<2>(&savedConnectionRetryTimerCallback));
+        }
+
+        void setDefaultResponsesForMasterInquiryReplyParsing()
+        {
+            ON_CALL(replyMock, getType())
+                .WillByDefault(Return(Reply::Type::ARRAY));
+            ON_CALL(replyMock, getArray())
+                .WillByDefault(Return(&masterInquiryReply));
+            ON_CALL(*masterInquiryReplyHost, getType())
+                .WillByDefault(Return(Reply::Type::STRING));
+            ON_CALL(*masterInquiryReplyHost, getString())
+                .WillByDefault(Return(&hostDataItem));
+            ON_CALL(*masterInquiryReplyPort, getType())
+                .WillByDefault(Return(Reply::Type::STRING));
+            ON_CALL(*masterInquiryReplyHost, getString())
+                .WillByDefault(Return(&portDataItem));
+        }
+    };
+
+    class AsyncSentinelDatabaseDiscoveryTest: public AsyncSentinelDatabaseDiscoveryBaseTest
+    {
+    public:
+        AsyncSentinelDatabaseDiscoveryTest()
+        {
+            expectNewDispatcherCreated();
+            asyncSentinelDatabaseDiscovery.reset(
+                    new AsyncSentinelDatabaseDiscovery(
+                            engineMock,
+                            logger,
+                            std::bind(&AsyncSentinelDatabaseDiscoveryBaseTest::asyncCommandDispatcherCreator,
+                                      this,
+                                      std::placeholders::_1,
+                                      std::placeholders::_2,
+                                      std::placeholders::_3),
+                            contentsBuilderMock));
+        }
+    };
+
+    using AsyncSentinelDatabaseDiscoveryDeathTest = AsyncSentinelDatabaseDiscoveryTest;
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryBaseTest, IsNotCopyable)
+{
+    InSequence dummy;
+    EXPECT_FALSE(std::is_copy_constructible<AsyncSentinelDatabaseDiscovery>::value);
+    EXPECT_FALSE(std::is_copy_assignable<AsyncSentinelDatabaseDiscovery>::value);
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryBaseTest, ImplementsAsyncDatabaseDiscovery)
+{
+    InSequence dummy;
+    EXPECT_TRUE((std::is_base_of<AsyncDatabaseDiscovery, AsyncSentinelDatabaseDiscovery>::value));
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryTest, RedisMasterIsInquiredFromSentinel)
+{
+    InSequence dummy;
+    expectDispatcherWaitConnectedAsync();
+    asyncSentinelDatabaseDiscovery->setStateChangedCb(std::bind(&AsyncSentinelDatabaseDiscoveryTest::stateChangedCb,
+            this,
+            std::placeholders::_1));
+    expectMasterInquiry();
+    dispatcherConnectAck();
+    expectMasterIquiryReply();
+    expectStateChangedCb();
+    savedCommandCb(std::error_code(), replyMock);
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryTest, RedisMasterInquiryErrorTriggersRetry)
+{
+    InSequence dummy;
+    expectDispatcherWaitConnectedAsync();
+    asyncSentinelDatabaseDiscovery->setStateChangedCb(std::bind(&AsyncSentinelDatabaseDiscoveryTest::stateChangedCb,
+            this,
+            std::placeholders::_1));
+    expectMasterInquiry();
+    dispatcherConnectAck();
+    expectMasterInquiryRetryTimer();
+    savedCommandCb(getWellKnownErrorCode(), replyMock);
+    expectMasterInquiry();
+    savedConnectionRetryTimerCallback();
+    expectMasterIquiryReply();
+    expectStateChangedCb();
+    savedCommandCb(std::error_code(), replyMock);
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidReplyType)
+{
+    InSequence dummy;
+    expectDispatcherWaitConnectedAsync();
+    asyncSentinelDatabaseDiscovery->setStateChangedCb(std::bind(&AsyncSentinelDatabaseDiscoveryTest::stateChangedCb,
+            this,
+            std::placeholders::_1));
+    expectMasterInquiry();
+    dispatcherConnectAck();
+    ON_CALL(replyMock, getType())
+        .WillByDefault(Return(Reply::Type::NIL));
+    EXPECT_EXIT(savedCommandCb(std::error_code(), replyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidHostElementType)
+{
+    InSequence dummy;
+    expectDispatcherWaitConnectedAsync();
+    asyncSentinelDatabaseDiscovery->setStateChangedCb(std::bind(&AsyncSentinelDatabaseDiscoveryTest::stateChangedCb,
+            this,
+            std::placeholders::_1));
+    expectMasterInquiry();
+    dispatcherConnectAck();
+    setDefaultResponsesForMasterInquiryReplyParsing();
+    ON_CALL(*masterInquiryReplyHost, getType())
+        .WillByDefault(Return(Reply::Type::NIL));
+    EXPECT_EXIT(savedCommandCb(std::error_code(), replyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_InvalidPortElementType)
+{
+    InSequence dummy;
+    expectDispatcherWaitConnectedAsync();
+    asyncSentinelDatabaseDiscovery->setStateChangedCb(std::bind(&AsyncSentinelDatabaseDiscoveryTest::stateChangedCb,
+            this,
+            std::placeholders::_1));
+    expectMasterInquiry();
+    dispatcherConnectAck();
+    setDefaultResponsesForMasterInquiryReplyParsing();
+    ON_CALL(*masterInquiryReplyPort, getType())
+        .WillByDefault(Return(Reply::Type::NIL));
+    EXPECT_EXIT(savedCommandCb(std::error_code(), replyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryDeathTest, MasterInquiryParsingErrorAborts_PortCantBeCastedToInt)
+{
+    InSequence dummy;
+    expectDispatcherWaitConnectedAsync();
+    asyncSentinelDatabaseDiscovery->setStateChangedCb(std::bind(&AsyncSentinelDatabaseDiscoveryTest::stateChangedCb,
+            this,
+            std::placeholders::_1));
+    expectMasterInquiry();
+    dispatcherConnectAck();
+    setDefaultResponsesForMasterInquiryReplyParsing();
+    std::string invalidPort("invalidPort");
+    Reply::DataItem invalidPortDataItem({invalidPort,ReplyStringLength(invalidPort.length())});
+    ON_CALL(*masterInquiryReplyPort, getString())
+        .WillByDefault(Return(&invalidPortDataItem));
+    EXPECT_EXIT(savedCommandCb(std::error_code(), replyMock), KilledBySignal(SIGABRT), ".*Master inquiry reply parsing error");
+}
+
+TEST_F(AsyncSentinelDatabaseDiscoveryTest, CallbackIsNotCalledAfterCleared)
+{
+    InSequence dummy;
+    expectDispatcherWaitConnectedAsync();
+    asyncSentinelDatabaseDiscovery->setStateChangedCb(std::bind(&AsyncSentinelDatabaseDiscoveryTest::stateChangedCb,
+            this,
+            std::placeholders::_1));
+    expectMasterInquiry();
+    dispatcherConnectAck();
+    expectMasterInquiryRetryTimer();
+    savedCommandCb(getWellKnownErrorCode(), replyMock);
+    expectMasterInquiry();
+    savedConnectionRetryTimerCallback();
+    expectMasterIquiryReply();
+    asyncSentinelDatabaseDiscovery->clearStateChangedCb();
+    EXPECT_CALL(*this, stateChangedCb(_))
+        .Times(0);
+    savedCommandCb(std::error_code(), replyMock);
+}
