45f7d8d6c98d1291033c0d2be42cef2e2f82cdb4
[ric-plt/sdl.git] / tst / hiredisepolladapter_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 <sys/epoll.h>
20 #include <async.h>
21 #include <gtest/gtest.h>
22 #include "private/redis/hiredisepolladapter.hpp"
23 #include "private/tst/enginemock.hpp"
24 #include "private/tst/hiredissystemmock.hpp"
25
26 using namespace shareddatalayer;
27 using namespace shareddatalayer::redis;
28 using namespace shareddatalayer::tst;
29 using namespace testing;
30
31 namespace
32 {
33     class HiredisEpollAdapterTest: public testing::Test
34     {
35     public:
36         StrictMock<EngineMock> engineMock;
37         StrictMock<HiredisSystemMock> hiredisSystemMock;
38         redisAsyncContext ac;
39         int acFd;
40         std::unique_ptr<HiredisEpollAdapter> adapter;
41         Engine::EventHandler savedEventHandler;
42
43         HiredisEpollAdapterTest():
44             ac { },
45             acFd(10)
46         {
47             ac.c.fd = acFd;
48             adapter.reset(new HiredisEpollAdapter(engineMock, hiredisSystemMock));
49         }
50
51         void expectAddMonitoredFD(int fd, unsigned int events)
52         {
53             EXPECT_CALL(engineMock, addMonitoredFD(fd,events,_))
54                 .Times(1)
55                 .WillOnce(SaveArg<2>(&savedEventHandler));
56         }
57
58         void expectModifyMonitoredFD(int fd, unsigned int events)
59         {
60             EXPECT_CALL(engineMock, modifyMonitoredFD(fd,events))
61                 .Times(1);
62         }
63
64         void expectDeleteMonitoredFD(int fd)
65         {
66             EXPECT_CALL(engineMock, deleteMonitoredFD(fd))
67                 .Times(1);
68         }
69     };
70
71     class HiredisEpollAdapterAttachedTest: public HiredisEpollAdapterTest
72     {
73     public:
74         HiredisEpollAdapterAttachedTest()
75         {
76             expectAddMonitoredFD(ac.c.fd, 0);
77             adapter->attach(&ac);
78         }
79
80         ~HiredisEpollAdapterAttachedTest()
81         {
82             expectDeleteMonitoredFD(ac.c.fd);
83         }
84     };
85 }
86
87 TEST_F(HiredisEpollAdapterTest, IsNotCopyable)
88 {
89     EXPECT_FALSE(std::is_copy_constructible<HiredisEpollAdapter>::value);
90     EXPECT_FALSE(std::is_copy_assignable<HiredisEpollAdapter>::value);
91 }
92
93 TEST_F(HiredisEpollAdapterAttachedTest, CanHandleInputEvents)
94 {
95     InSequence dummy;
96     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_IN);
97     ac.ev.addRead(ac.ev.data);
98     EXPECT_CALL(hiredisSystemMock, redisAsyncHandleRead(&ac))
99         .Times(1);
100     savedEventHandler(EngineMock::EVENT_IN);
101 }
102
103 TEST_F(HiredisEpollAdapterAttachedTest, DoesNotHandleInputEventIfNotReading)
104 {
105     InSequence dummy;
106     EXPECT_CALL(hiredisSystemMock, redisAsyncHandleRead(&ac))
107         .Times(0);
108     savedEventHandler(EngineMock::EVENT_IN);
109 }
110
111 TEST_F(HiredisEpollAdapterAttachedTest, CanHandleOutputEvents)
112 {
113     InSequence dummy;
114     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_OUT);
115     ac.ev.addWrite(ac.ev.data);
116     EXPECT_CALL(hiredisSystemMock, redisAsyncHandleWrite(&ac))
117         .Times(1);
118     savedEventHandler(EngineMock::EVENT_OUT);
119 }
120
121 TEST_F(HiredisEpollAdapterAttachedTest, DoesNotHandleOutputEventIfNotWriting)
122 {
123     InSequence dummy;
124     EXPECT_CALL(hiredisSystemMock, redisAsyncHandleWrite(&ac))
125         .Times(0);
126     savedEventHandler(EngineMock::EVENT_OUT);
127 }
128
129 TEST_F(HiredisEpollAdapterAttachedTest, CanBeAttachedAndEventStateChangedIdempotently)
130 {
131     InSequence dummy;
132     EXPECT_EQ(adapter.get(), ac.ev.data);
133     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_IN);
134     ac.ev.addRead(ac.ev.data);
135     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_IN | EngineMock::EVENT_OUT);
136     ac.ev.addWrite(ac.ev.data);
137     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_OUT);
138     ac.ev.delRead(ac.ev.data);
139     expectModifyMonitoredFD(ac.c.fd, 0);
140     ac.ev.delWrite(ac.ev.data);
141     expectModifyMonitoredFD(ac.c.fd,EngineMock::EVENT_IN);
142     ac.ev.addRead(ac.ev.data);
143     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_IN | EngineMock::EVENT_OUT);
144     ac.ev.addWrite(ac.ev.data);
145     expectDeleteMonitoredFD(ac.c.fd);
146     ac.ev.cleanup(ac.ev.data);
147     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_OUT);
148     ac.ev.addWrite(ac.ev.data);
149     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_IN | EngineMock::EVENT_OUT);
150     ac.ev.addRead(ac.ev.data);
151     expectAddMonitoredFD(ac.c.fd, 0);
152     adapter->attach(&ac);
153 }
154
155 TEST_F(HiredisEpollAdapterAttachedTest, FurtherAttachementsResetEventState)
156 {
157     InSequence dummy;
158     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_IN);
159     ac.ev.addRead(ac.ev.data);
160     expectAddMonitoredFD(ac.c.fd, 0);
161     adapter->attach(&ac);
162     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_OUT);
163     ac.ev.addWrite(ac.ev.data);
164 }
165
166 TEST_F(HiredisEpollAdapterAttachedTest, InputEventIsSetOnce)
167 {
168     InSequence dummy;
169     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_IN);
170     ac.ev.addRead(ac.ev.data);
171     ac.ev.addRead(ac.ev.data);
172 }
173
174 TEST_F(HiredisEpollAdapterAttachedTest, OutputEventIsSetOnce)
175 {
176     InSequence dummy;
177     expectModifyMonitoredFD(ac.c.fd, EngineMock::EVENT_OUT);
178     ac.ev.addWrite(ac.ev.data);
179     ac.ev.addWrite(ac.ev.data);
180 }
181
182 TEST_F(HiredisEpollAdapterAttachedTest, MakesCleanupIfDestructedWhileAttahced)
183 {
184     InSequence dummy;
185     expectDeleteMonitoredFD(ac.c.fd);
186     adapter.reset(new HiredisEpollAdapter(engineMock, hiredisSystemMock));
187     expectAddMonitoredFD(ac.c.fd, 0);
188     adapter->attach(&ac);
189 }
190
191 TEST_F(HiredisEpollAdapterTest, DoesNotMakeCleanupIfDestructedWhileNotAttahced)
192 {
193     InSequence dummy;
194     adapter.reset(new HiredisEpollAdapter(engineMock, hiredisSystemMock));
195 }