libcopp  2.2.0
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 
11 typedef 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 
30 CASE_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 
53 
54  co->start();
55 
58  co->resume();
59 
62 
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 
86 
87  co->start();
88 
91  co->resume();
92 
95 
98  }
99 
100  delete[] stack_buff;
101 }
102 
103 CASE_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 
135 CASE_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 
156 CASE_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 
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 
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 
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 
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 
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
221 static int test_context_base_foo_runner_throw_exception(void *) { return static_cast<int>(std::string().at(1)); }
222 
223 CASE_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 
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
CASE_TEST(coroutine, context_base)
static int g_test_coroutine_base_status
copp::coroutine_context_container< copp::allocator::stack_allocator_memory > test_context_base_coroutine_context_test_type
@ COPP_EC_NOT_READY
COPP_EC_NOT_READY.
Definition: errno.h:24
@ COPP_EC_ALREADY_EXIST
COPP_EC_ALREADY_EXIST.
Definition: errno.h:29
@ COPP_EC_ARGS_ERROR
COPP_EC_ARGS_ERROR.
Definition: errno.h:30
@ COPP_EC_NOT_RUNNING
COPP_EC_NOT_RUNNING.
Definition: errno.h:25
#define CASE_MSG_INFO()
Definition: test_macros.h:114
#define CASE_EXPECT_EQ(l, r)
Definition: test_macros.h:96
#define CASE_EXPECT_TRUE(c)
Definition: test_macros.h:94