Add Redis Sentinel based database discovery
[ric-plt/sdl.git] / tst / asynchiredisdatabasediscovery_test.cpp
1 /*
2    Copyright (c) 2018-2019 Nokia.
3
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
7
8        http://www.apache.org/licenses/LICENSE-2.0
9
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.
15 */
16
17 #include <type_traits>
18 #include <memory>
19 #include <cstring>
20 #include <arpa/inet.h>
21 #include <gtest/gtest.h>
22 #include "private/createlogger.hpp"
23 #include "private/databaseconfigurationimpl.hpp"
24 #include "private/logger.hpp"
25 #include "private/redis/asynchiredisdatabasediscovery.hpp"
26 #include "private/redis/databaseinfo.hpp"
27 #include "private/tst/enginemock.hpp"
28
29 using namespace shareddatalayer;
30 using namespace shareddatalayer::redis;
31 using namespace shareddatalayer::tst;
32 using namespace testing;
33
34 namespace
35 {
36     class AsyncHiredisDatabaseDiscoveryBaseTest: public testing::Test
37     {
38     public:
39         shareddatalayer::DatabaseConfiguration::Addresses someKnownStandaloneDatabaseAddress;
40         shareddatalayer::DatabaseConfiguration::Addresses someKnownClusterDatabaseAddresses;
41         std::shared_ptr<StrictMock<EngineMock>> engineMock;
42         const std::string defaultNamespaceName;
43         std::unique_ptr<AsyncHiredisDatabaseDiscovery> standaloneDiscovery;
44         std::unique_ptr<AsyncHiredisDatabaseDiscovery> clusterDiscovery;
45         Engine::Callback postedCallback;
46         std::shared_ptr<Logger> logger;
47
48         MOCK_METHOD1(stateChangedCb, void(const DatabaseInfo&));
49
50         AsyncHiredisDatabaseDiscoveryBaseTest():
51             someKnownStandaloneDatabaseAddress({ HostAndPort("addr1", htons(28416)) }),
52             someKnownClusterDatabaseAddresses({ HostAndPort("addr1", htons(28416)),
53                                                 HostAndPort("addr2", htons(56832)) }),
54             engineMock(std::make_shared<StrictMock<EngineMock>>()),
55             defaultNamespaceName("namespace"),
56             logger(createLogger(SDL_LOG_PREFIX))
57         {
58         }
59
60         virtual ~AsyncHiredisDatabaseDiscoveryBaseTest()
61         {
62         }
63
64         void expectStateChangedCbForStandalone()
65         {
66             EXPECT_CALL(*this, stateChangedCb(_))
67                 .Times(1)
68                 .WillOnce(Invoke([this](const DatabaseInfo& databaseInfo)
69                                  {
70                                      EXPECT_THAT(someKnownStandaloneDatabaseAddress, ContainerEq(databaseInfo.hosts));
71                                      EXPECT_EQ(DatabaseInfo::Type::SINGLE, databaseInfo.type);
72                                      EXPECT_STREQ(defaultNamespaceName.c_str(), databaseInfo.ns->c_str());
73                                  }));
74         }
75
76         void expectStateChangedCbForCluster()
77         {
78             EXPECT_CALL(*this, stateChangedCb(_))
79                 .Times(1)
80                 .WillOnce(Invoke([this](const DatabaseInfo& databaseInfo)
81                                  {
82                                      EXPECT_THAT(someKnownClusterDatabaseAddresses, ContainerEq(databaseInfo.hosts));
83                                      EXPECT_EQ(DatabaseInfo::Type::CLUSTER, databaseInfo.type);
84                                      EXPECT_EQ(DatabaseInfo::Discovery::HIREDIS, databaseInfo.discovery);
85                                      EXPECT_STREQ(defaultNamespaceName.c_str(), databaseInfo.ns->c_str());
86                                  }));
87         }
88
89         void expectPostStateChangedCb()
90         {
91             EXPECT_CALL(*engineMock, postCallback(_))
92                 .Times(1)
93                 .WillOnce(SaveArg<0>(&postedCallback));
94         }
95
96         void callPostedCallback()
97         {
98             ASSERT_NE(postedCallback, nullptr);
99             postedCallback();
100         }
101     };
102
103     class AsyncHiredisDatabaseDiscoveryTest: public AsyncHiredisDatabaseDiscoveryBaseTest
104     {
105     public:
106         AsyncHiredisDatabaseDiscoveryTest()
107         {
108             InSequence dummy;
109             standaloneDiscovery.reset(new AsyncHiredisDatabaseDiscovery(engineMock,
110                                                                         defaultNamespaceName,
111                                                                         DatabaseInfo::Type::SINGLE,
112                                                                         someKnownStandaloneDatabaseAddress,
113                                                                         logger));
114             clusterDiscovery.reset(new AsyncHiredisDatabaseDiscovery(engineMock,
115                                                                      defaultNamespaceName,
116                                                                      DatabaseInfo::Type::CLUSTER,
117                                                                      someKnownClusterDatabaseAddresses,
118                                                                      logger));
119         }
120
121         ~AsyncHiredisDatabaseDiscoveryTest()
122         {
123         }
124     };
125 }
126
127 TEST_F(AsyncHiredisDatabaseDiscoveryBaseTest, IsNotCopyable)
128 {
129     InSequence dummy;
130     EXPECT_FALSE(std::is_copy_constructible<AsyncHiredisDatabaseDiscovery>::value);
131     EXPECT_FALSE(std::is_copy_assignable<AsyncHiredisDatabaseDiscovery>::value);
132 }
133
134 TEST_F(AsyncHiredisDatabaseDiscoveryBaseTest, ImplementsAsyncDatabaseDiscovery)
135 {
136     InSequence dummy;
137     EXPECT_TRUE((std::is_base_of<AsyncDatabaseDiscovery, AsyncHiredisDatabaseDiscovery>::value));
138 }
139
140 TEST_F(AsyncHiredisDatabaseDiscoveryTest, StateChangedCallbackIsPostedImmediately)
141 {
142     InSequence dummy;
143     expectPostStateChangedCb();
144     clusterDiscovery->setStateChangedCb(std::bind(&AsyncHiredisDatabaseDiscoveryTest::stateChangedCb,
145                                                   this,
146                                                   std::placeholders::_1));
147     expectStateChangedCbForCluster();
148     callPostedCallback();
149
150     expectPostStateChangedCb();
151     standaloneDiscovery->setStateChangedCb(std::bind(&AsyncHiredisDatabaseDiscoveryTest::stateChangedCb,
152                                                      this,
153                                                      std::placeholders::_1));
154     expectStateChangedCbForStandalone();
155     callPostedCallback();
156 }