xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
test
core
Coroutine_test.cpp
1
2
#include <test/jtx/Env.h>
3
#include <test/jtx/envconfig.h>
4
5
#include <xrpld/core/Config.h>
6
7
#include <xrpl/basics/LocalValue.h>
8
#include <xrpl/beast/unit_test/suite.h>
9
#include <xrpl/core/Job.h>
10
#include <xrpl/core/JobQueue.h>
11
12
#include <
array
>
13
#include <
chrono
>
14
#include <
condition_variable
>
15
#include <
memory
>
16
#include <
mutex
>
17
18
namespace
xrpl::test
{
19
20
class
Coroutine_test
:
public
beast::unit_test::Suite
21
{
22
public
:
23
class
Gate
24
{
25
private
:
26
std::condition_variable
cv_
;
27
std::mutex
mutex_
;
28
bool
signaled_
=
false
;
29
30
public
:
31
// Thread safe, blocks until signaled or period expires.
32
// Returns `true` if signaled.
33
template
<
class
Rep,
class
Period>
34
bool
35
waitFor
(
std::chrono::duration<Rep, Period>
const
& relTime)
36
{
37
std::unique_lock<std::mutex>
lk(
mutex_
);
38
auto
b =
cv_
.wait_for(lk, relTime, [
this
] {
return
signaled_
; });
39
signaled_
=
false
;
40
return
b;
41
}
42
43
void
44
signal
()
45
{
46
std::scoped_lock
const
lk(
mutex_
);
47
signaled_
=
true
;
48
cv_
.notify_all();
49
}
50
};
51
52
void
53
correctOrder
()
54
{
55
using namespace
std::chrono_literals;
56
using namespace
jtx
;
57
58
testcase
(
"correct order"
);
59
60
Env
env(*
this
,
envconfig
([](
std::unique_ptr<Config>
cfg) {
61
cfg->forceMultiThread =
true
;
62
return
cfg;
63
}));
64
65
Gate
g1, g2;
66
std::shared_ptr<JobQueue::Coro>
c;
67
env.app().getJobQueue().postCoro(
JtClient
,
"CoroTest"
, [&](
auto
const
& cr) {
68
c = cr;
69
g1.signal();
70
c->yield();
71
g2.signal();
72
});
73
BEAST_EXPECT(g1.waitFor(5s));
74
c->join();
75
c->post();
76
BEAST_EXPECT(g2.waitFor(5s));
77
}
78
79
void
80
incorrectOrder
()
81
{
82
using namespace
std::chrono_literals;
83
using namespace
jtx
;
84
85
testcase
(
"incorrect order"
);
86
87
Env
env(*
this
,
envconfig
([](
std::unique_ptr<Config>
cfg) {
88
cfg->forceMultiThread =
true
;
89
return
cfg;
90
}));
91
92
Gate
g;
93
env.app().getJobQueue().postCoro(
JtClient
,
"CoroTest"
, [&](
auto
const
& c) {
94
c->post();
95
c->yield();
96
g.signal();
97
});
98
BEAST_EXPECT(g.waitFor(5s));
99
}
100
101
void
102
threadSpecificStorage
()
103
{
104
using namespace
std::chrono_literals;
105
using namespace
jtx
;
106
107
testcase
(
"thread specific storage"
);
108
Env
env(*
this
);
109
110
auto
& jq = env.
app
().
getJobQueue
();
111
112
static
int
const
kN = 4;
113
std::array<std::shared_ptr<JobQueue::Coro>
, kN> a;
114
115
LocalValue<int>
lv(-1);
116
BEAST_EXPECT(*lv == -1);
117
118
Gate
g;
119
jq.addJob(
JtClient
,
"LocalValTest"
, [&]() {
120
this->BEAST_EXPECT(*lv == -1);
121
*lv = -2;
122
this->BEAST_EXPECT(*lv == -2);
123
g.
signal
();
124
});
125
BEAST_EXPECT(g.
waitFor
(5s));
126
BEAST_EXPECT(*lv == -1);
127
128
for
(
int
i = 0; i < kN; ++i)
129
{
130
jq.postCoro(
JtClient
,
"CoroTest"
, [&,
id
= i](
auto
const
& c) {
131
a[id] = c;
132
g.
signal
();
133
c->yield();
134
135
this->BEAST_EXPECT(*lv == -1);
136
*lv = id;
137
this->BEAST_EXPECT(*lv ==
id
);
138
g.
signal
();
139
c->yield();
140
141
this->BEAST_EXPECT(*lv ==
id
);
142
});
143
BEAST_EXPECT(g.
waitFor
(5s));
144
a[i]->join();
145
}
146
for
(
auto
const
& c : a)
147
{
148
c->post();
149
BEAST_EXPECT(g.
waitFor
(5s));
150
c->join();
151
}
152
for
(
auto
const
& c : a)
153
{
154
c->post();
155
c->join();
156
}
157
158
jq.addJob(
JtClient
,
"LocalValTest"
, [&]() {
159
this->BEAST_EXPECT(*lv == -2);
160
g.
signal
();
161
});
162
BEAST_EXPECT(g.
waitFor
(5s));
163
BEAST_EXPECT(*lv == -1);
164
}
165
166
void
167
run
()
override
168
{
169
correctOrder
();
170
incorrectOrder
();
171
threadSpecificStorage
();
172
}
173
};
174
175
BEAST_DEFINE_TESTSUITE
(Coroutine, core,
xrpl
);
176
177
}
// namespace xrpl::test
array
chrono
beast::unit_test::Suite
A testsuite class.
Definition
suite.h:52
beast::unit_test::Suite::testcase
TestcaseT testcase
Memberspace for declaring test cases.
Definition
suite.h:155
xrpl::LocalValue
Definition
LocalValue.h:66
xrpl::ServiceRegistry::getJobQueue
virtual JobQueue & getJobQueue()=0
xrpl::test::Coroutine_test::Gate
Definition
Coroutine_test.cpp:24
xrpl::test::Coroutine_test::Gate::mutex_
std::mutex mutex_
Definition
Coroutine_test.cpp:27
xrpl::test::Coroutine_test::Gate::signal
void signal()
Definition
Coroutine_test.cpp:44
xrpl::test::Coroutine_test::Gate::waitFor
bool waitFor(std::chrono::duration< Rep, Period > const &relTime)
Definition
Coroutine_test.cpp:35
xrpl::test::Coroutine_test::Gate::signaled_
bool signaled_
Definition
Coroutine_test.cpp:28
xrpl::test::Coroutine_test::Gate::cv_
std::condition_variable cv_
Definition
Coroutine_test.cpp:26
xrpl::test::Coroutine_test
Definition
Coroutine_test.cpp:21
xrpl::test::Coroutine_test::threadSpecificStorage
void threadSpecificStorage()
Definition
Coroutine_test.cpp:102
xrpl::test::Coroutine_test::correctOrder
void correctOrder()
Definition
Coroutine_test.cpp:53
xrpl::test::Coroutine_test::incorrectOrder
void incorrectOrder()
Definition
Coroutine_test.cpp:80
xrpl::test::Coroutine_test::run
void run() override
Runs the suite.
Definition
Coroutine_test.cpp:167
xrpl::test::jtx::Env
A transaction testing environment.
Definition
Env.h:161
xrpl::test::jtx::Env::app
Application & app()
Definition
Env.h:300
condition_variable
std::chrono::duration
memory
mutex
xrpl::test::jtx
Definition
Oracle_test.cpp:34
xrpl::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition
envconfig.h:38
xrpl::test
Definition
STLedgerEntry.h:21
xrpl::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::JtClient
@ JtClient
Definition
Job.h:31
std::scoped_lock
std::shared_ptr
std::unique_lock
std::unique_ptr
Generated by
1.17.0