blob: e89377df16056ff319c4475771f9f330392e752c [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
manojkiraneda4eaf2ee2019-12-13 17:10:41 +05305#include "gmock/gmock.h"
6
7namespace crow
8{
9namespace ibm_mc_lock
10{
11using SType = std::string;
12using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
13using LockRequests = std::vector<LockRequest>;
14using Rc =
15 std::pair<bool, std::variant<uint32_t, std::pair<uint32_t, LockRequest>>>;
16using RcRelaseLock = std::pair<bool, std::pair<uint32_t, LockRequest>>;
17using RcGetLockList =
18 std::variant<std::string, std::vector<std::pair<uint32_t, LockRequests>>>;
19using ListOfTransactionIds = std::vector<uint32_t>;
20using RcAcquireLock = std::pair<bool, std::variant<Rc, std::pair<bool, int>>>;
21using RcReleaseLockApi = std::pair<bool, std::variant<bool, RcRelaseLock>>;
22using SessionFlags = std::pair<SType, SType>;
23using ListOfSessionIds = std::vector<std::string>;
24
25class LockTest : public ::testing::Test
26{
27 protected:
28 LockRequests request;
29 LockRequests request1, request2;
30 LockRequest record;
31
32 public:
33 LockTest()
34 {
35 record = {
36 "xxxxx", "hmc-id", "Read", 234, {{"DontLock", 2}, {"DontLock", 4}}};
37 // lockrequest with multiple lockrequests
38 request = {{"xxxxx",
39 "hmc-id",
40 "Read",
41 234,
42 {{"DontLock", 2}, {"DontLock", 4}}},
43 {"xxxxx",
44 "hmc-id",
45 "Read",
46 234,
47 {{"DontLock", 2}, {"DontLock", 4}}}};
48 request1 = {{"xxxxx",
49 "hmc-id",
50 "Read",
51 234,
52 {{"DontLock", 2}, {"DontLock", 4}}}};
53 request2 = {{"xxxxx",
54 "hmc-id",
55 "Write",
56 234,
57 {{"LockAll", 2}, {"DontLock", 4}}}};
58 }
Ed Tanous3174e4d2020-10-07 11:41:22 -070059
60 ~LockTest() override = default;
Ed Tanousecd6a3a2022-01-07 09:18:40 -080061
62 LockTest(const LockTest&) = delete;
63 LockTest(LockTest&&) = delete;
64 LockTest& operator=(const LockTest&) = delete;
65 LockTest& operator=(const LockTest&&) = delete;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053066};
67
68class MockLock : public crow::ibm_mc_lock::Lock
69{
70 public:
Ed Tanousb5a76932020-09-29 16:16:58 -070071 bool isValidLockRequest(const LockRequest& record1) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053072 {
73 bool status = Lock::isValidLockRequest(record1);
74 return status;
75 }
Ed Tanousb5a76932020-09-29 16:16:58 -070076 bool isConflictRequest(const LockRequests& request) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053077 {
78 bool status = Lock::isConflictRequest(request);
79 return status;
80 }
Ed Tanousb5a76932020-09-29 16:16:58 -070081 Rc isConflictWithTable(const LockRequests& request) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053082 {
83 auto conflict = Lock::isConflictWithTable(request);
84 return conflict;
85 }
86 uint32_t generateTransactionId() override
87 {
88 uint32_t tid = Lock::generateTransactionId();
89 return tid;
90 }
91
92 bool validateRids(const ListOfTransactionIds& tids) override
93 {
94 bool status = Lock::validateRids(tids);
95 return status;
96 }
97 RcRelaseLock isItMyLock(const ListOfTransactionIds& tids,
98 const SessionFlags& ids) override
99 {
100 auto status = Lock::isItMyLock(tids, ids);
101 return status;
102 }
103 RcGetLockList getList(std::vector<std::string>& listSessionid)
104 {
105 auto status = Lock::getLockList(listSessionid);
106 return status;
107 }
108 friend class LockTest;
109};
110
111TEST_F(LockTest, ValidationGoodTestCase)
112{
113 MockLock lockManager;
114 const LockRequest& t = record;
115 ASSERT_EQ(1, lockManager.isValidLockRequest(t));
116}
117
118TEST_F(LockTest, ValidationBadTestWithLocktype)
119{
120 MockLock lockManager;
121 // Corrupt the lock type
122 std::get<2>(record) = "rwrite";
123 const LockRequest& t = record;
124 ASSERT_EQ(0, lockManager.isValidLockRequest(t));
125}
126
127TEST_F(LockTest, ValidationBadTestWithlockFlags)
128{
129 MockLock lockManager;
130 // Corrupt the lockflag
131 std::get<4>(record)[0].first = "lock";
132 const LockRequest& t = record;
133 ASSERT_EQ(0, lockManager.isValidLockRequest(t));
134}
135
136TEST_F(LockTest, ValidationBadTestWithSegmentlength)
137{
138 MockLock lockManager;
139 // Corrupt the Segment length
140 std::get<4>(record)[0].second = 7;
141 const LockRequest& t = record;
142 ASSERT_EQ(0, lockManager.isValidLockRequest(t));
143}
144
145TEST_F(LockTest, MultiRequestWithoutConflict)
146{
147 MockLock lockManager;
148 const LockRequests& t = request;
149 ASSERT_EQ(0, lockManager.isConflictRequest(t));
150}
151
152TEST_F(LockTest, MultiRequestWithConflictduetoSameSegmentLength)
153{
154 MockLock lockManager;
155 // Corrupt the locktype
156 std::get<2>(request[0]) = "Write";
157 // Match the segment lengths to points them to lock similar kind of
158 // resource
159 std::get<4>(request[0])[0].first = "LockAll";
160 const LockRequests& t = request;
161 ASSERT_EQ(1, lockManager.isConflictRequest(t));
162}
163
164TEST_F(LockTest, MultiRequestWithoutConflictduetoDifferentSegmentData)
165{
166 MockLock lockManager;
167 // Corrupt the locktype
168 std::get<2>(request[0]) = "Write";
169 // Match the segment lengths to points them to lock similar kind of
170 // resource
171 std::get<4>(request[0])[0].first = "DontLock";
172 std::get<4>(request[0])[1].first = "LockAll";
173
174 // Change the resource id(2nd byte) of first record, so the locks are
175 // different so no conflict
176 std::get<3>(request[0]) = 216179379183550464; // HEX 03 00 06 00 00 00 00 00
177 std::get<3>(request[1]) = 288236973221478400; // HEX 04 00 06 00 00 00 00 00
178 const LockRequests& t = request;
179 ASSERT_EQ(0, lockManager.isConflictRequest(t));
180}
181
182TEST_F(LockTest, MultiRequestWithConflictduetoSameSegmentData)
183{
184 MockLock lockManager;
185 // Corrupt the locktype
186 std::get<2>(request[0]) = "Write";
187 // Match the segment lengths to points them to lock similar kind of
188 // resource
189 std::get<4>(request[0])[0].first = "DontLock";
190 std::get<4>(request[0])[1].first = "LockAll";
191 // Dont Change the resource id(1st & 2nd byte) at all, so that the conflict
192 // occurs from the second segment which is trying to lock all the resources.
193 std::get<3>(request[0]) = 216173882346831872; // 03 00 01 00 2B 00 00 00
194 std::get<3>(request[1]) = 216173882346831872; // 03 00 01 00 2B 00 00 00
195 const LockRequests& t = request;
196 ASSERT_EQ(1, lockManager.isConflictRequest(t));
197}
198
199TEST_F(LockTest, MultiRequestWithoutConflictduetoDifferentSegmentLength)
200{
201 MockLock lockManager;
202 // Corrupt the locktype
203 std::get<2>(request[0]) = "Write";
204 // Match the segment lengths to points them to lock similar kind of
205 // resource
206 std::get<4>(request[0])[0].first = "LockSame";
207 // Change the segment length , so that the requests are trying to lock
208 // two different kind of resources
209 std::get<4>(request[0])[0].second = 3;
210 const LockRequests& t = request;
211 // Return No Conflict
212 ASSERT_EQ(0, lockManager.isConflictRequest(t));
213}
214
215TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktype)
216{
217 MockLock lockManager;
218 // Match the segment lengths to points them to lock similar kind of
219 // resource
220 std::get<4>(request[0])[0].first = "LockAll";
221 const LockRequests& t = request;
222 // Return No Conflict
223 ASSERT_EQ(0, lockManager.isConflictRequest(t));
224}
225
226TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktypeAndLockall)
227{
228 MockLock lockManager;
229 // Match the segment lengths to points them to lock similar kind of
230 // resource
231 std::get<4>(request[0])[0].first = "LockAll";
232 std::get<4>(request[0])[1].first = "LockAll";
233 const LockRequests& t = request;
234 // Return No Conflict
235 ASSERT_EQ(0, lockManager.isConflictRequest(t));
236}
237
238TEST_F(LockTest, RequestConflictedWithLockTableEntries)
239{
240 MockLock lockManager;
241 const LockRequests& t = request1;
242 auto rc1 = lockManager.isConflictWithTable(t);
243 // Corrupt the lock type
244 std::get<2>(request[0]) = "Write";
245 // Corrupt the lockflag
246 std::get<4>(request[0])[1].first = "LockAll";
247 const LockRequests& p = request;
248 auto rc2 = lockManager.isConflictWithTable(p);
249 // Return a Conflict
250 ASSERT_EQ(1, rc2.first);
251}
252
253TEST_F(LockTest, RequestNotConflictedWithLockTableEntries)
254{
255 MockLock lockManager;
256 const LockRequests& t = request1;
257 // Insert the request1 into the lock table
258 auto rc1 = lockManager.isConflictWithTable(t);
259 // Corrupt the lock type
260 std::get<2>(request[0]) = "Read";
261 // Corrupt the lockflag
262 std::get<4>(request[0])[1].first = "LockAll";
263 const LockRequests& p = request;
264 auto rc2 = lockManager.isConflictWithTable(p);
265 // Return No Conflict
266 ASSERT_EQ(0, rc2.first);
267}
268
269TEST_F(LockTest, TestGenerateTransactionIDFunction)
270{
271 MockLock lockManager;
272 uint32_t transactionid1 = lockManager.generateTransactionId();
273 uint32_t transactionid2 = lockManager.generateTransactionId();
274 EXPECT_TRUE(transactionid2 == ++transactionid1);
275}
276
277TEST_F(LockTest, ValidateTransactionIDsGoodTestCase)
278{
279 MockLock lockManager;
280 const LockRequests& t = request1;
281 // Insert the request1 into the lock table
282 auto rc1 = lockManager.isConflictWithTable(t);
283 std::vector<uint32_t> tids = {1};
284 const std::vector<uint32_t>& p = tids;
285 ASSERT_EQ(1, lockManager.validateRids(p));
286}
287
288TEST_F(LockTest, ValidateTransactionIDsBadTestCase)
289{
290 MockLock lockManager;
291 // Insert the request1 into the lock table
292 const LockRequests& t = request1;
293 auto rc1 = lockManager.isConflictWithTable(t);
Sunitha Harish3e919b52020-10-13 01:21:48 -0500294 std::vector<uint32_t> tids = {10};
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530295 const std::vector<uint32_t>& p = tids;
296 ASSERT_EQ(0, lockManager.validateRids(p));
297}
298
299TEST_F(LockTest, ValidateisItMyLockGoodTestCase)
300{
301 MockLock lockManager;
302 // Insert the request1 into the lock table
303 const LockRequests& t = request1;
304 auto rc1 = lockManager.isConflictWithTable(t);
305 std::vector<uint32_t> tids = {1};
306 const std::vector<uint32_t>& p = tids;
307 std::string hmcid = "hmc-id";
308 std::string sessionid = "xxxxx";
309 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
310 auto rc = lockManager.isItMyLock(p, ids);
311 ASSERT_EQ(1, rc.first);
312}
313
314TEST_F(LockTest, ValidateisItMyLockBadTestCase)
315{
316 MockLock lockManager;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530317 // Corrupt the client identifier
318 std::get<1>(request1[0]) = "randomid";
319 // Insert the request1 into the lock table
320 const LockRequests& t = request1;
321 auto rc1 = lockManager.isConflictWithTable(t);
322 std::vector<uint32_t> tids = {1};
323 const std::vector<uint32_t>& p = tids;
324 std::string hmcid = "hmc-id";
Sunitha Harish3e919b52020-10-13 01:21:48 -0500325 std::string sessionid = "random";
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530326 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
327 auto rc = lockManager.isItMyLock(p, ids);
328 ASSERT_EQ(0, rc.first);
329}
330
331TEST_F(LockTest, ValidateSessionIDForGetlocklistBadTestCase)
332{
333 MockLock lockManager;
334 // Insert the request1 into the lock table
335 const LockRequests& t = request1;
336 auto rc1 = lockManager.isConflictWithTable(t);
337 std::vector<std::string> sessionid = {"random"};
338 auto status = lockManager.getLockList(sessionid);
339 auto result =
340 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
341 ASSERT_EQ(0, result.size());
342}
343
344TEST_F(LockTest, ValidateSessionIDForGetlocklistGoodTestCase)
345{
346 MockLock lockManager;
347 // Insert the request1 into the lock table
348 const LockRequests& t = request1;
349 auto rc1 = lockManager.isConflictWithTable(t);
350 std::vector<std::string> sessionid = {"xxxxx"};
351 auto status = lockManager.getLockList(sessionid);
352 auto result =
353 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
354 ASSERT_EQ(1, result.size());
355}
Sunitha Harish3e919b52020-10-13 01:21:48 -0500356
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530357} // namespace ibm_mc_lock
358} // namespace crow