blob: 570b61af1899b8cfd5999fde2d0db5efe0b864e0 [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
279 void expectRemoveAsync(const SyncStorage::Keys& keys)
280 {
281 EXPECT_CALL(*asyncStorageMockRawPtr, removeAsync(ns, keys, _))
282 .Times(1)
283 .WillOnce(SaveArg<2>(&savedModifyAck));
284 }
285
286 void expectRemoveIfAsync(const SyncStorage::Key& key, const SyncStorage::Data& data)
287 {
288 EXPECT_CALL(*asyncStorageMockRawPtr, removeIfAsync(ns, key, data, _))
289 .Times(1)
290 .WillOnce(SaveArg<3>(&savedModifyIfAck));
291 }
292
293 void expectRemoveAllAsync()
294 {
295 EXPECT_CALL(*asyncStorageMockRawPtr, removeAllAsync(ns, _))
296 .Times(1)
297 .WillOnce(SaveArg<1>(&savedModifyAck));
298 }
299
300 void expectSetIfNotExistsAsync(const SyncStorage::Key& key, const SyncStorage::Data& data)
301 {
302 EXPECT_CALL(*asyncStorageMockRawPtr, setIfNotExistsAsync(ns, key, data, _))
303 .Times(1)
304 .WillOnce(SaveArg<3>(&savedModifyIfAck));
305 }
306 };
307}
308
309TEST_F(SyncStorageImplTest, IsNotCopyable)
310{
311 InSequence dummy;
312 EXPECT_FALSE(std::is_copy_constructible<SyncStorageImpl>::value);
313 EXPECT_FALSE(std::is_copy_assignable<SyncStorageImpl>::value);
314}
315
316TEST_F(SyncStorageImplTest, ImplementssyncStorage)
317{
318 InSequence dummy;
319 EXPECT_TRUE((std::is_base_of<SyncStorage, SyncStorageImpl>::value));
320}
321
322TEST_F(SyncStorageImplTest, EventsAreNotHandledWhenPollReturnsError)
323{
324 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300325 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300326 expectSetAsync(dataMap);
327 expectPollError();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300328 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
329 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300330 syncStorage->set(ns, dataMap);
331}
332
333TEST_F(SyncStorageImplTest, EventsAreNotHandledWhenThereIsAnExceptionalConditionOnTheFd)
334{
335 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300336 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300337 expectSetAsync(dataMap);
338 expectPollExceptionalCondition();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300339 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
340 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300341 syncStorage->set(ns, dataMap);
342}
343
Timo Tietavainend565df62021-08-11 07:33:30 +0300344TEST_F(SyncStorageImplTest, WaitReadySuccessfully)
345{
346 InSequence dummy;
347 expectWaitReadyAsync();
348 expectPollWait(TEST_READY_POLL_WAIT_TIMEOUT);
349 expectHandleEvents_callWaitReadyAck();
350 syncStorage->waitReady(ns, TEST_READY_WAIT_TIMEOUT);
351}
352
353TEST_F(SyncStorageImplTest, WaitReadyCanThrowRejectedBySdl)
354{
355 InSequence dummy;
356 expectWaitReadyAsync();
357 EXPECT_THROW(syncStorage->waitReady(ns, std::chrono::nanoseconds(1)), RejectedBySdl);
358}
359
360TEST_F(SyncStorageImplTest, WaitReadyCanThrowNotConnected)
361{
362 InSequence dummy;
363 expectWaitReadyAsync();
364 expectPollWait(TEST_READY_POLL_WAIT_TIMEOUT);
365 expectHandleEvents_callWaitReadyAckWithError();
366 EXPECT_THROW(syncStorage->waitReady(ns, TEST_READY_WAIT_TIMEOUT), NotConnected);
367}
368
Rolf Badorekef2bf512019-08-20 11:17:15 +0300369TEST_F(SyncStorageImplTest, SetSuccessfully)
370{
371 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300372 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300373 expectSetAsync(dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300374 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
375 expectHandleEvents_callModifyAck();
376 syncStorage->set(ns, dataMap);
377}
378
379TEST_F(SyncStorageImplTest, SetWithReadinessTimeoutSuccessfully)
380{
381 InSequence dummy;
382 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
383 expectSetAsync(dataMap);
384 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
385 expectHandleEvents_callModifyAck();
386 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300387 syncStorage->set(ns, dataMap);
388}
389
390TEST_F(SyncStorageImplTest, SetCanThrowBackendError)
391{
392 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300393 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300394 expectSetAsync(dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300395 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300396 expectModifyAckWithError();
397 EXPECT_THROW(syncStorage->set(ns, dataMap), BackendError);
398}
399
400TEST_F(SyncStorageImplTest, SetIfSuccessfully)
401{
402 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300403 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300404 expectSetAsync(dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300405 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
406 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300407 syncStorage->set(ns, dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300408 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300409 expectSetIfAsync("key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300410 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
411 expectHandleEvents_callModifyAck();
412 syncStorage->setIf(ns, "key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
413}
414
415TEST_F(SyncStorageImplTest, SetIfWithReadinessTimeoutSuccessfully)
416{
417 InSequence dummy;
418 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
419 expectSetAsync(dataMap);
420 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
421 expectHandleEvents_callModifyAck();
422 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
423 syncStorage->set(ns, dataMap);
424 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
425 expectSetIfAsync("key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
426 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
427 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300428 syncStorage->setIf(ns, "key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
429}
430
431TEST_F(SyncStorageImplTest, SetIfCanThrowBackendError)
432{
433 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300434 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300435 expectSetAsync(dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300436 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
437 expectHandleEvents_callModifyAck();
Rolf Badorekef2bf512019-08-20 11:17:15 +0300438 syncStorage->set(ns, dataMap);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300439 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300440 expectSetIfAsync("key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300441 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300442 expectModifyIfAck(AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY, false);
443 EXPECT_THROW(syncStorage->setIf(ns, "key1", { 0x0a, 0x0b, 0x0c }, { 0x0d, 0x0e, 0x0f }), BackendError);
444}
445
446TEST_F(SyncStorageImplTest, SetIfNotExistsSuccessfully)
447{
448 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300449 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300450 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300451 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300452 expectModifyIfAck(std::error_code(), true);
Rolf Badorekb8cd8b62019-09-20 14:20:05 +0300453 EXPECT_TRUE(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }));
Rolf Badorekef2bf512019-08-20 11:17:15 +0300454}
455
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300456TEST_F(SyncStorageImplTest, SetIfNotExistsIfWithReadinessTimeoutSuccessfully)
457{
458 InSequence dummy;
459 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
460 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
461 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
462 expectModifyIfAck(std::error_code(), true);
463 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
464 EXPECT_TRUE(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }));
465}
466
Rolf Badorekef2bf512019-08-20 11:17:15 +0300467TEST_F(SyncStorageImplTest, SetIfNotExistsReturnsFalseIfKeyAlreadyExists)
468{
469 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300470 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300471 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300472 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300473 expectModifyIfAck(std::error_code(), false);
Rolf Badorekb8cd8b62019-09-20 14:20:05 +0300474 EXPECT_FALSE(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }));
Rolf Badorekef2bf512019-08-20 11:17:15 +0300475}
476
477TEST_F(SyncStorageImplTest, SetIfNotExistsCanThrowBackendError)
478{
479 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300480 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300481 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300482 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300483 expectModifyIfAck(AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY, false);
484 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
485}
486
487TEST_F(SyncStorageImplTest, GetSuccessfully)
488{
489 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300490 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300491 expectGetAsync(keys);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300492 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300493 expectGetAck();
494 auto map(syncStorage->get(ns, keys));
495 EXPECT_EQ(map, dataMap);
496}
497
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300498TEST_F(SyncStorageImplTest, GetWithReadinessTimeoutSuccessfully)
499{
500 InSequence dummy;
501 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
502 expectGetAsync(keys);
503 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
504 expectGetAck();
505 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
506 auto map(syncStorage->get(ns, keys));
507 EXPECT_EQ(map, dataMap);
508}
509
Rolf Badorekef2bf512019-08-20 11:17:15 +0300510TEST_F(SyncStorageImplTest, GetCanThrowBackendError)
511{
512 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300513 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300514 expectGetAsync(keys);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300515 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300516 expectGetAckWithError();
517 EXPECT_THROW(syncStorage->get(ns, keys), BackendError);
518}
519
520TEST_F(SyncStorageImplTest, RemoveSuccessfully)
521{
522 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300523 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300524 expectRemoveAsync(keys);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300525 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
526 expectHandleEvents_callModifyAck();
527 syncStorage->remove(ns, keys);
528}
529
530TEST_F(SyncStorageImplTest, RemoveWithReadinessTimeoutSuccessfully)
531{
532 InSequence dummy;
533 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
534 expectRemoveAsync(keys);
535 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
536 expectHandleEvents_callModifyAck();
537 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300538 syncStorage->remove(ns, keys);
539}
540
541TEST_F(SyncStorageImplTest, RemoveCanThrowBackendError)
542{
543 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300544 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300545 expectRemoveAsync(keys);
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300546 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300547 expectModifyAckWithError();
548 EXPECT_THROW(syncStorage->remove(ns, keys), BackendError);
549}
550
551TEST_F(SyncStorageImplTest, RemoveIfSuccessfully)
552{
553 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300554 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300555 expectRemoveIfAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300556 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300557 expectModifyIfAck(std::error_code(), true);
Rolf Badorekb8cd8b62019-09-20 14:20:05 +0300558 EXPECT_TRUE(syncStorage->removeIf(ns, "key1", { 0x0a, 0x0b, 0x0c }));
Rolf Badorekef2bf512019-08-20 11:17:15 +0300559}
560
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300561TEST_F(SyncStorageImplTest, RemoveIfWithReadinessTimeoutSuccessfully)
562{
563 InSequence dummy;
564 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
565 expectRemoveIfAsync("key1", { 0x0a, 0x0b, 0x0c });
566 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
567 expectModifyIfAck(std::error_code(), true);
568 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
569 EXPECT_TRUE(syncStorage->removeIf(ns, "key1", { 0x0a, 0x0b, 0x0c }));
570}
571
Rolf Badorekef2bf512019-08-20 11:17:15 +0300572TEST_F(SyncStorageImplTest, RemoveIfReturnsFalseIfKeyDoesnotMatch)
573{
574 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300575 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300576 expectRemoveIfAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300577 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300578 expectModifyIfAck(std::error_code(), false);
Rolf Badorekb8cd8b62019-09-20 14:20:05 +0300579 EXPECT_FALSE(syncStorage->removeIf(ns, "key1", { 0x0a, 0x0b, 0x0c }));
Rolf Badorekef2bf512019-08-20 11:17:15 +0300580}
581
582TEST_F(SyncStorageImplTest, RemoveIfCanThrowBackendError)
583{
584 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300585 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300586 expectRemoveIfAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300587 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300588 expectModifyIfAck(AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY, false);
589 EXPECT_THROW(syncStorage->removeIf(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
590}
591
592TEST_F(SyncStorageImplTest, FindKeysSuccessfully)
593{
594 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300595 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300596 expectFindKeysAsync();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300597 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300598 expectFindKeysAck();
599 auto ids(syncStorage->findKeys(ns, "*"));
600 EXPECT_EQ(ids, keys);
601}
602
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300603TEST_F(SyncStorageImplTest, FindKeysWithReadinessTimeoutSuccessfully)
604{
605 InSequence dummy;
606 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
607 expectFindKeysAsync();
608 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
609 expectFindKeysAck();
610 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
611 auto ids(syncStorage->findKeys(ns, "*"));
612 EXPECT_EQ(ids, keys);
613}
614
Rolf Badorekef2bf512019-08-20 11:17:15 +0300615TEST_F(SyncStorageImplTest, FindKeysAckCanThrowBackendError)
616{
617 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300618 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300619 expectFindKeysAsync();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300620 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300621 expectFindKeysAckWithError();
622 EXPECT_THROW(syncStorage->findKeys(ns, "*"), BackendError);
623}
624
625TEST_F(SyncStorageImplTest, RemoveAllSuccessfully)
626{
627 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300628 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300629 expectRemoveAllAsync();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300630 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
631 expectHandleEvents_callModifyAck();
632 syncStorage->removeAll(ns);
633}
634
635TEST_F(SyncStorageImplTest, RemoveAllWithReadinessTimeoutSuccessfully)
636{
637 InSequence dummy;
638 expectSdlReadinessCheck(TEST_OPERATION_POLL_WAIT_TIMEOUT);
639 expectRemoveAllAsync();
640 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
641 expectHandleEvents_callModifyAck();
642 syncStorage->setOperationTimeout(TEST_OPERATION_WAIT_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300643 syncStorage->removeAll(ns);
644}
645
646TEST_F(SyncStorageImplTest, RemoveAllCanThrowBackendError)
647{
648 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300649 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300650 expectRemoveAllAsync();
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300651 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300652 expectModifyAckWithError();
653 EXPECT_THROW(syncStorage->removeAll(ns), BackendError);
654}
655
656TEST_F(SyncStorageImplTest, AllAsyncRedisStorageErrorCodesThrowCorrectException)
657{
658 InSequence dummy;
659 std::error_code ec;
660
661 for (AsyncRedisStorage::ErrorCode arsec = AsyncRedisStorage::ErrorCode::SUCCESS; arsec < AsyncRedisStorage::ErrorCode::END_MARKER; ++arsec)
662 {
663 if (arsec != AsyncRedisStorage::ErrorCode::SUCCESS)
664 {
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300665 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300666 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300667 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300668 }
669
670 switch (arsec)
671 {
672 case AsyncRedisStorage::ErrorCode::SUCCESS:
673 break;
674 case AsyncRedisStorage::ErrorCode::INVALID_NAMESPACE:
675 expectModifyIfAck(arsec, false);
676 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), InvalidNamespace);
677 break;
678 case AsyncRedisStorage::ErrorCode::REDIS_NOT_YET_DISCOVERED:
679 expectModifyIfAck(arsec, false);
680 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), NotConnected);
681 break;
682 default:
683 FAIL() << "No mapping for AsyncRedisStorage::ErrorCode value: " << arsec;
684 break;
685 }
686 }
687}
688
689TEST_F(SyncStorageImplTest, AllDispatcherErrorCodesThrowCorrectException)
690{
691 InSequence dummy;
692 std::error_code ec;
693
694 for (AsyncRedisCommandDispatcherErrorCode aec = AsyncRedisCommandDispatcherErrorCode::SUCCESS; aec < AsyncRedisCommandDispatcherErrorCode::END_MARKER; ++aec)
695 {
696 if (aec != AsyncRedisCommandDispatcherErrorCode::SUCCESS)
697 {
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300698 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300699 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300700 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300701 }
702
703 switch (aec)
704 {
705 case AsyncRedisCommandDispatcherErrorCode::SUCCESS:
706 break;
707 case AsyncRedisCommandDispatcherErrorCode::UNKNOWN_ERROR:
708 expectModifyIfAck(aec, false);
709 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
710 break;
711 case AsyncRedisCommandDispatcherErrorCode::CONNECTION_LOST:
712 expectModifyIfAck(aec, false);
713 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), OperationInterrupted);
714 break;
715 case AsyncRedisCommandDispatcherErrorCode::PROTOCOL_ERROR:
716 expectModifyIfAck(aec, false);
717 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), RejectedByBackend);
718 break;
719 case AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY:
720 expectModifyIfAck(aec, false);
721 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
722 break;
723 case AsyncRedisCommandDispatcherErrorCode::DATASET_LOADING:
724 expectModifyIfAck(aec, false);
725 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), NotConnected);
726 break;
727 case AsyncRedisCommandDispatcherErrorCode::NOT_CONNECTED:
728 expectModifyIfAck(aec, false);
729 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), NotConnected);
730 break;
731 case AsyncRedisCommandDispatcherErrorCode::IO_ERROR:
732 expectModifyIfAck(aec, false);
733 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
734 break;
Rolf Badorekb7f49712019-09-23 14:14:56 +0300735 case AsyncRedisCommandDispatcherErrorCode::WRITING_TO_SLAVE:
736 expectModifyIfAck(aec, false);
737 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), BackendError);
738 break;
Rolf Badorekef2bf512019-08-20 11:17:15 +0300739 default:
740 FAIL() << "No mapping for AsyncRedisCommandDispatcherErrorCode value: " << aec;
741 break;
742 }
743 }
744}
745
746TEST_F(SyncStorageImplTest, CanThrowStdExceptionIfDispatcherErrorCodeCannotBeMappedToSdlException)
747{
748 InSequence dummy;
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300749 expectSdlReadinessCheck(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300750 expectSetIfNotExistsAsync("key1", { 0x0a, 0x0b, 0x0c });
Timo Tietavainenfaf9fc72021-08-05 11:46:07 +0300751 expectPollWait(SyncStorageImpl::NO_TIMEOUT);
Rolf Badorekef2bf512019-08-20 11:17:15 +0300752 expectModifyIfAck(std::error_code(1, std::system_category()), false);
753 EXPECT_THROW(syncStorage->setIfNotExists(ns, "key1", { 0x0a, 0x0b, 0x0c }), std::range_error);
754}