blob: 5c0df1fa7581aa937a308be1240b493da9e8165c [file] [log] [blame]
manojkiraneda4eaf2ee2019-12-13 17:10:41 +05301#include "ibm/locks.hpp"
manojkiraneda4eaf2ee2019-12-13 17:10:41 +05302
Gunnar Mills1214b7e2020-06-04 10:11:30 -05003#include <string>
4
Nan Zhoub5a10a22022-07-04 01:18:14 +00005#include <gmock/gmock.h>
6#include <gtest/gtest.h>
manojkiraneda4eaf2ee2019-12-13 17:10:41 +05307
Nan Zhou38ead5e2022-07-03 23:07:27 +00008namespace crow::ibm_mc_lock
manojkiraneda4eaf2ee2019-12-13 17:10:41 +05309{
Nan Zhou38ead5e2022-07-03 23:07:27 +000010namespace
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053011{
Nan Zhou38ead5e2022-07-03 23:07:27 +000012
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053013using SType = std::string;
14using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
15using LockRequests = std::vector<LockRequest>;
16using Rc =
17 std::pair<bool, std::variant<uint32_t, std::pair<uint32_t, LockRequest>>>;
18using RcRelaseLock = std::pair<bool, std::pair<uint32_t, LockRequest>>;
19using RcGetLockList =
20 std::variant<std::string, std::vector<std::pair<uint32_t, LockRequests>>>;
21using ListOfTransactionIds = std::vector<uint32_t>;
22using RcAcquireLock = std::pair<bool, std::variant<Rc, std::pair<bool, int>>>;
23using RcReleaseLockApi = std::pair<bool, std::variant<bool, RcRelaseLock>>;
24using SessionFlags = std::pair<SType, SType>;
25using ListOfSessionIds = std::vector<std::string>;
Nan Zhoub5a10a22022-07-04 01:18:14 +000026using ::testing::IsEmpty;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053027
28class LockTest : public ::testing::Test
29{
30 protected:
31 LockRequests request;
32 LockRequests request1, request2;
33 LockRequest record;
34
35 public:
36 LockTest()
37 {
38 record = {
39 "xxxxx", "hmc-id", "Read", 234, {{"DontLock", 2}, {"DontLock", 4}}};
40 // lockrequest with multiple lockrequests
41 request = {{"xxxxx",
42 "hmc-id",
43 "Read",
44 234,
45 {{"DontLock", 2}, {"DontLock", 4}}},
46 {"xxxxx",
47 "hmc-id",
48 "Read",
49 234,
50 {{"DontLock", 2}, {"DontLock", 4}}}};
51 request1 = {{"xxxxx",
52 "hmc-id",
53 "Read",
54 234,
55 {{"DontLock", 2}, {"DontLock", 4}}}};
56 request2 = {{"xxxxx",
57 "hmc-id",
58 "Write",
59 234,
60 {{"LockAll", 2}, {"DontLock", 4}}}};
61 }
Ed Tanous3174e4d2020-10-07 11:41:22 -070062
63 ~LockTest() override = default;
Ed Tanousecd6a3a2022-01-07 09:18:40 -080064
65 LockTest(const LockTest&) = delete;
66 LockTest(LockTest&&) = delete;
67 LockTest& operator=(const LockTest&) = delete;
68 LockTest& operator=(const LockTest&&) = delete;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053069};
70
71class MockLock : public crow::ibm_mc_lock::Lock
72{
73 public:
Ed Tanousb5a76932020-09-29 16:16:58 -070074 bool isValidLockRequest(const LockRequest& record1) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053075 {
76 bool status = Lock::isValidLockRequest(record1);
77 return status;
78 }
Ed Tanousb5a76932020-09-29 16:16:58 -070079 bool isConflictRequest(const LockRequests& request) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053080 {
81 bool status = Lock::isConflictRequest(request);
82 return status;
83 }
Ed Tanousb5a76932020-09-29 16:16:58 -070084 Rc isConflictWithTable(const LockRequests& request) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053085 {
86 auto conflict = Lock::isConflictWithTable(request);
87 return conflict;
88 }
89 uint32_t generateTransactionId() override
90 {
91 uint32_t tid = Lock::generateTransactionId();
92 return tid;
93 }
94
95 bool validateRids(const ListOfTransactionIds& tids) override
96 {
97 bool status = Lock::validateRids(tids);
98 return status;
99 }
100 RcRelaseLock isItMyLock(const ListOfTransactionIds& tids,
101 const SessionFlags& ids) override
102 {
103 auto status = Lock::isItMyLock(tids, ids);
104 return status;
105 }
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530106 friend class LockTest;
107};
108
109TEST_F(LockTest, ValidationGoodTestCase)
110{
111 MockLock lockManager;
112 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000113 EXPECT_TRUE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530114}
115
116TEST_F(LockTest, ValidationBadTestWithLocktype)
117{
118 MockLock lockManager;
119 // Corrupt the lock type
120 std::get<2>(record) = "rwrite";
121 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000122 EXPECT_FALSE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530123}
124
125TEST_F(LockTest, ValidationBadTestWithlockFlags)
126{
127 MockLock lockManager;
128 // Corrupt the lockflag
129 std::get<4>(record)[0].first = "lock";
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, ValidationBadTestWithSegmentlength)
135{
136 MockLock lockManager;
137 // Corrupt the Segment length
138 std::get<4>(record)[0].second = 7;
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, MultiRequestWithoutConflict)
144{
145 MockLock lockManager;
146 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000147 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530148}
149
150TEST_F(LockTest, MultiRequestWithConflictduetoSameSegmentLength)
151{
152 MockLock lockManager;
153 // Corrupt the locktype
154 std::get<2>(request[0]) = "Write";
155 // Match the segment lengths to points them to lock similar kind of
156 // resource
157 std::get<4>(request[0])[0].first = "LockAll";
158 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000159 EXPECT_TRUE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530160}
161
162TEST_F(LockTest, MultiRequestWithoutConflictduetoDifferentSegmentData)
163{
164 MockLock lockManager;
165 // Corrupt the locktype
166 std::get<2>(request[0]) = "Write";
167 // Match the segment lengths to points them to lock similar kind of
168 // resource
169 std::get<4>(request[0])[0].first = "DontLock";
170 std::get<4>(request[0])[1].first = "LockAll";
171
172 // Change the resource id(2nd byte) of first record, so the locks are
173 // different so no conflict
174 std::get<3>(request[0]) = 216179379183550464; // HEX 03 00 06 00 00 00 00 00
175 std::get<3>(request[1]) = 288236973221478400; // HEX 04 00 06 00 00 00 00 00
176 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000177 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530178}
179
180TEST_F(LockTest, MultiRequestWithConflictduetoSameSegmentData)
181{
182 MockLock lockManager;
183 // Corrupt the locktype
184 std::get<2>(request[0]) = "Write";
185 // Match the segment lengths to points them to lock similar kind of
186 // resource
187 std::get<4>(request[0])[0].first = "DontLock";
188 std::get<4>(request[0])[1].first = "LockAll";
Nan Zhoub5a10a22022-07-04 01:18:14 +0000189 // Dont Change the resource id(1st & 2nd byte) at all, so that the
190 // conflict occurs from the second segment which is trying to lock all
191 // the resources.
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530192 std::get<3>(request[0]) = 216173882346831872; // 03 00 01 00 2B 00 00 00
193 std::get<3>(request[1]) = 216173882346831872; // 03 00 01 00 2B 00 00 00
194 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000195 EXPECT_TRUE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530196}
197
198TEST_F(LockTest, MultiRequestWithoutConflictduetoDifferentSegmentLength)
199{
200 MockLock lockManager;
201 // Corrupt the locktype
202 std::get<2>(request[0]) = "Write";
203 // Match the segment lengths to points them to lock similar kind of
204 // resource
205 std::get<4>(request[0])[0].first = "LockSame";
206 // Change the segment length , so that the requests are trying to lock
207 // two different kind of resources
208 std::get<4>(request[0])[0].second = 3;
209 const LockRequests& t = request;
210 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000211 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530212}
213
214TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktype)
215{
216 MockLock lockManager;
217 // Match the segment lengths to points them to lock similar kind of
218 // resource
219 std::get<4>(request[0])[0].first = "LockAll";
220 const LockRequests& t = request;
221 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000222 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530223}
224
225TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktypeAndLockall)
226{
227 MockLock lockManager;
228 // Match the segment lengths to points them to lock similar kind of
229 // resource
230 std::get<4>(request[0])[0].first = "LockAll";
231 std::get<4>(request[0])[1].first = "LockAll";
232 const LockRequests& t = request;
233 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000234 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530235}
236
237TEST_F(LockTest, RequestConflictedWithLockTableEntries)
238{
239 MockLock lockManager;
240 const LockRequests& t = request1;
241 auto rc1 = lockManager.isConflictWithTable(t);
242 // Corrupt the lock type
243 std::get<2>(request[0]) = "Write";
244 // Corrupt the lockflag
245 std::get<4>(request[0])[1].first = "LockAll";
246 const LockRequests& p = request;
247 auto rc2 = lockManager.isConflictWithTable(p);
248 // Return a Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000249 EXPECT_TRUE(rc2.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530250}
251
252TEST_F(LockTest, RequestNotConflictedWithLockTableEntries)
253{
254 MockLock lockManager;
255 const LockRequests& t = request1;
256 // Insert the request1 into the lock table
257 auto rc1 = lockManager.isConflictWithTable(t);
258 // Corrupt the lock type
259 std::get<2>(request[0]) = "Read";
260 // Corrupt the lockflag
261 std::get<4>(request[0])[1].first = "LockAll";
262 const LockRequests& p = request;
263 auto rc2 = lockManager.isConflictWithTable(p);
264 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000265 EXPECT_FALSE(rc2.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530266}
267
268TEST_F(LockTest, TestGenerateTransactionIDFunction)
269{
270 MockLock lockManager;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000271 uint32_t transactionId1 = lockManager.generateTransactionId();
272 uint32_t transactionId2 = lockManager.generateTransactionId();
273 EXPECT_EQ(transactionId2, ++transactionId1);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530274}
275
276TEST_F(LockTest, ValidateTransactionIDsGoodTestCase)
277{
278 MockLock lockManager;
279 const LockRequests& t = request1;
280 // Insert the request1 into the lock table
281 auto rc1 = lockManager.isConflictWithTable(t);
282 std::vector<uint32_t> tids = {1};
283 const std::vector<uint32_t>& p = tids;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000284 EXPECT_TRUE(lockManager.validateRids(p));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530285}
286
287TEST_F(LockTest, ValidateTransactionIDsBadTestCase)
288{
289 MockLock lockManager;
290 // Insert the request1 into the lock table
291 const LockRequests& t = request1;
292 auto rc1 = lockManager.isConflictWithTable(t);
Sunitha Harish3e919b52020-10-13 01:21:48 -0500293 std::vector<uint32_t> tids = {10};
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530294 const std::vector<uint32_t>& p = tids;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000295 EXPECT_FALSE(lockManager.validateRids(p));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530296}
297
298TEST_F(LockTest, ValidateisItMyLockGoodTestCase)
299{
300 MockLock lockManager;
301 // Insert the request1 into the lock table
302 const LockRequests& t = request1;
303 auto rc1 = lockManager.isConflictWithTable(t);
304 std::vector<uint32_t> tids = {1};
305 const std::vector<uint32_t>& p = tids;
306 std::string hmcid = "hmc-id";
307 std::string sessionid = "xxxxx";
308 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
309 auto rc = lockManager.isItMyLock(p, ids);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000310 EXPECT_TRUE(rc.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530311}
312
313TEST_F(LockTest, ValidateisItMyLockBadTestCase)
314{
315 MockLock lockManager;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530316 // Corrupt the client identifier
317 std::get<1>(request1[0]) = "randomid";
318 // Insert the request1 into the lock table
319 const LockRequests& t = request1;
320 auto rc1 = lockManager.isConflictWithTable(t);
321 std::vector<uint32_t> tids = {1};
322 const std::vector<uint32_t>& p = tids;
323 std::string hmcid = "hmc-id";
Sunitha Harish3e919b52020-10-13 01:21:48 -0500324 std::string sessionid = "random";
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530325 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
326 auto rc = lockManager.isItMyLock(p, ids);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000327 EXPECT_FALSE(rc.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530328}
329
330TEST_F(LockTest, ValidateSessionIDForGetlocklistBadTestCase)
331{
332 MockLock lockManager;
333 // Insert the request1 into the lock table
334 const LockRequests& t = request1;
335 auto rc1 = lockManager.isConflictWithTable(t);
336 std::vector<std::string> sessionid = {"random"};
337 auto status = lockManager.getLockList(sessionid);
338 auto result =
339 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000340 EXPECT_THAT(result, IsEmpty());
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530341}
342
343TEST_F(LockTest, ValidateSessionIDForGetlocklistGoodTestCase)
344{
345 MockLock lockManager;
346 // Insert the request1 into the lock table
347 const LockRequests& t = request1;
348 auto rc1 = lockManager.isConflictWithTable(t);
349 std::vector<std::string> sessionid = {"xxxxx"};
350 auto status = lockManager.getLockList(sessionid);
351 auto result =
352 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000353 EXPECT_EQ(result.size(), 1);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530354}
Sunitha Harish3e919b52020-10-13 01:21:48 -0500355
Nan Zhou38ead5e2022-07-03 23:07:27 +0000356} // namespace
357} // namespace crow::ibm_mc_lock