xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
tests
libxrpl
basics
Mutex.cpp
1
#include <xrpl/basics/Mutex.hpp>
2
3
#include <gtest/gtest.h>
4
5
#include <
memory
>
6
#include <
mutex
>
7
#include <
shared_mutex
>
8
#include <
string
>
9
#include <
type_traits
>
10
#include <
utility
>
11
#include <
vector
>
12
13
using namespace
xrpl
;
14
15
struct
MutexMakeTest
: ::testing::Test
16
{
17
};
18
19
TEST_F
(
MutexMakeTest
, default_constructor)
20
{
21
auto
m = Mutex<int>::make();
22
auto
lock = m.lock();
23
EXPECT_EQ(*lock, 0);
24
}
25
26
TEST_F
(
MutexMakeTest
, single_argument)
27
{
28
auto
m = Mutex<int>::make(42);
29
auto
lock
= m.lock();
30
EXPECT_EQ(*lock, 42);
31
}
32
33
TEST_F
(
MutexMakeTest
, string_argument)
34
{
35
auto
m = Mutex<std::string>::make(
"test"
);
36
auto
lock
= m.lock();
37
EXPECT_EQ(*lock,
"test"
);
38
}
39
40
TEST_F
(
MutexMakeTest
, move_only_type)
41
{
42
auto
m = Mutex<std::unique_ptr<int>>::make(
std::make_unique<int>
(100));
43
auto
lock
= m.lock();
44
EXPECT_NE(
lock
->get(),
nullptr
);
45
EXPECT_EQ(**lock, 100);
46
}
47
48
struct
MutexDirectConstructionTest
: ::testing::Test
49
{
50
};
51
52
TEST_F
(
MutexDirectConstructionTest
, default_constructor)
53
{
54
// Test default construction with a type that has a non-trivial
55
// default constructor
56
Mutex<std::string> m;
57
auto
lock = m.lock();
58
EXPECT_TRUE(lock->empty());
59
}
60
61
TEST_F
(
MutexDirectConstructionTest
, default_initialization)
62
{
63
Mutex<int> m;
64
auto
lock
= m.lock();
65
EXPECT_EQ(*lock, 0);
66
}
67
68
TEST_F
(
MutexDirectConstructionTest
, constructor_with_value)
69
{
70
Mutex<int> m(42);
71
auto
lock
= m.lock();
72
EXPECT_EQ(*lock, 42);
73
}
74
75
TEST_F
(
MutexDirectConstructionTest
, constructor_with_string)
76
{
77
Mutex<std::string> m(
std::string
(
"hello"
));
78
auto
lock
= m.lock();
79
EXPECT_EQ(*lock,
"hello"
);
80
}
81
82
struct
MutexLockNonConstTest
: ::testing::Test
83
{
84
};
85
86
TEST_F
(
MutexLockNonConstTest
, operator_star)
87
{
88
Mutex<int> m(10);
89
{
90
auto
lock = m.lock();
91
EXPECT_EQ(*lock, 10);
92
*lock = 20;
93
}
94
auto
lock
= m.lock();
95
EXPECT_EQ(*lock, 20);
96
}
97
98
TEST_F
(
MutexLockNonConstTest
, get_method)
99
{
100
Mutex<int> m(10);
101
{
102
auto
lock
= m.lock();
103
EXPECT_EQ(
lock
.get(), 10);
104
lock
.get() = 30;
105
}
106
auto
lock
= m.lock();
107
EXPECT_EQ(
lock
.get(), 30);
108
}
109
110
TEST_F
(
MutexLockNonConstTest
, operator_arrow)
111
{
112
Mutex<std::string> m(
std::string
(
"test"
));
113
{
114
auto
lock
= m.lock();
115
EXPECT_EQ(
lock
->size(), 4);
116
lock
->append(
" string"
);
117
}
118
auto
lock
= m.lock();
119
EXPECT_EQ(*lock,
"test string"
);
120
}
121
122
TEST_F
(
MutexLockNonConstTest
, multiple_modifications)
123
{
124
Mutex<int> m(10);
125
{
126
auto
lock
= m.lock();
127
*
lock
= 20;
128
}
129
{
130
auto
lock
= m.lock();
131
EXPECT_EQ(
lock
.get(), 20);
132
lock
.get() = 30;
133
}
134
{
135
auto
lock
= m.lock();
136
EXPECT_EQ(*lock, 30);
137
}
138
}
139
140
struct
MutexLockConstTest
: ::testing::Test
141
{
142
};
143
144
TEST_F
(
MutexLockConstTest
, operator_star)
145
{
146
Mutex<int>
const
m(42);
147
auto
lock = m.lock();
148
static_assert
(
std::is_const_v
<
std::remove_reference_t
<
decltype
(*lock)>>);
149
EXPECT_EQ(*lock, 42);
150
}
151
152
TEST_F
(
MutexLockConstTest
, get_method)
153
{
154
Mutex<int>
const
m(42);
155
auto
lock
= m.lock();
156
static_assert
(
std::is_const_v
<
std::remove_reference_t
<
decltype
(
lock
.get())>>);
157
EXPECT_EQ(
lock
.get(), 42);
158
}
159
160
TEST_F
(
MutexLockConstTest
, operator_arrow)
161
{
162
Mutex<std::string>
const
m(
std::string
(
"test"
));
163
auto
lock
= m.lock();
164
static_assert
(
std::is_const_v
<
std::remove_reference_t
<
decltype
(*lock)>>);
165
EXPECT_EQ(
lock
->size(), 4);
166
EXPECT_EQ(
lock
->at(0),
't'
);
167
}
168
169
struct
MutexConstCorrectnessTest
: ::testing::Test
170
{
171
};
172
173
TEST_F
(
MutexConstCorrectnessTest
, non_const_allows_modification)
174
{
175
Mutex<std::vector<int>> m({1, 2, 3, 4, 5});
176
{
177
auto
lock
= m.lock();
178
EXPECT_EQ(
lock
->size(), 5);
179
lock
->push_back(6);
180
}
181
auto
lock
= m.lock();
182
EXPECT_EQ(
lock
->size(), 6);
183
EXPECT_EQ(
lock
->back(), 6);
184
}
185
186
TEST_F
(
MutexConstCorrectnessTest
, const_reference_provides_const_access)
187
{
188
Mutex<std::vector<int>>
const
m({1, 2, 3, 4, 5, 6});
189
Mutex<std::vector<int>>
const
& constRef = m;
190
auto
lock
= constRef.lock();
191
static_assert
(
std::is_const_v
<
std::remove_reference_t
<
decltype
(*lock)>>);
192
EXPECT_EQ(
lock
->size(), 6);
193
EXPECT_EQ(
lock
->at(5), 6);
194
}
195
196
struct
MutexDifferentLockTypesTest
: ::testing::Test
197
{
198
};
199
200
TEST_F
(
MutexDifferentLockTypesTest
, scoped_lock)
201
{
202
Mutex<int> m(0);
203
{
204
auto
lock = m.lock();
205
*lock = 1;
206
}
207
auto
lock
= m.lock();
208
EXPECT_EQ(*lock, 1);
209
}
210
211
TEST_F
(
MutexDifferentLockTypesTest
, unique_lock)
212
{
213
Mutex<int> m(0);
214
auto
lock
= m.lock<
std::unique_lock
>();
215
EXPECT_EQ(*lock, 0);
216
*
lock
= 2;
217
218
std::unique_lock<std::mutex>
& ul =
lock
;
219
ul.
unlock
();
220
ul.
lock
();
221
EXPECT_EQ(*lock, 2);
222
}
223
224
struct
MutexSharedMutexTest
: ::testing::Test
225
{
226
};
227
228
TEST_F
(
MutexSharedMutexTest
, shared_lock_for_const_access)
229
{
230
Mutex<int, std::shared_mutex>
const
m(100);
231
Mutex<int, std::shared_mutex>
const
& constRef = m;
232
auto
lock = constRef.lock<
std::shared_lock
>();
233
EXPECT_EQ(*lock, 100);
234
}
235
236
TEST_F
(
MutexSharedMutexTest
, unique_lock_for_mutable_access)
237
{
238
Mutex<int, std::shared_mutex> m(100);
239
{
240
auto
lock
= m.lock<
std::unique_lock
>();
241
*
lock
= 200;
242
}
243
auto
lock
= m.lock<
std::shared_lock
>();
244
EXPECT_EQ(*lock, 200);
245
}
246
247
struct
MutexComplexTypeTest
: ::testing::Test
248
{
249
struct
Data
250
{
251
int
x
;
252
std::string
y
;
253
254
Data
(
int
x
,
std::string
y
) :
x
(
x
),
y
(
std
::move(
y
))
255
{
256
}
257
};
258
};
259
260
TEST_F
(
MutexComplexTypeTest
, construct_and_access)
261
{
262
auto
m = Mutex<Data>::make(42,
"hello"
);
263
auto
lock
= m.lock();
264
EXPECT_EQ(
lock
->x, 42);
265
EXPECT_EQ(
lock
->y,
"hello"
);
266
}
267
268
TEST_F
(
MutexComplexTypeTest
, modify_fields)
269
{
270
auto
m = Mutex<Data>::make(42,
"hello"
);
271
{
272
auto
lock
= m.lock();
273
lock
->x = 100;
274
lock
->y =
"world"
;
275
}
276
{
277
auto
lock
= m.lock();
278
EXPECT_EQ(
lock
->x, 100);
279
EXPECT_EQ(
lock
->y,
"world"
);
280
}
281
}
282
283
TEST_F
(
MutexComplexTypeTest
, const_access_to_fields)
284
{
285
auto
const
m = Mutex<Data>::make(42,
"hello"
);
286
auto
lock
= m.lock();
287
static_assert
(
std::is_const_v
<
std::remove_reference_t
<
decltype
(*lock)>>);
288
EXPECT_EQ(
lock
->x, 42);
289
EXPECT_EQ(
lock
->y,
"hello"
);
290
}
std::string
std::is_const_v
T is_const_v
std::lock
T lock(T... args)
std::make_unique
T make_unique(T... args)
memory
mutex
std
STL namespace.
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::TEST_F
TEST_F(HardenedHashTest, user_types)
Definition
hardened_hash.cpp:213
std::remove_reference_t
std::shared_lock
shared_mutex
string
MutexComplexTypeTest::Data::x
int x
Definition
Mutex.cpp:251
MutexComplexTypeTest::Data::y
std::string y
Definition
Mutex.cpp:252
MutexComplexTypeTest::Data::Data
Data(int x, std::string y)
Definition
Mutex.cpp:254
MutexComplexTypeTest
Definition
Mutex.cpp:248
MutexConstCorrectnessTest
Definition
Mutex.cpp:170
MutexDifferentLockTypesTest
Definition
Mutex.cpp:197
MutexDirectConstructionTest
Definition
Mutex.cpp:49
MutexLockConstTest
Definition
Mutex.cpp:141
MutexLockNonConstTest
Definition
Mutex.cpp:83
MutexMakeTest
Definition
Mutex.cpp:16
MutexSharedMutexTest
Definition
Mutex.cpp:225
type_traits
std::unique_lock
std::unique_lock::unlock
T unlock(T... args)
utility
vector
Generated by
1.17.0