blob: 45f7d8d6c98d1291033c0d2be42cef2e2f82cdb4 [file] [log] [blame]
Rolf Badorekef2bf512019-08-20 11:17:15 +03001/*
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
26using namespace shareddatalayer;
27using namespace shareddatalayer::redis;
28using namespace shareddatalayer::tst;
29using namespace testing;
30
31namespace
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
87TEST_F(HiredisEpollAdapterTest, IsNotCopyable)
88{
89 EXPECT_FALSE(std::is_copy_constructible<HiredisEpollAdapter>::value);
90 EXPECT_FALSE(std::is_copy_assignable<HiredisEpollAdapter>::value);
91}
92
93TEST_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
103TEST_F(HiredisEpollAdapterAttachedTest, DoesNotHandleInputEventIfNotReading)
104{
105 InSequence dummy;
106 EXPECT_CALL(hiredisSystemMock, redisAsyncHandleRead(&ac))
107 .Times(0);
108 savedEventHandler(EngineMock::EVENT_IN);
109}
110
111TEST_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
121TEST_F(HiredisEpollAdapterAttachedTest, DoesNotHandleOutputEventIfNotWriting)
122{
123 InSequence dummy;
124 EXPECT_CALL(hiredisSystemMock, redisAsyncHandleWrite(&ac))
125 .Times(0);
126 savedEventHandler(EngineMock::EVENT_OUT);
127}
128
129TEST_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
155TEST_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
166TEST_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
174TEST_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
182TEST_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
191TEST_F(HiredisEpollAdapterTest, DoesNotMakeCleanupIfDestructedWhileNotAttahced)
192{
193 InSequence dummy;
194 adapter.reset(new HiredisEpollAdapter(engineMock, hiredisSystemMock));
195}