blob: 33c5354f6426d6ac2c2a23a01b5c2b5dddbd0b83 [file] [log] [blame]
manojkiraneda4eaf2ee2019-12-13 17:10:41 +05301#include "ibm/locks.hpp"
manojkiraneda4eaf2ee2019-12-13 17:10:41 +05302
Nan Zhoud5c80ad2022-07-11 01:16:31 +00003#include <cstdint>
4#include <memory>
Gunnar Mills1214b7e2020-06-04 10:11:30 -05005#include <string>
Nan Zhoud5c80ad2022-07-11 01:16:31 +00006#include <tuple>
7#include <utility>
8#include <variant>
9#include <vector>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050010
Nan Zhoud5c80ad2022-07-11 01:16:31 +000011#include <gmock/gmock.h> // IWYU pragma: keep
12#include <gtest/gtest.h> // IWYU pragma: keep
13
14// IWYU pragma: no_include <gtest/gtest-message.h>
15// IWYU pragma: no_include <gtest/gtest-test-part.h>
16// IWYU pragma: no_include "gtest/gtest_pred_impl.h"
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053017
Nan Zhou38ead5e2022-07-03 23:07:27 +000018namespace crow::ibm_mc_lock
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053019{
Nan Zhou38ead5e2022-07-03 23:07:27 +000020namespace
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053021{
Nan Zhou38ead5e2022-07-03 23:07:27 +000022
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053023using SType = std::string;
24using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
25using LockRequests = std::vector<LockRequest>;
26using Rc =
27 std::pair<bool, std::variant<uint32_t, std::pair<uint32_t, LockRequest>>>;
28using RcRelaseLock = std::pair<bool, std::pair<uint32_t, LockRequest>>;
29using RcGetLockList =
30 std::variant<std::string, std::vector<std::pair<uint32_t, LockRequests>>>;
31using ListOfTransactionIds = std::vector<uint32_t>;
32using RcAcquireLock = std::pair<bool, std::variant<Rc, std::pair<bool, int>>>;
33using RcReleaseLockApi = std::pair<bool, std::variant<bool, RcRelaseLock>>;
34using SessionFlags = std::pair<SType, SType>;
35using ListOfSessionIds = std::vector<std::string>;
Nan Zhoub5a10a22022-07-04 01:18:14 +000036using ::testing::IsEmpty;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053037
38class LockTest : public ::testing::Test
39{
40 protected:
41 LockRequests request;
42 LockRequests request1, request2;
43 LockRequest record;
44
45 public:
Ed Tanousb31cef62022-06-30 17:51:46 -070046 LockTest() :
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053047 // lockrequest with multiple lockrequests
Ed Tanousb31cef62022-06-30 17:51:46 -070048 request{{"xxxxx",
49 "hmc-id",
50 "Read",
51 234,
52 {{"DontLock", 2}, {"DontLock", 4}}},
53 {"xxxxx",
54 "hmc-id",
55 "Read",
56 234,
57 {{"DontLock", 2}, {"DontLock", 4}}}},
58 request1{{"xxxxx",
59 "hmc-id",
60 "Read",
61 234,
62 {{"DontLock", 2}, {"DontLock", 4}}}},
63 request2{{"xxxxx",
64 "hmc-id",
65 "Write",
66 234,
67 {{"LockAll", 2}, {"DontLock", 4}}}},
68 record{
69 "xxxxx", "hmc-id", "Read", 234, {{"DontLock", 2}, {"DontLock", 4}}}
70 {}
Ed Tanous3174e4d2020-10-07 11:41:22 -070071
72 ~LockTest() override = default;
Ed Tanousecd6a3a2022-01-07 09:18:40 -080073
74 LockTest(const LockTest&) = delete;
75 LockTest(LockTest&&) = delete;
76 LockTest& operator=(const LockTest&) = delete;
77 LockTest& operator=(const LockTest&&) = delete;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053078};
79
80class MockLock : public crow::ibm_mc_lock::Lock
81{
82 public:
Ed Tanousb5a76932020-09-29 16:16:58 -070083 bool isValidLockRequest(const LockRequest& record1) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053084 {
85 bool status = Lock::isValidLockRequest(record1);
86 return status;
87 }
Ed Tanousb5a76932020-09-29 16:16:58 -070088 bool isConflictRequest(const LockRequests& request) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053089 {
90 bool status = Lock::isConflictRequest(request);
91 return status;
92 }
Ed Tanousb5a76932020-09-29 16:16:58 -070093 Rc isConflictWithTable(const LockRequests& request) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053094 {
95 auto conflict = Lock::isConflictWithTable(request);
96 return conflict;
97 }
98 uint32_t generateTransactionId() override
99 {
100 uint32_t tid = Lock::generateTransactionId();
101 return tid;
102 }
103
104 bool validateRids(const ListOfTransactionIds& tids) override
105 {
106 bool status = Lock::validateRids(tids);
107 return status;
108 }
109 RcRelaseLock isItMyLock(const ListOfTransactionIds& tids,
110 const SessionFlags& ids) override
111 {
112 auto status = Lock::isItMyLock(tids, ids);
113 return status;
114 }
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530115 friend class LockTest;
116};
117
118TEST_F(LockTest, ValidationGoodTestCase)
119{
120 MockLock lockManager;
121 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000122 EXPECT_TRUE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530123}
124
125TEST_F(LockTest, ValidationBadTestWithLocktype)
126{
127 MockLock lockManager;
128 // Corrupt the lock type
129 std::get<2>(record) = "rwrite";
130 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000131 EXPECT_FALSE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530132}
133
134TEST_F(LockTest, ValidationBadTestWithlockFlags)
135{
136 MockLock lockManager;
137 // Corrupt the lockflag
138 std::get<4>(record)[0].first = "lock";
139 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000140 EXPECT_FALSE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530141}
142
143TEST_F(LockTest, ValidationBadTestWithSegmentlength)
144{
145 MockLock lockManager;
146 // Corrupt the Segment length
147 std::get<4>(record)[0].second = 7;
148 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000149 EXPECT_FALSE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530150}
151
152TEST_F(LockTest, MultiRequestWithoutConflict)
153{
154 MockLock lockManager;
155 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000156 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530157}
158
159TEST_F(LockTest, MultiRequestWithConflictduetoSameSegmentLength)
160{
161 MockLock lockManager;
162 // Corrupt the locktype
163 std::get<2>(request[0]) = "Write";
164 // Match the segment lengths to points them to lock similar kind of
165 // resource
166 std::get<4>(request[0])[0].first = "LockAll";
167 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000168 EXPECT_TRUE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530169}
170
171TEST_F(LockTest, MultiRequestWithoutConflictduetoDifferentSegmentData)
172{
173 MockLock lockManager;
174 // Corrupt the locktype
175 std::get<2>(request[0]) = "Write";
176 // Match the segment lengths to points them to lock similar kind of
177 // resource
178 std::get<4>(request[0])[0].first = "DontLock";
179 std::get<4>(request[0])[1].first = "LockAll";
180
181 // Change the resource id(2nd byte) of first record, so the locks are
182 // different so no conflict
183 std::get<3>(request[0]) = 216179379183550464; // HEX 03 00 06 00 00 00 00 00
184 std::get<3>(request[1]) = 288236973221478400; // HEX 04 00 06 00 00 00 00 00
185 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000186 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530187}
188
189TEST_F(LockTest, MultiRequestWithConflictduetoSameSegmentData)
190{
191 MockLock lockManager;
192 // Corrupt the locktype
193 std::get<2>(request[0]) = "Write";
194 // Match the segment lengths to points them to lock similar kind of
195 // resource
196 std::get<4>(request[0])[0].first = "DontLock";
197 std::get<4>(request[0])[1].first = "LockAll";
Nan Zhoub5a10a22022-07-04 01:18:14 +0000198 // Dont Change the resource id(1st & 2nd byte) at all, so that the
199 // conflict occurs from the second segment which is trying to lock all
200 // the resources.
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530201 std::get<3>(request[0]) = 216173882346831872; // 03 00 01 00 2B 00 00 00
202 std::get<3>(request[1]) = 216173882346831872; // 03 00 01 00 2B 00 00 00
203 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000204 EXPECT_TRUE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530205}
206
207TEST_F(LockTest, MultiRequestWithoutConflictduetoDifferentSegmentLength)
208{
209 MockLock lockManager;
210 // Corrupt the locktype
211 std::get<2>(request[0]) = "Write";
212 // Match the segment lengths to points them to lock similar kind of
213 // resource
214 std::get<4>(request[0])[0].first = "LockSame";
215 // Change the segment length , so that the requests are trying to lock
216 // two different kind of resources
217 std::get<4>(request[0])[0].second = 3;
218 const LockRequests& t = request;
219 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000220 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530221}
222
223TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktype)
224{
225 MockLock lockManager;
226 // Match the segment lengths to points them to lock similar kind of
227 // resource
228 std::get<4>(request[0])[0].first = "LockAll";
229 const LockRequests& t = request;
230 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000231 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530232}
233
234TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktypeAndLockall)
235{
236 MockLock lockManager;
237 // Match the segment lengths to points them to lock similar kind of
238 // resource
239 std::get<4>(request[0])[0].first = "LockAll";
240 std::get<4>(request[0])[1].first = "LockAll";
241 const LockRequests& t = request;
242 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000243 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530244}
245
246TEST_F(LockTest, RequestConflictedWithLockTableEntries)
247{
248 MockLock lockManager;
249 const LockRequests& t = request1;
250 auto rc1 = lockManager.isConflictWithTable(t);
251 // Corrupt the lock type
252 std::get<2>(request[0]) = "Write";
253 // Corrupt the lockflag
254 std::get<4>(request[0])[1].first = "LockAll";
255 const LockRequests& p = request;
256 auto rc2 = lockManager.isConflictWithTable(p);
257 // Return a Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000258 EXPECT_TRUE(rc2.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530259}
260
261TEST_F(LockTest, RequestNotConflictedWithLockTableEntries)
262{
263 MockLock lockManager;
264 const LockRequests& t = request1;
265 // Insert the request1 into the lock table
266 auto rc1 = lockManager.isConflictWithTable(t);
267 // Corrupt the lock type
268 std::get<2>(request[0]) = "Read";
269 // Corrupt the lockflag
270 std::get<4>(request[0])[1].first = "LockAll";
271 const LockRequests& p = request;
272 auto rc2 = lockManager.isConflictWithTable(p);
273 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000274 EXPECT_FALSE(rc2.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530275}
276
277TEST_F(LockTest, TestGenerateTransactionIDFunction)
278{
279 MockLock lockManager;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000280 uint32_t transactionId1 = lockManager.generateTransactionId();
281 uint32_t transactionId2 = lockManager.generateTransactionId();
282 EXPECT_EQ(transactionId2, ++transactionId1);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530283}
284
285TEST_F(LockTest, ValidateTransactionIDsGoodTestCase)
286{
287 MockLock lockManager;
288 const LockRequests& t = request1;
289 // Insert the request1 into the lock table
290 auto rc1 = lockManager.isConflictWithTable(t);
291 std::vector<uint32_t> tids = {1};
292 const std::vector<uint32_t>& p = tids;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000293 EXPECT_TRUE(lockManager.validateRids(p));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530294}
295
296TEST_F(LockTest, ValidateTransactionIDsBadTestCase)
297{
298 MockLock lockManager;
299 // Insert the request1 into the lock table
300 const LockRequests& t = request1;
301 auto rc1 = lockManager.isConflictWithTable(t);
Sunitha Harish3e919b52020-10-13 01:21:48 -0500302 std::vector<uint32_t> tids = {10};
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530303 const std::vector<uint32_t>& p = tids;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000304 EXPECT_FALSE(lockManager.validateRids(p));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530305}
306
307TEST_F(LockTest, ValidateisItMyLockGoodTestCase)
308{
309 MockLock lockManager;
310 // Insert the request1 into the lock table
311 const LockRequests& t = request1;
312 auto rc1 = lockManager.isConflictWithTable(t);
313 std::vector<uint32_t> tids = {1};
314 const std::vector<uint32_t>& p = tids;
315 std::string hmcid = "hmc-id";
316 std::string sessionid = "xxxxx";
317 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
318 auto rc = lockManager.isItMyLock(p, ids);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000319 EXPECT_TRUE(rc.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530320}
321
322TEST_F(LockTest, ValidateisItMyLockBadTestCase)
323{
324 MockLock lockManager;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530325 // Corrupt the client identifier
326 std::get<1>(request1[0]) = "randomid";
327 // Insert the request1 into the lock table
328 const LockRequests& t = request1;
329 auto rc1 = lockManager.isConflictWithTable(t);
330 std::vector<uint32_t> tids = {1};
331 const std::vector<uint32_t>& p = tids;
332 std::string hmcid = "hmc-id";
Sunitha Harish3e919b52020-10-13 01:21:48 -0500333 std::string sessionid = "random";
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530334 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
335 auto rc = lockManager.isItMyLock(p, ids);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000336 EXPECT_FALSE(rc.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530337}
338
339TEST_F(LockTest, ValidateSessionIDForGetlocklistBadTestCase)
340{
341 MockLock lockManager;
342 // Insert the request1 into the lock table
343 const LockRequests& t = request1;
344 auto rc1 = lockManager.isConflictWithTable(t);
345 std::vector<std::string> sessionid = {"random"};
346 auto status = lockManager.getLockList(sessionid);
347 auto result =
348 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000349 EXPECT_THAT(result, IsEmpty());
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530350}
351
352TEST_F(LockTest, ValidateSessionIDForGetlocklistGoodTestCase)
353{
354 MockLock lockManager;
355 // Insert the request1 into the lock table
356 const LockRequests& t = request1;
357 auto rc1 = lockManager.isConflictWithTable(t);
358 std::vector<std::string> sessionid = {"xxxxx"};
359 auto status = lockManager.getLockList(sessionid);
360 auto result =
361 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000362 EXPECT_EQ(result.size(), 1);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530363}
Sunitha Harish3e919b52020-10-13 01:21:48 -0500364
Nan Zhou38ead5e2022-07-03 23:07:27 +0000365} // namespace
366} // namespace crow::ibm_mc_lock