libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
coroutine_context_channel_test.cpp
Go to the documentation of this file.
1// Copyright 2025 owent
2
6
7#include <cstdio>
8#include <cstring>
9#include <iostream>
10
11#include "frame/test_macros.h"
12
14 copp::coroutine_context_container<copp::allocator::stack_allocator_memory>;
15
16#if defined(LIBCOPP_MACRO_ENABLE_WIN_FIBER) && LIBCOPP_MACRO_ENABLE_WIN_FIBER
17using test_context_channel_coroutine_context_fiber_test_type =
18 copp::coroutine_context_fiber_container<copp::allocator::stack_allocator_memory>;
19#endif
20
22
23template <class T>
25
26template <>
28 int operator()(copp::copp_error_code err_code) { return static_cast<int>(err_code) - 10000; }
29};
30
31template <>
33 int *operator()(copp::copp_error_code /*err_code*/) { return &g_test_coroutine_channel_status; }
34};
35
36template <class TCTX>
38
39template <>
42 return copp::this_coroutine::get<test_context_channel_coroutine_context_test_type>();
43 }
44};
45
46#if defined(LIBCOPP_MACRO_ENABLE_WIN_FIBER) && LIBCOPP_MACRO_ENABLE_WIN_FIBER
47template <>
48struct test_context_channel_this_coroutine<test_context_channel_coroutine_context_fiber_test_type> {
49 static test_context_channel_coroutine_context_fiber_test_type *get() {
50 return copp::this_fiber::get<test_context_channel_coroutine_context_fiber_test_type>();
51 }
52};
53#endif
54
55template <class TCTX, class T>
57 public:
59
62 copp::memory::strong_rc_ptr<copp::stackful_channel_sender<T>> sender;
64
65 copp::stackful_channel_receiver<T> create_channel() {
66 auto ret = copp::make_stackful_channel<T>();
67 sender = copp::memory::make_strong_rc<copp::stackful_channel_sender<T>>(ret.second);
68 return std::move(ret.first);
69 }
70
85};
86
87CASE_TEST(coroutine_channel, channel_int) {
88 unsigned char *stack_buff = new unsigned char[128 * 1024];
89
91 // Normal
94 {
95 copp::stack_context test_move_alloc;
96
97 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
98 copp::allocator::stack_allocator_memory alloc(alloc_created);
99
100 alloc_created.allocate(test_move_alloc, 64 * 1024);
101 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
102
103 test_context_channel_coroutine_context_test_type::ptr_t co =
104 test_context_channel_coroutine_context_test_type::create(&runner, alloc);
105 runner.call_times = 0;
106
107 CASE_EXPECT_TRUE(!!co);
108
109 co->start();
110
112
113 runner.sender->set_value(137);
114
116 CASE_EXPECT_EQ(runner.last_value, 137);
117
118 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
119 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
120 }
121
122 // auto transform
125 {
126 copp::stack_context test_move_alloc;
127
128 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
129 copp::allocator::stack_allocator_memory alloc(alloc_created);
130
131 alloc_created.allocate(test_move_alloc, 64 * 1024);
132 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
133
134 test_context_channel_coroutine_context_test_type::ptr_t co =
135 test_context_channel_coroutine_context_test_type::create(&runner, alloc);
136 runner.call_times = 0;
137
138 CASE_EXPECT_TRUE(!!co);
139
140 co->start();
141
143
144 co->resume(nullptr);
145
147 CASE_EXPECT_EQ(runner.last_value, copp::COPP_EC_OPERATION_CANCLE);
148
149 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
150 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
151 }
152
153 // custom transform
156 {
157 copp::stack_context test_move_alloc;
158
159 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
160 copp::allocator::stack_allocator_memory alloc(alloc_created);
161
162 alloc_created.allocate(test_move_alloc, 64 * 1024);
163 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
164
165 test_context_channel_coroutine_context_test_type::ptr_t co =
166 test_context_channel_coroutine_context_test_type::create(&runner, alloc);
167 runner.call_times = 0;
168 runner.use_error_transform = true;
169
170 CASE_EXPECT_TRUE(!!co);
171
172 co->start();
173
175
176 co->resume(nullptr);
177
179 CASE_EXPECT_EQ(runner.last_value, copp::COPP_EC_OPERATION_CANCLE - 10000);
180
181 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
182 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
183 }
184
185 delete[] stack_buff;
186}
187
188CASE_TEST(coroutine_channel, channel_pointer) {
189 unsigned char *stack_buff = new unsigned char[128 * 1024];
190
192 // Normal
195 {
196 copp::stack_context test_move_alloc;
197
198 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
199 copp::allocator::stack_allocator_memory alloc(alloc_created);
200
201 alloc_created.allocate(test_move_alloc, 64 * 1024);
202 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
203
204 test_context_channel_coroutine_context_test_type::ptr_t co =
205 test_context_channel_coroutine_context_test_type::create(&runner, alloc);
206 runner.call_times = 0;
207
208 CASE_EXPECT_TRUE(!!co);
209
210 co->start();
211
213
214 runner.sender->set_value(reinterpret_cast<int *>(stack_buff));
215
217 CASE_EXPECT_EQ(runner.last_value, reinterpret_cast<int *>(stack_buff));
218
219 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
220 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
221 }
222
223 // auto transform
226 {
227 copp::stack_context test_move_alloc;
228
229 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
230 copp::allocator::stack_allocator_memory alloc(alloc_created);
231
232 alloc_created.allocate(test_move_alloc, 64 * 1024);
233 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
234
235 test_context_channel_coroutine_context_test_type::ptr_t co =
236 test_context_channel_coroutine_context_test_type::create(&runner, alloc);
237 runner.call_times = 0;
238
239 CASE_EXPECT_TRUE(!!co);
240
241 co->start();
242
244
245 co->resume(nullptr);
246
248 CASE_EXPECT_EQ(runner.last_value, nullptr);
249
250 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
251 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
252 }
253
254 // custom transform
257 {
258 copp::stack_context test_move_alloc;
259
260 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
261 copp::allocator::stack_allocator_memory alloc(alloc_created);
262
263 alloc_created.allocate(test_move_alloc, 64 * 1024);
264 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
265
266 test_context_channel_coroutine_context_test_type::ptr_t co =
267 test_context_channel_coroutine_context_test_type::create(&runner, alloc);
268 runner.call_times = 0;
269 runner.use_error_transform = true;
270
271 CASE_EXPECT_TRUE(!!co);
272
273 co->start();
274
276
277 co->resume(nullptr);
278
281
282 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
283 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
284 }
285
286 delete[] stack_buff;
287}
288
289#if defined(LIBCOPP_MACRO_ENABLE_WIN_FIBER) && LIBCOPP_MACRO_ENABLE_WIN_FIBER
290
291CASE_TEST(coroutine_channel, fiber_channel_int) {
292 unsigned char *stack_buff = new unsigned char[128 * 1024];
293
295 // Normal
298 {
299 copp::stack_context test_move_alloc;
300
301 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
302 copp::allocator::stack_allocator_memory alloc(alloc_created);
303
304 alloc_created.allocate(test_move_alloc, 64 * 1024);
305 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
306
307 test_context_channel_coroutine_context_fiber_test_type::ptr_t co =
308 test_context_channel_coroutine_context_fiber_test_type::create(&runner, alloc);
309 runner.call_times = 0;
310
311 CASE_EXPECT_TRUE(!!co);
312
313 co->start();
314
316
317 runner.sender->set_value(157);
318
320 CASE_EXPECT_EQ(runner.last_value, 157);
321
322 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
323 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
324 }
325
326 // auto transform
329 {
330 copp::stack_context test_move_alloc;
331
332 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
333 copp::allocator::stack_allocator_memory alloc(alloc_created);
334
335 alloc_created.allocate(test_move_alloc, 64 * 1024);
336 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
337
338 test_context_channel_coroutine_context_fiber_test_type::ptr_t co =
339 test_context_channel_coroutine_context_fiber_test_type::create(&runner, alloc);
340 runner.call_times = 0;
341
342 CASE_EXPECT_TRUE(!!co);
343
344 co->start();
345
347
348 co->resume(nullptr);
349
351 CASE_EXPECT_EQ(runner.last_value, copp::COPP_EC_OPERATION_CANCLE);
352
353 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
354 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
355 }
356
357 // custom transform
360 {
361 copp::stack_context test_move_alloc;
362
363 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
364 copp::allocator::stack_allocator_memory alloc(alloc_created);
365
366 alloc_created.allocate(test_move_alloc, 64 * 1024);
367 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
368
369 test_context_channel_coroutine_context_fiber_test_type::ptr_t co =
370 test_context_channel_coroutine_context_fiber_test_type::create(&runner, alloc);
371 runner.call_times = 0;
372 runner.use_error_transform = true;
373
374 CASE_EXPECT_TRUE(!!co);
375
376 co->start();
377
379
380 co->resume(nullptr);
381
383 CASE_EXPECT_EQ(runner.last_value, copp::COPP_EC_OPERATION_CANCLE - 10000);
384
385 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
386 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
387 }
388
389 delete[] stack_buff;
390}
391
392CASE_TEST(coroutine_channel, fiber_channel_pointer) {
393 unsigned char *stack_buff = new unsigned char[128 * 1024];
394
396 // Normal
399 {
400 copp::stack_context test_move_alloc;
401
402 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
403 copp::allocator::stack_allocator_memory alloc(alloc_created);
404
405 alloc_created.allocate(test_move_alloc, 64 * 1024);
406 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
407
408 test_context_channel_coroutine_context_fiber_test_type::ptr_t co =
409 test_context_channel_coroutine_context_fiber_test_type::create(&runner, alloc);
410 runner.call_times = 0;
411
412 CASE_EXPECT_TRUE(!!co);
413
414 co->start();
415
417
418 runner.sender->set_value(reinterpret_cast<int *>(stack_buff));
419
421 CASE_EXPECT_EQ(runner.last_value, reinterpret_cast<int *>(stack_buff));
422
423 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
424 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
425 }
426
427 // auto transform
430 {
431 copp::stack_context test_move_alloc;
432
433 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
434 copp::allocator::stack_allocator_memory alloc(alloc_created);
435
436 alloc_created.allocate(test_move_alloc, 64 * 1024);
437 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
438
439 test_context_channel_coroutine_context_fiber_test_type::ptr_t co =
440 test_context_channel_coroutine_context_fiber_test_type::create(&runner, alloc);
441 runner.call_times = 0;
442
443 CASE_EXPECT_TRUE(!!co);
444
445 co->start();
446
448
449 co->resume(nullptr);
450
452 CASE_EXPECT_EQ(runner.last_value, nullptr);
453
454 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
455 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
456 }
457
458 // custom transform
461 {
462 copp::stack_context test_move_alloc;
463
464 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
465 copp::allocator::stack_allocator_memory alloc(alloc_created);
466
467 alloc_created.allocate(test_move_alloc, 64 * 1024);
468 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
469
470 test_context_channel_coroutine_context_fiber_test_type::ptr_t co =
471 test_context_channel_coroutine_context_fiber_test_type::create(&runner, alloc);
472 runner.call_times = 0;
473 runner.use_error_transform = true;
474
475 CASE_EXPECT_TRUE(!!co);
476
477 co->start();
478
480
481 co->resume(nullptr);
482
485
486 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
487 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
488 }
489
490 delete[] stack_buff;
491}
492#endif
copp::memory::strong_rc_ptr< copp::stackful_channel_sender< T > > sender
copp::stackful_channel_receiver< T > create_channel()
static int g_test_coroutine_channel_status
copp::coroutine_context_container< copp::allocator::stack_allocator_memory > test_context_channel_coroutine_context_test_type
LIBCOPP_COPP_API_HEAD_ONLY Tc * get()
get current coroutine and try to convert type
#define CASE_EXPECT_EQ(l, r)
Definition test_macros.h:99
#define CASE_TEST(test_name, case_name)
Definition test_macros.h:47
#define CASE_EXPECT_TRUE(c)
Definition test_macros.h:97