blob: 9570ec6f903c228bc04ad83931fd328b2a199f1d [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}
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530169
170TEST_F(LockTest, MultiRequestWithoutConflictduetoDifferentSegmentLength)
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 = "LockSame";
178 // Change the segment length , so that the requests are trying to lock
179 // two different kind of resources
180 std::get<4>(request[0])[0].second = 3;
181 const LockRequests& t = request;
182 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000183 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530184}
185
186TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktype)
187{
188 MockLock lockManager;
189 // Match the segment lengths to points them to lock similar kind of
190 // resource
191 std::get<4>(request[0])[0].first = "LockAll";
192 const LockRequests& t = request;
193 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000194 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530195}
196
197TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktypeAndLockall)
198{
199 MockLock lockManager;
200 // Match the segment lengths to points them to lock similar kind of
201 // resource
202 std::get<4>(request[0])[0].first = "LockAll";
203 std::get<4>(request[0])[1].first = "LockAll";
204 const LockRequests& t = request;
205 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000206 EXPECT_FALSE(lockManager.isConflictRequest(t));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530207}
208
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530209TEST_F(LockTest, RequestNotConflictedWithLockTableEntries)
210{
211 MockLock lockManager;
212 const LockRequests& t = request1;
213 // Insert the request1 into the lock table
214 auto rc1 = lockManager.isConflictWithTable(t);
215 // Corrupt the lock type
216 std::get<2>(request[0]) = "Read";
217 // Corrupt the lockflag
218 std::get<4>(request[0])[1].first = "LockAll";
219 const LockRequests& p = request;
220 auto rc2 = lockManager.isConflictWithTable(p);
221 // Return No Conflict
Nan Zhoub5a10a22022-07-04 01:18:14 +0000222 EXPECT_FALSE(rc2.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530223}
224
225TEST_F(LockTest, TestGenerateTransactionIDFunction)
226{
227 MockLock lockManager;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000228 uint32_t transactionId1 = lockManager.generateTransactionId();
229 uint32_t transactionId2 = lockManager.generateTransactionId();
230 EXPECT_EQ(transactionId2, ++transactionId1);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530231}
232
233TEST_F(LockTest, ValidateTransactionIDsGoodTestCase)
234{
235 MockLock lockManager;
236 const LockRequests& t = request1;
237 // Insert the request1 into the lock table
238 auto rc1 = lockManager.isConflictWithTable(t);
239 std::vector<uint32_t> tids = {1};
240 const std::vector<uint32_t>& p = tids;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000241 EXPECT_TRUE(lockManager.validateRids(p));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530242}
243
244TEST_F(LockTest, ValidateTransactionIDsBadTestCase)
245{
246 MockLock lockManager;
247 // Insert the request1 into the lock table
248 const LockRequests& t = request1;
249 auto rc1 = lockManager.isConflictWithTable(t);
Sunitha Harish3e919b52020-10-13 01:21:48 -0500250 std::vector<uint32_t> tids = {10};
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530251 const std::vector<uint32_t>& p = tids;
Nan Zhoub5a10a22022-07-04 01:18:14 +0000252 EXPECT_FALSE(lockManager.validateRids(p));
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530253}
254
255TEST_F(LockTest, ValidateisItMyLockGoodTestCase)
256{
257 MockLock lockManager;
258 // Insert the request1 into the lock table
259 const LockRequests& t = request1;
260 auto rc1 = lockManager.isConflictWithTable(t);
261 std::vector<uint32_t> tids = {1};
262 const std::vector<uint32_t>& p = tids;
263 std::string hmcid = "hmc-id";
264 std::string sessionid = "xxxxx";
265 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
266 auto rc = lockManager.isItMyLock(p, ids);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000267 EXPECT_TRUE(rc.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530268}
269
270TEST_F(LockTest, ValidateisItMyLockBadTestCase)
271{
272 MockLock lockManager;
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530273 // Corrupt the client identifier
274 std::get<1>(request1[0]) = "randomid";
275 // Insert the request1 into the lock table
276 const LockRequests& t = request1;
277 auto rc1 = lockManager.isConflictWithTable(t);
278 std::vector<uint32_t> tids = {1};
279 const std::vector<uint32_t>& p = tids;
280 std::string hmcid = "hmc-id";
Sunitha Harish3e919b52020-10-13 01:21:48 -0500281 std::string sessionid = "random";
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530282 std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
283 auto rc = lockManager.isItMyLock(p, ids);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000284 EXPECT_FALSE(rc.first);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530285}
286
287TEST_F(LockTest, ValidateSessionIDForGetlocklistBadTestCase)
288{
289 MockLock lockManager;
290 // Insert the request1 into the lock table
291 const LockRequests& t = request1;
292 auto rc1 = lockManager.isConflictWithTable(t);
293 std::vector<std::string> sessionid = {"random"};
294 auto status = lockManager.getLockList(sessionid);
295 auto result =
296 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000297 EXPECT_THAT(result, IsEmpty());
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530298}
299
300TEST_F(LockTest, ValidateSessionIDForGetlocklistGoodTestCase)
301{
302 MockLock lockManager;
303 // Insert the request1 into the lock table
304 const LockRequests& t = request1;
305 auto rc1 = lockManager.isConflictWithTable(t);
306 std::vector<std::string> sessionid = {"xxxxx"};
307 auto status = lockManager.getLockList(sessionid);
308 auto result =
309 std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
Nan Zhoub5a10a22022-07-04 01:18:14 +0000310 EXPECT_EQ(result.size(), 1);
manojkiraneda4eaf2ee2019-12-13 17:10:41 +0530311}
Sunitha Harish3e919b52020-10-13 01:21:48 -0500312
Nan Zhou38ead5e2022-07-03 23:07:27 +0000313} // namespace
314} // namespace crow::ibm_mc_lock