blob: 3dd9dd45f49f52782bd34027512e02cbcf6ee632 [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
Timo Tietavainena0745d22019-11-28 09:55:22 +020017/*
18 * This source code is part of the near-RT RIC (RAN Intelligent Controller)
19 * platform project (RICP).
20*/
21
Rolf Badorekef2bf512019-08-20 11:17:15 +030022#include <gtest/gtest.h>
23#include "private/error.hpp"
24#include "private/redis/asyncredisstorage.hpp"
25#include "private/syncstorageimpl.hpp"
26#include "private/tst/asyncstoragemock.hpp"
27#include "private/tst/systemmock.hpp"
28#include <sdl/backenderror.hpp>
29#include <sdl/invalidnamespace.hpp>
30#include <sdl/notconnected.hpp>
31#include <sdl/operationinterrupted.hpp>
32#include <sdl/rejectedbybackend.hpp>
Timo Tietavainend565df62021-08-11 07:33:30 +030033#include <sdl/rejectedbysdl.hpp>
Rolf Badorekef2bf512019-08-20 11:17:15 +030034
35using namespace shareddatalayer;
36using namespace shareddatalayer::redis;
37using namespace shareddatalayer::tst;
38using namespace testing;
39
40namespace
41{
42 class SyncStorageImplTest: public testing::Test
43 {
44 public:
45 std::unique_ptr<SyncStorageImpl> syncStorage;
46 /* AsyncStorageMock ownership will be passed to implementation. To be able to do verification
47 * with the mock object also here after its ownership is passed we take raw pointer to
48 * AsyncStorageMock before passing it to implementation. Works fine, as implementation will
49 * not release injected mock object before test case execution finishes
50 */
51 std::unique_ptr<StrictMock<AsyncStorageMock>> asyncStorageMockPassedToImplementation;
52 StrictMock<AsyncStorageMock>* asyncStorageMockRawPtr;
53 StrictMock<SystemMock> systemMock;
54 AsyncStorage::ModifyAck savedModifyAck;
55 AsyncStorage::ModifyIfAck savedModifyIfAck;
56 AsyncStorage::GetAck savedGetAck;
57 AsyncStorage::FindKeysAck savedFindKeysAck;
58 AsyncStorage::ReadyAck savedReadyAck;
59 int pFd;
60 SyncStorage::DataMap dataMap;
61 SyncStorage::Keys keys;
62 const SyncStorage::Namespace ns;
Timo Tietavainend565df62021-08-11 07:33:30 +030063 std::chrono::steady_clock::duration TEST_READY_WAIT_TIMEOUT;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +030064 std::chrono::steady_clock::duration TEST_OPERATION_WAIT_TIMEOUT;
Timo Tietavainend565df62021-08-11 07:33:30 +030065 int TEST_READY_POLL_WAIT_TIMEOUT;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +030066 int TEST_OPERATION_POLL_WAIT_TIMEOUT;
Rolf Badorekef2bf512019-08-20 11:17:15 +030067 SyncStorageImplTest():
68 asyncStorageMockPassedToImplementation(new StrictMock<AsyncStorageMock>()),
69 asyncStorageMockRawPtr(asyncStorageMockPassedToImplementation.get()),
70 pFd(10),
71 dataMap({{ "key1", { 0x0a, 0x0b, 0x0c } }, { "key2", { 0x0d, 0x0e, 0x0f, 0xff } }}),
72 keys({ "key1", "key2" }),
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +030073 ns("someKnownNamespace"),
Timo Tietavainend565df62021-08-11 07:33:30 +030074 TEST_READY_WAIT_TIMEOUT(std::chrono::minutes(1)),
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +030075 TEST_OPERATION_WAIT_TIMEOUT(std::chrono::seconds(1)),
Timo Tietavainend565df62021-08-11 07:33:30 +030076 TEST_READY_POLL_WAIT_TIMEOUT(std::chrono::duration_cast<std::chrono::milliseconds>(TEST_READY_WAIT_TIMEOUT).count() / 10),
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +030077 TEST_OPERATION_POLL_WAIT_TIMEOUT(std::chrono::duration_cast<std::chrono::milliseconds>(TEST_OPERATION_WAIT_TIMEOUT).count() / 10)
Rolf Badorekef2bf512019-08-20 11:17:15 +030078 {
79 expectConstructorCalls();
80 syncStorage.reset(new SyncStorageImpl(std::move(asyncStorageMockPassedToImplementation), systemMock));
81 }
82
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +030083 ~SyncStorageImplTest()
84 {
85 syncStorage->setOperationTimeout(std::chrono::steady_clock::duration::zero());
86 }
87
Rolf Badorekef2bf512019-08-20 11:17:15 +030088 void expectConstructorCalls()
89 {
90 InSequence dummy;
91 EXPECT_CALL(*asyncStorageMockRawPtr, fd())
92 .Times(1)
93 .WillOnce(Return(pFd));
94 }
95
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +030096 void expectSdlReadinessCheck(int timeout)
Rolf Badorekef2bf512019-08-20 11:17:15 +030097 {
98 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +030099 expectPollForPendingEvents_ReturnNoEvents();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300100 expectWaitReadyAsync();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300101 expectPollWait(timeout);
102 expectHandleEvents_callWaitReadyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300103 }
104
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300105 void expectPollForPendingEvents_ReturnNoEvents()
Rolf Badorekef2bf512019-08-20 11:17:15 +0300106 {
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300107 EXPECT_CALL(systemMock, poll( _, 1, 0))
108 .Times(1)
109 .WillOnce(Invoke([](struct pollfd *, nfds_t, int)
110 {
111 return 0;
112 }));
113 }
114
115 void expectPollWait(int timeout)
116 {
117 EXPECT_CALL(systemMock, poll( _, 1, timeout))
Rolf Badorekef2bf512019-08-20 11:17:15 +0300118 .Times(1)
119 .WillOnce(Invoke([](struct pollfd *fds, nfds_t, int)
120 {
121 fds->revents = POLLIN;
122 return 1;
123 }));
124 }
125
126 void expectPollError()
127 {
128 EXPECT_CALL(systemMock, poll( _, 1, -1))
129 .Times(1)
130 .WillOnce(Invoke([](struct pollfd *fds, nfds_t, int)
131 {
132 fds->revents = POLLIN;
133 return -1;
134 }));
135 }
136
137 void expectPollExceptionalCondition()
138 {
139 EXPECT_CALL(systemMock, poll( _, 1, -1))
140 .Times(1)
141 .WillOnce(Invoke([](struct pollfd *fds, nfds_t, int)
142 {
143 fds->revents = POLLPRI;
144 return 1;
145 }));
146 }
147
148 void expectHandleEvents()
149 {
150 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300151 .Times(1);
152 }
153
154 void expectHandleEvents_callWaitReadyAck()
155 {
156 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
Rolf Badorekef2bf512019-08-20 11:17:15 +0300157 .Times(1)
158 .WillOnce(Invoke([this]()
159 {
160 savedReadyAck(std::error_code());
161 }));
162 }
163
Timo Tietavainend565df62021-08-11 07:33:30 +0300164 void expectHandleEvents_callWaitReadyAckWithError()
165 {
166 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
167 .Times(1)
168 .WillOnce(Invoke([this]()
169 {
170 savedReadyAck(AsyncRedisCommandDispatcherErrorCode::NOT_CONNECTED);
171 }));
172 }
173
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300174 void expectHandleEvents_callModifyAck()
175 {
176 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
177 .Times(1)
178 .WillOnce(Invoke([this]()
179 {
180 savedModifyAck(std::error_code());
181 }));
182 }
183
Rolf Badorekef2bf512019-08-20 11:17:15 +0300184 void expectWaitReadyAsync()
185 {
186 EXPECT_CALL(*asyncStorageMockRawPtr, waitReadyAsync(ns,_))
187 .Times(1)
188 .WillOnce(SaveArg<1>(&savedReadyAck));
189 }
190
Rolf Badorekef2bf512019-08-20 11:17:15 +0300191 void expectModifyAckWithError()
192 {
193 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
194 .Times(1)
195 .WillOnce(Invoke([this]()
196 {
197 savedModifyAck(AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY);
198 }));
199 }
200
201 void expectModifyIfAck(const std::error_code& error, bool status)
202 {
203 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
204 .Times(1)
205 .WillOnce(Invoke([this, error, status]()
206 {
207 savedModifyIfAck(error, status);
208 }));
209 }
210
211 void expectGetAckWithError()
212 {
213 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
214 .Times(1)
215 .WillOnce(Invoke([this]()
216 {
217 savedGetAck(AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY, dataMap);
218 }));
219 }
220
221 void expectGetAck()
222 {
223 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
224 .Times(1)
225 .WillOnce(Invoke([this]()
226 {
227 savedGetAck(std::error_code(), dataMap);
228 }));
229 }
230
231 void expectFindKeysAck()
232 {
233 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
234 .Times(1)
235 .WillOnce(Invoke([this]()
236 {
237 savedFindKeysAck(std::error_code(), keys);
238 }));
239 }
240
241 void expectFindKeysAckWithError()
242 {
243 EXPECT_CALL(*asyncStorageMockRawPtr, handleEvents())
244 .Times(1)
245 .WillOnce(Invoke([this]()
246 {
247 savedFindKeysAck(AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY, keys);
248 }));
249 }
250
251 void expectSetAsync(const SyncStorage::DataMap& dataMap)
252 {
253 EXPECT_CALL(*asyncStorageMockRawPtr, setAsync(ns, dataMap, _))
254 .Times(1)
255 .WillOnce(SaveArg<2>(&savedModifyAck));
256 }
257
258 void expectSetIfAsync(const SyncStorage::Key& key, const SyncStorage::Data& oldData, const SyncStorage::Data& newData)
259 {
260 EXPECT_CALL(*asyncStorageMockRawPtr, setIfAsync(ns, key, oldData, newData, _))
261 .Times(1)
262 .WillOnce(SaveArg<4>(&savedModifyIfAck));
263 }
264
265 void expectGetAsync(const SyncStorage::Keys& keys)
266 {
267 EXPECT_CALL(*asyncStorageMockRawPtr, getAsync(ns, keys, _))
268 .Times(1)
269 .WillOnce(SaveArg<2>(&savedGetAck));
270 }
271
272 void expectFindKeysAsync()
273 {
274 EXPECT_CALL(*asyncStorageMockRawPtr, findKeysAsync(ns, _, _))
275 .Times(1)
276 .WillOnce(SaveArg<2>(&savedFindKeysAck));
277 }
278
Petri Ovaska63869e12021-09-17 11:54:21 +0300279 void expectListKeys()
280 {
281 EXPECT_CALL(*asyncStorageMockRawPtr, listKeys(ns, _, _))
282 .Times(1)
283 .WillOnce(SaveArg<2>(&savedFindKeysAck));
284 }
285
Rolf Badorekef2bf512019-08-20 11:17:15 +0300286 void expectRemoveAsync(const SyncStorage::Keys& keys)
287 {
288 EXPECT_CALL(*asyncStorageMockRawPtr, removeAsync(ns, keys, _))
289 .Times(1)
290 .WillOnce(SaveArg<2>(&savedModifyAck));
291 }
292
293 void expectRemoveIfAsync(const SyncStorage::Key& key, const SyncStorage::Data& data)
294 {
295 EXPECT_CALL(*asyncStorageMockRawPtr, removeIfAsync(ns, key, data, _))
296 .Times(1)
297 .WillOnce(SaveArg<3>(&savedModifyIfAck));
298 }
299
300 void expectRemoveAllAsync()
301 {
302 EXPECT_CALL(*asyncStorageMockRawPtr, removeAllAsync(ns, _))
303 .Times(1)
304 .WillOnce(SaveArg<1>(&savedModifyAck));
305 }
306
307 void expectSetIfNotExistsAsync(const SyncStorage::Key& key, const SyncStorage::Data& data)
308 {
309 EXPECT_CALL(*asyncStorageMockRawPtr, setIfNotExistsAsync(ns, key, data, _))
310 .Times(1)
311 .WillOnce(SaveArg<3>(&savedModifyIfAck));
312 }
313 };
314}
315
316TEST_F(SyncStorageImplTest, IsNotCopyable)
317{
318 InSequence dummy;
319 EXPECT_FALSE(std::is_copy_constructible<SyncStorageImpl>::value);
320 EXPECT_FALSE(std::is_copy_assignable<SyncStorageImpl>::value);
321}
322
323TEST_F(SyncStorageImplTest, ImplementssyncStorage)
324{
325 InSequence dummy;
326 EXPECT_TRUE((std::is_base_of<SyncStorage, SyncStorageImpl>::value));
327}
328
329TEST_F(SyncStorageImplTest, EventsAreNotHandledWhenPollReturnsError)
330{
331 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300332 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300333 expectSetAsync(dataMap);
334 expectPollError();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300335 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
336 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300337 syncStorage->set(ns, dataMap);
338}
339
340TEST_F(SyncStorageImplTest, EventsAreNotHandledWhenThereIsAnExceptionalConditionOnTheFd)
341{
342 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300343 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300344 expectSetAsync(dataMap);
345 expectPollExceptionalCondition();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300346 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
347 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300348 syncStorage->set(ns, dataMap);
349}
350
Timo Tietavainend565df62021-08-11 07:33:30 +0300351TEST_F(SyncStorageImplTest, WaitReadySuccessfully)
352{
353 InSequence dummy;
354 expectWaitReadyAsync();
355 expectPollWait(TEST_READY_POLL_WAIT_TIMEOUT);
356 expectHandleEvents_callWaitReadyAck();
357 syncStorage->waitReady(ns, TEST_READY_WAIT_TIMEOUT);
358}
359
360TEST_F(SyncStorageImplTest, WaitReadyCanThrowRejectedBySdl)
361{
362 InSequence dummy;
363 expectWaitReadyAsync();
364 EXPECT_THROW(syncStorage->waitReady(ns, std::chrono::nanoseconds(1)), RejectedBySdl);
365}
366
367TEST_F(SyncStorageImplTest, WaitReadyCanThrowNotConnected)
368{
369 InSequence dummy;
370 expectWaitReadyAsync();
371 expectPollWait(TEST_READY_POLL_WAIT_TIMEOUT);
372 expectHandleEvents_callWaitReadyAckWithError();
373 EXPECT_THROW(syncStorage->waitReady(ns, TEST_READY_WAIT_TIMEOUT), NotConnected);
374}
375
Rolf Badorekef2bf512019-08-20 11:17:15 +0300376TEST_F(SyncStorageImplTest, SetSuccessfully)
377{
378 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300379 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300380 expectSetAsync(dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300381 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
382 expectHandleEvents_callModifyAck();
383 syncStorage->set(ns, dataMap);
384}
385
386TEST_F(SyncStorageImplTest, SetWithReadinessTimeoutSuccessfully)
387{
388 InSequence dummy;
389 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
390 expectSetAsync(dataMap);
391 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
392 expectHandleEvents_callModifyAck();
393 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300394 syncStorage->set(ns, dataMap);
395}
396
397TEST_F(SyncStorageImplTest, SetCanThrowBackendError)
398{
399 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300400 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300401 expectSetAsync(dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300402 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300403 expectModifyAckWithError();
404 EXPECT_THROW(syncStorage->set(ns, dataMap), BackendError);
405}
406
407TEST_F(SyncStorageImplTest, SetIfSuccessfully)
408{
409 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300410 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300411 expectSetAsync(dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300412 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
413 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300414 syncStorage->set(ns, dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300415 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300416 expectSetIfAsync("key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300417 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
418 expectHandleEvents_callModifyAck();
419 syncStorage->setIf(ns, "key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
420}
421
422TEST_F(SyncStorageImplTest, SetIfWithReadinessTimeoutSuccessfully)
423{
424 InSequence dummy;
425 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
426 expectSetAsync(dataMap);
427 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
428 expectHandleEvents_callModifyAck();
429 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
430 syncStorage->set(ns, dataMap);
431 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
432 expectSetIfAsync("key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
433 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
434 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300435 syncStorage->setIf(ns, "key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
436}
437
438TEST_F(SyncStorageImplTest, SetIfCanThrowBackendError)
439{
440 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300441 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300442 expectSetAsync(dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300443 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
444 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300445 syncStorage->set(ns, dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300446 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300447 expectSetIfAsync("key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300448 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300449 expectModifyIfAck(AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY, false);
450 EXPECT_THROW(syncStorage->setIf(ns, "key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f }), BackendError);
451}
452
453TEST_F(SyncStorageImplTest, SetIfNotExistsSuccessfully)
454{
455 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300456 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300457 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300458 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300459 expectModifyIfAck(std::error_code(), true);
Rolf Badorekb8cd8b62019-09-20 14:20:05 +0300460 EXPECT_TRUE(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }));
Rolf Badorekef2bf512019-08-20 11:17:15 +0300461}
462
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300463TEST_F(SyncStorageImplTest, SetIfNotExistsIfWithReadinessTimeoutSuccessfully)
464{
465 InSequence dummy;
466 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
467 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
468 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
469 expectModifyIfAck(std::error_code(), true);
470 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
471 EXPECT_TRUE(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }));
472}
473
Rolf Badorekef2bf512019-08-20 11:17:15 +0300474TEST_F(SyncStorageImplTest, SetIfNotExistsReturnsFalseIfKeyAlreadyExists)
475{
476 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300477 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300478 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300479 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300480 expectModifyIfAck(std::error_code(), false);
Rolf Badorekb8cd8b62019-09-20 14:20:05 +0300481 EXPECT_FALSE(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }));
Rolf Badorekef2bf512019-08-20 11:17:15 +0300482}
483
484TEST_F(SyncStorageImplTest, SetIfNotExistsCanThrowBackendError)
485{
486 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300487 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300488 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300489 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300490 expectModifyIfAck(AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY, false);
491 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
492}
493
494TEST_F(SyncStorageImplTest, GetSuccessfully)
495{
496 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300497 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300498 expectGetAsync(keys);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300499 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300500 expectGetAck();
501 auto map(syncStorage->get(ns, keys));
502 EXPECT_EQ(map, dataMap);
503}
504
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300505TEST_F(SyncStorageImplTest, GetWithReadinessTimeoutSuccessfully)
506{
507 InSequence dummy;
508 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
509 expectGetAsync(keys);
510 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
511 expectGetAck();
512 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
513 auto map(syncStorage->get(ns, keys));
514 EXPECT_EQ(map, dataMap);
515}
516
Rolf Badorekef2bf512019-08-20 11:17:15 +0300517TEST_F(SyncStorageImplTest, GetCanThrowBackendError)
518{
519 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300520 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300521 expectGetAsync(keys);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300522 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300523 expectGetAckWithError();
524 EXPECT_THROW(syncStorage->get(ns, keys), BackendError);
525}
526
527TEST_F(SyncStorageImplTest, RemoveSuccessfully)
528{
529 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300530 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300531 expectRemoveAsync(keys);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300532 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
533 expectHandleEvents_callModifyAck();
534 syncStorage->remove(ns, keys);
535}
536
537TEST_F(SyncStorageImplTest, RemoveWithReadinessTimeoutSuccessfully)
538{
539 InSequence dummy;
540 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
541 expectRemoveAsync(keys);
542 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
543 expectHandleEvents_callModifyAck();
544 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300545 syncStorage->remove(ns, keys);
546}
547
548TEST_F(SyncStorageImplTest, RemoveCanThrowBackendError)
549{
550 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300551 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300552 expectRemoveAsync(keys);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300553 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300554 expectModifyAckWithError();
555 EXPECT_THROW(syncStorage->remove(ns, keys), BackendError);
556}
557
558TEST_F(SyncStorageImplTest, RemoveIfSuccessfully)
559{
560 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300561 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300562 expectRemoveIfAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300563 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300564 expectModifyIfAck(std::error_code(), true);
Rolf Badorekb8cd8b62019-09-20 14:20:05 +0300565 EXPECT_TRUE(syncStorage->removeIf(ns, "key1", { 0x0a, 0x0b, 0x0c }));
Rolf Badorekef2bf512019-08-20 11:17:15 +0300566}
567
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300568TEST_F(SyncStorageImplTest, RemoveIfWithReadinessTimeoutSuccessfully)
569{
570 InSequence dummy;
571 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
572 expectRemoveIfAsync("key1", { 0x0a, 0x0b, 0x0c });
573 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
574 expectModifyIfAck(std::error_code(), true);
575 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
576 EXPECT_TRUE(syncStorage->removeIf(ns, "key1", { 0x0a, 0x0b, 0x0c }));
577}
578
Rolf Badorekef2bf512019-08-20 11:17:15 +0300579TEST_F(SyncStorageImplTest, RemoveIfReturnsFalseIfKeyDoesnotMatch)
580{
581 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300582 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300583 expectRemoveIfAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300584 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300585 expectModifyIfAck(std::error_code(), false);
Rolf Badorekb8cd8b62019-09-20 14:20:05 +0300586 EXPECT_FALSE(syncStorage->removeIf(ns, "key1", { 0x0a, 0x0b, 0x0c }));
Rolf Badorekef2bf512019-08-20 11:17:15 +0300587}
588
589TEST_F(SyncStorageImplTest, RemoveIfCanThrowBackendError)
590{
591 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300592 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300593 expectRemoveIfAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300594 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300595 expectModifyIfAck(AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY, false);
596 EXPECT_THROW(syncStorage->removeIf(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
597}
598
599TEST_F(SyncStorageImplTest, FindKeysSuccessfully)
600{
601 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300602 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300603 expectFindKeysAsync();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300604 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300605 expectFindKeysAck();
606 auto ids(syncStorage->findKeys(ns, "*"));
607 EXPECT_EQ(ids, keys);
608}
609
Petri Ovaska63869e12021-09-17 11:54:21 +0300610TEST_F(SyncStorageImplTest, ListKeysSuccessfully)
611{
612 InSequence dummy;
613 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
614 expectListKeys();
615 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
616 expectFindKeysAck();
617 auto ids(syncStorage->listKeys(ns, "*"));
618 EXPECT_EQ(ids, keys);
619}
620
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300621TEST_F(SyncStorageImplTest, FindKeysWithReadinessTimeoutSuccessfully)
622{
623 InSequence dummy;
624 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
625 expectFindKeysAsync();
626 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
627 expectFindKeysAck();
628 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
629 auto ids(syncStorage->findKeys(ns, "*"));
630 EXPECT_EQ(ids, keys);
631}
632
Rolf Badorekef2bf512019-08-20 11:17:15 +0300633TEST_F(SyncStorageImplTest, FindKeysAckCanThrowBackendError)
634{
635 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300636 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300637 expectFindKeysAsync();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300638 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300639 expectFindKeysAckWithError();
640 EXPECT_THROW(syncStorage->findKeys(ns, "*"), BackendError);
641}
642
643TEST_F(SyncStorageImplTest, RemoveAllSuccessfully)
644{
645 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300646 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300647 expectRemoveAllAsync();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300648 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
649 expectHandleEvents_callModifyAck();
650 syncStorage->removeAll(ns);
651}
652
653TEST_F(SyncStorageImplTest, RemoveAllWithReadinessTimeoutSuccessfully)
654{
655 InSequence dummy;
656 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
657 expectRemoveAllAsync();
658 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
659 expectHandleEvents_callModifyAck();
660 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300661 syncStorage->removeAll(ns);
662}
663
664TEST_F(SyncStorageImplTest, RemoveAllCanThrowBackendError)
665{
666 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300667 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300668 expectRemoveAllAsync();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300669 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300670 expectModifyAckWithError();
671 EXPECT_THROW(syncStorage->removeAll(ns), BackendError);
672}
673
674TEST_F(SyncStorageImplTest, AllAsyncRedisStorageErrorCodesThrowCorrectException)
675{
676 InSequence dummy;
677 std::error_code ec;
678
679 for (AsyncRedisStorage::ErrorCode arsec = AsyncRedisStorage::ErrorCode::SUCCESS; arsec < AsyncRedisStorage::ErrorCode::END_MARKER; ++arsec)
680 {
681 if (arsec != AsyncRedisStorage::ErrorCode::SUCCESS)
682 {
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300683 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300684 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300685 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300686 }
687
688 switch (arsec)
689 {
690 case AsyncRedisStorage::ErrorCode::SUCCESS:
691 break;
692 case AsyncRedisStorage::ErrorCode::INVALID_NAMESPACE:
693 expectModifyIfAck(arsec, false);
694 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), InvalidNamespace);
695 break;
696 case AsyncRedisStorage::ErrorCode::REDIS_NOT_YET_DISCOVERED:
697 expectModifyIfAck(arsec, false);
698 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), NotConnected);
699 break;
700 default:
701 FAIL() << "No mapping for AsyncRedisStorage::ErrorCode value: " << arsec;
702 break;
703 }
704 }
705}
706
707TEST_F(SyncStorageImplTest, AllDispatcherErrorCodesThrowCorrectException)
708{
709 InSequence dummy;
710 std::error_code ec;
711
712 for (AsyncRedisCommandDispatcherErrorCode aec = AsyncRedisCommandDispatcherErrorCode::SUCCESS; aec < AsyncRedisCommandDispatcherErrorCode::END_MARKER; ++aec)
713 {
714 if (aec != AsyncRedisCommandDispatcherErrorCode::SUCCESS)
715 {
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300716 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300717 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300718 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300719 }
720
721 switch (aec)
722 {
723 case AsyncRedisCommandDispatcherErrorCode::SUCCESS:
724 break;
725 case AsyncRedisCommandDispatcherErrorCode::UNKNOWN_ERROR:
726 expectModifyIfAck(aec, false);
727 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
728 break;
729 case AsyncRedisCommandDispatcherErrorCode::CONNECTION_LOST:
730 expectModifyIfAck(aec, false);
731 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), OperationInterrupted);
732 break;
733 case AsyncRedisCommandDispatcherErrorCode::PROTOCOL_ERROR:
734 expectModifyIfAck(aec, false);
735 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), RejectedByBackend);
736 break;
737 case AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY:
738 expectModifyIfAck(aec, false);
739 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
740 break;
741 case AsyncRedisCommandDispatcherErrorCode::DATASET_LOADING:
742 expectModifyIfAck(aec, false);
743 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), NotConnected);
744 break;
745 case AsyncRedisCommandDispatcherErrorCode::NOT_CONNECTED:
746 expectModifyIfAck(aec, false);
747 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), NotConnected);
748 break;
749 case AsyncRedisCommandDispatcherErrorCode::IO_ERROR:
750 expectModifyIfAck(aec, false);
751 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
752 break;
Rolf Badorekb7f49712019-09-23 14:14:56 +0300753 case AsyncRedisCommandDispatcherErrorCode::WRITING_TO_SLAVE:
754 expectModifyIfAck(aec, false);
755 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
756 break;
Rolf Badorekef2bf512019-08-20 11:17:15 +0300757 default:
758 FAIL() << "No mapping for AsyncRedisCommandDispatcherErrorCode value: " << aec;
759 break;
760 }
761 }
762}
763
764TEST_F(SyncStorageImplTest, CanThrowStdExceptionIfDispatcherErrorCodeCannotBeMappedToSdlException)
765{
766 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300767 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300768 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300769 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300770 expectModifyIfAck(std::error_code(1, std::system_category()), false);
771 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), std::range_error);
772}