blob: 087a84b431422844f588cd6a0b9e3048ecada7b9 [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>
Gunnar Mills1214b7e2020-06-04 10:11:30 -05004#include <string>
Nan Zhoud5c80ad2022-07-11 01:16:31 +00005#include <tuple>
6#include <utility>
7#include <variant>
8#include <vector>
Gunnar Mills1214b7e2020-06-04 10:11:30 -05009
Nan Zhoud5c80ad2022-07-11 01:16:31 +000010#include <gmock/gmock.h> // IWYU pragma: keep
11#include <gtest/gtest.h> // IWYU pragma: keep
12
13// IWYU pragma: no_include <gtest/gtest-message.h>
14// IWYU pragma: no_include <gtest/gtest-test-part.h>
15// IWYU pragma: no_include "gtest/gtest_pred_impl.h"
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053016
Nan Zhou38ead5e2022-07-03 23:07:27 +000017namespace crow::ibm_mc_lock
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053018{
Nan Zhou38ead5e2022-07-03 23:07:27 +000019namespace
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053020{
Nan Zhou38ead5e2022-07-03 23:07:27 +000021
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053022using SType = std::string;
23using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
24using LockRequests = std::vector<LockRequest>;
25using Rc =
26 std::pair<bool, std::variant<uint32_t, std::pair<uint32_t, LockRequest>>>;
27using RcRelaseLock = std::pair<bool, std::pair<uint32_t, LockRequest>>;
28using RcGetLockList =
29 std::variant<std::string, std::vector<std::pair<uint32_t, LockRequests>>>;
30using ListOfTransactionIds = std::vector<uint32_t>;
31using RcAcquireLock = std::pair<bool, std::variant<Rc, std::pair<bool, int>>>;
32using RcReleaseLockApi = std::pair<bool, std::variant<bool, RcRelaseLock>>;
33using SessionFlags = std::pair<SType, SType>;
34using ListOfSessionIds = std::vector<std::string>;
Nan Zhoub5a10a22022-07-04 01:18:14 +000035using ::testing::IsEmpty;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053036
37class LockTest : public ::testing::Test
38{
39 protected:
40 LockRequests request;
41 LockRequests request1, request2;
42 LockRequest record;
43
44 public:
Ed Tanousb31cef62022-06-30 17:51:46 -070045 LockTest() :
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053046 // lockrequest with multiple lockrequests
Ed Tanousb31cef62022-06-30 17:51:46 -070047 request{{"xxxxx",
48 "hmc-id",
49 "Read",
50 234,
51 {{"DontLock", 2}, {"DontLock", 4}}},
52 {"xxxxx",
53 "hmc-id",
54 "Read",
55 234,
56 {{"DontLock", 2}, {"DontLock", 4}}}},
57 request1{{"xxxxx",
58 "hmc-id",
59 "Read",
60 234,
61 {{"DontLock", 2}, {"DontLock", 4}}}},
62 request2{{"xxxxx",
63 "hmc-id",
64 "Write",
65 234,
66 {{"LockAll", 2}, {"DontLock", 4}}}},
67 record{
68 "xxxxx", "hmc-id", "Read", 234, {{"DontLock", 2}, {"DontLock", 4}}}
69 {}
Ed Tanous3174e4d2020-10-07 11:41:22 -070070
71 ~LockTest() override = default;
Ed Tanousecd6a3a2022-01-07 09:18:40 -080072
73 LockTest(const LockTest&) = delete;
74 LockTest(LockTest&&) = delete;
75 LockTest& operator=(const LockTest&) = delete;
76 LockTest& operator=(const LockTest&&) = delete;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053077};
78
79class MockLock : public crow::ibm_mc_lock::Lock
80{
81 public:
Ed Tanousb5a76932020-09-29 16:16:58 -070082 bool isValidLockRequest(const LockRequest& record1) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053083 {
84 bool status = Lock::isValidLockRequest(record1);
85 return status;
86 }
Ed Tanousb5a76932020-09-29 16:16:58 -070087 bool isConflictRequest(const LockRequests& request) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053088 {
89 bool status = Lock::isConflictRequest(request);
90 return status;
91 }
Ed Tanousb5a76932020-09-29 16:16:58 -070092 Rc isConflictWithTable(const LockRequests& request) override
manojkiraneda4eaf2ee2019-12-13 17:10:41 +053093 {
94 auto conflict = Lock::isConflictWithTable(request);
95 return conflict;
96 }
97 uint32_t generateTransactionId() override
98 {
99 uint32_t tid = Lock::generateTransactionId();
100 return tid;
101 }
102
103 bool validateRids(const ListOfTransactionIds& tids) override
104 {
105 bool status = Lock::validateRids(tids);
106 return status;
107 }
108 RcRelaseLock isItMyLock(const ListOfTransactionIds& tids,
109 const SessionFlags& ids) override
110 {
111 auto status = Lock::isItMyLock(tids, ids);
112 return status;
113 }
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530114 friend class LockTest;
115};
116
117TEST_F(LockTest, ValidationGoodTestCase)
118{
119 MockLock lockManager;
120 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000121 EXPECT_TRUE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530122}
123
124TEST_F(LockTest, ValidationBadTestWithLocktype)
125{
126 MockLock lockManager;
127 // Corrupt the lock type
128 std::get<2>(record) = "rwrite";
129 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000130 EXPECT_FALSE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530131}
132
133TEST_F(LockTest, ValidationBadTestWithlockFlags)
134{
135 MockLock lockManager;
136 // Corrupt the lockflag
137 std::get<4>(record)[0].first = "lock";
138 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000139 EXPECT_FALSE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530140}
141
142TEST_F(LockTest, ValidationBadTestWithSegmentlength)
143{
144 MockLock lockManager;
145 // Corrupt the Segment length
146 std::get<4>(record)[0].second = 7;
147 const LockRequest& t = record;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000148 EXPECT_FALSE(lockManager.isValidLockRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530149}
150
151TEST_F(LockTest, MultiRequestWithoutConflict)
152{
153 MockLock lockManager;
154 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000155 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530156}
157
158TEST_F(LockTest, MultiRequestWithConflictduetoSameSegmentLength)
159{
160 MockLock lockManager;
161 // Corrupt the locktype
162 std::get<2>(request[0]) = "Write";
163 // Match the segment lengths to points them to lock similar kind of
164 // resource
165 std::get<4>(request[0])[0].first = "LockAll";
166 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000167 EXPECT_TRUE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530168}
Patrick Williams26b36302023-05-10 17:29:00 -0500169#if 0 // Comment out due to bad code in include/ibm/locks.hpp
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530170TEST_F(LockTest, MultiRequestWithoutConflictduetoDifferentSegmentData)
171{
172 MockLock lockManager;
173 // Corrupt the locktype
174 std::get<2>(request[0]) = "Write";
175 // Match the segment lengths to points them to lock similar kind of
176 // resource
177 std::get<4>(request[0])[0].first = "DontLock";
178 std::get<4>(request[0])[1].first = "LockAll";
179
180 // Change the resource id(2nd byte) of first record, so the locks are
181 // different so no conflict
182 std::get<3>(request[0]) = 216179379183550464; // HEX 03 00 06 00 00 00 00 00
183 std::get<3>(request[1]) = 288236973221478400; // HEX 04 00 06 00 00 00 00 00
184 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000185 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530186}
187
188TEST_F(LockTest, MultiRequestWithConflictduetoSameSegmentData)
189{
190 MockLock lockManager;
191 // Corrupt the locktype
192 std::get<2>(request[0]) = "Write";
193 // Match the segment lengths to points them to lock similar kind of
194 // resource
195 std::get<4>(request[0])[0].first = "DontLock";
196 std::get<4>(request[0])[1].first = "LockAll";
Nan Zhoub5a10a22022-07-04 01:18:14 +0000197 // Dont Change the resource id(1st & 2nd byte) at all, so that the
198 // conflict occurs from the second segment which is trying to lock all
199 // the resources.
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530200 std::get<3>(request[0]) = 216173882346831872; // 03 00 01 00 2B 00 00 00
201 std::get<3>(request[1]) = 216173882346831872; // 03 00 01 00 2B 00 00 00
202 const LockRequests& t = request;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000203 EXPECT_TRUE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530204}
Patrick Williams26b36302023-05-10 17:29:00 -0500205#endif
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530206
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
Patrick Williams26b36302023-05-10 17:29:00 -0500246#if 0 // Comment out due to bad code in include/ibm/locks.hpp
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530247TEST_F(LockTest, RequestConflictedWithLockTableEntries)
248{
249 MockLock lockManager;
250 const LockRequests& t = request1;
251 auto rc1 = lockManager.isConflictWithTable(t);
252 // Corrupt the lock type
253 std::get<2>(request[0]) = "Write";
254 // Corrupt the lockflag
255 std::get<4>(request[0])[1].first = "LockAll";
256 const LockRequests& p = request;
257 auto rc2 = lockManager.isConflictWithTable(p);
258 // Return a Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000259 EXPECT_TRUE(rc2.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530260}
Patrick Williams26b36302023-05-10 17:29:00 -0500261#endif
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530262
263TEST_F(LockTest, RequestNotConflictedWithLockTableEntries)
264{
265 MockLock lockManager;
266 const LockRequests& t = request1;
267 // Insert the request1 into the lock table
268 auto rc1 = lockManager.isConflictWithTable(t);
269 // Corrupt the lock type
270 std::get<2>(request[0]) = "Read";
271 // Corrupt the lockflag
272 std::get<4>(request[0])[1].first = "LockAll";
273 const LockRequests& p = request;
274 auto rc2 = lockManager.isConflictWithTable(p);
275 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000276 EXPECT_FALSE(rc2.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530277}
278
279TEST_F(LockTest, TestGenerateTransactionIDFunction)
280{
281 MockLock lockManager;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000282 uint32_t transactionId1 = lockManager.generateTransactionId();
283 uint32_t transactionId2 = lockManager.generateTransactionId();
284 EXPECT_EQ(transactionId2, ++transactionId1);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530285}
286
287TEST_F(LockTest, ValidateTransactionIDsGoodTestCase)
288{
289 MockLock lockManager;
290 const LockRequests& t = request1;
291 // Insert the request1 into the lock table
292 auto rc1 = lockManager.isConflictWithTable(t);
293 std::vector<uint32_t> tids = {1};
294 const std::vector<uint32_t>& p = tids;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000295 EXPECT_TRUE(lockManager.validateRids(p));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530296}
297
298TEST_F(LockTest, ValidateTransactionIDsBadTestCase)
299{
300 MockLock lockManager;
301 // Insert the request1 into the lock table
302 const LockRequests& t = request1;
303 auto rc1 = lockManager.isConflictWithTable(t);
Sunitha Harish3e919b52020-10-13 01:21:48 -0500304 std::vector<uint32_t> tids = {10};
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530305 const std::vector<uint32_t>& p = tids;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000306 EXPECT_FALSE(lockManager.validateRids(p));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530307}
308
309TEST_F(LockTest, ValidateisItMyLockGoodTestCase)
310{
311 MockLock lockManager;
312 // Insert the request1 into the lock table
313 const LockRequests& t = request1;
314 auto rc1 = lockManager.isConflictWithTable(t);
315 std::vector<uint32_t> tids = {1};
316 const std::vector<uint32_t>& p = tids;
317 std::string hmcid = "hmc-id";
318 std::string sessionid = "xxxxx";
319 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
320 auto rc = lockManager.isItMyLock(p, ids);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000321 EXPECT_TRUE(rc.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530322}
323
324TEST_F(LockTest, ValidateisItMyLockBadTestCase)
325{
326 MockLock lockManager;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530327 // Corrupt the client identifier
328 std::get<1>(request1[0]) = "randomid";
329 // Insert the request1 into the lock table
330 const LockRequests& t = request1;
331 auto rc1 = lockManager.isConflictWithTable(t);
332 std::vector<uint32_t> tids = {1};
333 const std::vector<uint32_t>& p = tids;
334 std::string hmcid = "hmc-id";
Sunitha Harish3e919b52020-10-13 01:21:48 -0500335 std::string sessionid = "random";
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530336 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
337 auto rc = lockManager.isItMyLock(p, ids);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000338 EXPECT_FALSE(rc.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530339}
340
341TEST_F(LockTest, ValidateSessionIDForGetlocklistBadTestCase)
342{
343 MockLock lockManager;
344 // Insert the request1 into the lock table
345 const LockRequests& t = request1;
346 auto rc1 = lockManager.isConflictWithTable(t);
347 std::vector<std::string> sessionid = {"random"};
348 auto status = lockManager.getLockList(sessionid);
349 auto result =
350 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000351 EXPECT_THAT(result, IsEmpty());
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530352}
353
354TEST_F(LockTest, ValidateSessionIDForGetlocklistGoodTestCase)
355{
356 MockLock lockManager;
357 // Insert the request1 into the lock table
358 const LockRequests& t = request1;
359 auto rc1 = lockManager.isConflictWithTable(t);
360 std::vector<std::string> sessionid = {"xxxxx"};
361 auto status = lockManager.getLockList(sessionid);
362 auto result =
363 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000364 EXPECT_EQ(result.size(), 1);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530365}
Sunitha Harish3e919b52020-10-13 01:21:48 -0500366
Nan Zhou38ead5e2022-07-03 23:07:27 +0000367} // namespace
368} // namespace crow::ibm_mc_lock