libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
coroutine_context_base_test.cpp
Go to the documentation of this file.
1// Copyright 2023 owent
2
4
5#include <cstdio>
6#include <cstring>
7#include <iostream>
8
9#include "frame/test_macros.h"
10
11typedef copp::coroutine_context_container<copp::allocator::stack_allocator_memory>
13
15
17 public:
20 int operator()(void *) {
21 ++call_times;
23 copp::this_coroutine::get<test_context_base_coroutine_context_test_type>()->yield();
24
26 return 0;
27 }
28};
29
30CASE_TEST(coroutine, context_base) {
31 unsigned char *stack_buff = new unsigned char[128 * 1024];
35
37 {
38 copp::stack_context test_move_alloc;
39
40 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
41 copp::allocator::stack_allocator_memory alloc(alloc_created);
42
43 alloc_created.allocate(test_move_alloc, 64 * 1024);
44 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
45
46 test_context_base_coroutine_context_test_type::ptr_t co =
47 test_context_base_coroutine_context_test_type::create(&runner, alloc);
48 runner.call_times = 0;
49
50 CASE_EXPECT_TRUE(!!co);
51
52 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_RUNNING, co->yield());
53
54 co->start();
55
58 co->resume();
59
62
63 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
64 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
65 }
66
67 {
69 copp::stack_context test_move_alloc;
70
71 copp::allocator::stack_allocator_memory alloc_created;
72 alloc_created.attach(stack_buff, 128 * 1024);
73 copp::allocator::stack_allocator_memory alloc;
74 alloc = alloc_created;
75
76 alloc_created.allocate(test_move_alloc, 64 * 1024);
77 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
78
79 test_context_base_coroutine_context_test_type::ptr_t co =
80 test_context_base_coroutine_context_test_type::create(&runner, alloc);
81 runner.call_times = 0;
82
83 CASE_EXPECT_TRUE(!!co);
84
85 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_RUNNING, co->yield());
86
87 co->start();
88
91 co->resume();
92
95
96 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_READY, co->resume());
97 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_ALREADY_EXIST, co->yield());
98 }
99
100 delete[] stack_buff;
101}
102
103CASE_TEST(coroutine, shared_runner) {
104 const int stack_len = 128 * 1024;
105 unsigned char *stack_buff = new unsigned char[4 * stack_len];
109
111 runner.call_times = 0;
112
113 {
114 test_context_base_coroutine_context_test_type::ptr_t co[4];
115 for (int i = 0; i < 4; ++i) {
116 copp::allocator::stack_allocator_memory alloc(stack_buff + i * stack_len, stack_len);
117 co[i] = test_context_base_coroutine_context_test_type::create(&runner, alloc);
118 co[i]->start();
119 }
120
122
123 for (int i = 0; i < 4; ++i) {
124 co[i]->resume();
125 }
126
128
129 CASE_EXPECT_EQ(runner.call_times, 4);
130 }
131
132 delete[] stack_buff;
133}
134
135CASE_TEST(coroutine, coroutine_context_container_create_failed) {
136 unsigned char *stack_buff = new unsigned char[128 * 1024];
137
139 {
140 copp::stack_context test_move_alloc;
141
142 copp::allocator::stack_allocator_memory alloc_created(stack_buff, 128 * 1024);
143 copp::allocator::stack_allocator_memory alloc(alloc_created);
144
145 alloc_created.allocate(test_move_alloc, 64 * 1024);
146 CASE_EXPECT_EQ(nullptr, test_move_alloc.sp);
147
148 test_context_base_coroutine_context_test_type::ptr_t co =
149 test_context_base_coroutine_context_test_type::create(&runner, alloc, 32 * 1024, 16 * 1024, 16 * 1024);
150 CASE_EXPECT_TRUE(!co);
151 }
152
153 delete[] stack_buff;
154}
155
156CASE_TEST(coroutine, coroutine_context_create_failed) {
157 unsigned char *stack_buff = new unsigned char[128 * 1024];
158
159 copp::coroutine_context *placement_new_addr = reinterpret_cast<copp::coroutine_context *>(stack_buff + 112 * 1024);
161 {
162 copp::stack_context callee_stack;
163 callee_stack.sp = reinterpret_cast<void *>(stack_buff + 120 * 1024);
164 callee_stack.size = 120 * 1024;
165
166 CASE_EXPECT_EQ(copp::COPP_EC_ARGS_ERROR,
167 copp::coroutine_context::create(nullptr, std::move(runner), callee_stack, 4096, 4096));
168 }
169
170 {
171 copp::stack_context callee_stack;
172 callee_stack.sp = reinterpret_cast<void *>(stack_buff + 120 * 1024);
173 callee_stack.size = 120 * 1024;
174
175 CASE_EXPECT_EQ(copp::COPP_EC_ARGS_ERROR,
176 copp::coroutine_context::create(placement_new_addr, std::move(runner), callee_stack, 4096, 4095));
177 }
178
179 {
180 copp::stack_context callee_stack;
181 callee_stack.sp = reinterpret_cast<void *>(stack_buff + 120 * 1024);
182 callee_stack.size = 120 * 1024;
183
184 CASE_EXPECT_EQ(copp::COPP_EC_ARGS_ERROR,
185 copp::coroutine_context::create(placement_new_addr, std::move(runner), callee_stack, 4095, 4096));
186 }
187
188 {
189 copp::stack_context callee_stack;
190 callee_stack.sp = nullptr;
191 callee_stack.size = 120 * 1024;
192
193 CASE_EXPECT_EQ(copp::COPP_EC_ARGS_ERROR,
194 copp::coroutine_context::create(placement_new_addr, std::move(runner), callee_stack, 4096, 4096));
195 }
196
197 {
198 copp::stack_context callee_stack;
199 callee_stack.sp = reinterpret_cast<void *>(stack_buff + 120 * 1024);
200 callee_stack.size = 8192;
201
202 CASE_EXPECT_EQ(copp::COPP_EC_ARGS_ERROR,
203 copp::coroutine_context::create(placement_new_addr, std::move(runner), callee_stack, 4096, 4096));
204 }
205
206 {
207 copp::stack_context callee_stack;
208 callee_stack.sp = reinterpret_cast<void *>(stack_buff + 120 * 1024);
209 callee_stack.size = 120 * 1024;
210
211 copp::coroutine_context *placement_invalid_addr =
212 reinterpret_cast<copp::coroutine_context *>(stack_buff + 116 * 1024);
213 CASE_EXPECT_EQ(copp::COPP_EC_ARGS_ERROR, copp::coroutine_context::create(placement_invalid_addr, std::move(runner),
214 callee_stack, 4096, 4096));
215 }
216
217 delete[] stack_buff;
218}
219
220#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
221static int test_context_base_foo_runner_throw_exception(void *) { return static_cast<int>(std::string().at(1)); }
222
223CASE_TEST(coroutine, coroutine_context_throw_exception) {
224 unsigned char *stack_buff = new unsigned char[128 * 1024];
225
226 try {
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_base_coroutine_context_test_type::ptr_t co =
236 test_context_base_coroutine_context_test_type::create(test_context_base_foo_runner_throw_exception, alloc);
237
238 CASE_EXPECT_TRUE(!!co);
239
240 CASE_EXPECT_EQ(LIBCOPP_COPP_NAMESPACE_ID::COPP_EC_NOT_RUNNING, co->yield());
241
242 co->start();
243 } catch (const std::exception &e) {
244 CASE_MSG_INFO() << "Caught exception \"" << e.what() << "\"" << std::endl;
245 }
246
247 delete[] stack_buff;
248}
249
250#endif
static int g_test_coroutine_base_status
copp::coroutine_context_container< copp::allocator::stack_allocator_memory > test_context_base_coroutine_context_test_type
#define CASE_MSG_INFO()
#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