rippled
Loading...
Searching...
No Matches
Coroutine_test.cpp
1#include <test/jtx.h>
2
3#include <xrpld/core/JobQueue.h>
4
5#include <chrono>
6#include <mutex>
7
8namespace ripple {
9namespace test {
10
12{
13public:
14 class gate
15 {
16 private:
19 bool signaled_ = false;
20
21 public:
22 // Thread safe, blocks until signaled or period expires.
23 // Returns `true` if signaled.
24 template <class Rep, class Period>
25 bool
27 {
29 auto b = cv_.wait_for(lk, rel_time, [this] { return signaled_; });
30 signaled_ = false;
31 return b;
32 }
33
34 void
36 {
38 signaled_ = true;
40 }
41 };
42
43 void
45 {
46 using namespace std::chrono_literals;
47 using namespace jtx;
48
49 testcase("correct order");
50
51 Env env(*this, envconfig([](std::unique_ptr<Config> cfg) {
52 cfg->FORCE_MULTI_THREAD = true;
53 return cfg;
54 }));
55
56 gate g1, g2;
58 env.app().getJobQueue().postCoro(
59 jtCLIENT, "Coroutine-Test", [&](auto const& cr) {
60 c = cr;
61 g1.signal();
62 c->yield();
63 g2.signal();
64 });
65 BEAST_EXPECT(g1.wait_for(5s));
66 c->join();
67 c->post();
68 BEAST_EXPECT(g2.wait_for(5s));
69 }
70
71 void
73 {
74 using namespace std::chrono_literals;
75 using namespace jtx;
76
77 testcase("incorrect order");
78
79 Env env(*this, envconfig([](std::unique_ptr<Config> cfg) {
80 cfg->FORCE_MULTI_THREAD = true;
81 return cfg;
82 }));
83
84 gate g;
85 env.app().getJobQueue().postCoro(
86 jtCLIENT, "Coroutine-Test", [&](auto const& c) {
87 c->post();
88 c->yield();
89 g.signal();
90 });
91 BEAST_EXPECT(g.wait_for(5s));
92 }
93
94 void
96 {
97 using namespace std::chrono_literals;
98 using namespace jtx;
99
100 testcase("thread specific storage");
101 Env env(*this);
102
103 auto& jq = env.app().getJobQueue();
104
105 static int const N = 4;
107
108 LocalValue<int> lv(-1);
109 BEAST_EXPECT(*lv == -1);
110
111 gate g;
112 jq.addJob(jtCLIENT, "LocalValue-Test", [&]() {
113 this->BEAST_EXPECT(*lv == -1);
114 *lv = -2;
115 this->BEAST_EXPECT(*lv == -2);
116 g.signal();
117 });
118 BEAST_EXPECT(g.wait_for(5s));
119 BEAST_EXPECT(*lv == -1);
120
121 for (int i = 0; i < N; ++i)
122 {
123 jq.postCoro(jtCLIENT, "Coroutine-Test", [&, id = i](auto const& c) {
124 a[id] = c;
125 g.signal();
126 c->yield();
127
128 this->BEAST_EXPECT(*lv == -1);
129 *lv = id;
130 this->BEAST_EXPECT(*lv == id);
131 g.signal();
132 c->yield();
133
134 this->BEAST_EXPECT(*lv == id);
135 });
136 BEAST_EXPECT(g.wait_for(5s));
137 a[i]->join();
138 }
139 for (auto const& c : a)
140 {
141 c->post();
142 BEAST_EXPECT(g.wait_for(5s));
143 c->join();
144 }
145 for (auto const& c : a)
146 {
147 c->post();
148 c->join();
149 }
150
151 jq.addJob(jtCLIENT, "LocalValue-Test", [&]() {
152 this->BEAST_EXPECT(*lv == -2);
153 g.signal();
154 });
155 BEAST_EXPECT(g.wait_for(5s));
156 BEAST_EXPECT(*lv == -1);
157 }
158
159 void
160 run() override
161 {
165 }
166};
167
168BEAST_DEFINE_TESTSUITE(Coroutine, core, ripple);
169
170} // namespace test
171} // namespace ripple
A testsuite class.
Definition suite.h:52
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:152
virtual JobQueue & getJobQueue()=0
std::shared_ptr< Coro > postCoro(JobType t, std::string const &name, F &&f)
Creates a coroutine and adds a job to the queue which will run it.
Definition JobQueue.h:394
bool wait_for(std::chrono::duration< Rep, Period > const &rel_time)
void run() override
Runs the suite.
A transaction testing environment.
Definition Env.h:102
Application & app()
Definition Env.h:242
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition envconfig.h:35
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
@ jtCLIENT
Definition Job.h:26