15#include "../testing.hh"
23 auto loop1 = Loop::current();
24 auto loop2 = Loop::current();
25 TCHECK (loop1 == loop2,
"Loop::current() should return the same loop instance");
26 auto loop3 = Loop::current();
27 TCHECK (loop1 == loop3,
"Loop::current() should always return the same instance");
32loop_current_multithread_test()
35 auto main_thread_loop = Loop::current();
40 thread1_loop = Loop::current();
41 TCHECK (thread1_loop !=
nullptr,
"Thread 1 should get a valid loop");
42 auto same = Loop::current();
43 TCHECK (thread1_loop == same,
"Thread 1 should always get the same loop");
48 thread2_loop = Loop::current();
49 TCHECK (thread2_loop !=
nullptr,
"Thread 2 should get a valid loop");
50 auto same = Loop::current();
51 TCHECK (thread2_loop == same,
"Thread 2 should always get the same loop");
58 TCHECK (thread1_ready && thread2_ready,
"Both threads should complete");
59 TCHECK (thread1_loop && thread2_loop,
"Both thread loops should exist");
60 TCHECK (thread1_loop != main_thread_loop,
"Thread 1 loop differs from main");
61 TCHECK (thread2_loop != main_thread_loop,
"Thread 2 loop differs from main");
62 TCHECK (thread1_loop != thread2_loop,
"Each thread gets its own loop");
64TEST_ADD (loop_current_multithread_test);
72 auto loop = Loop::current();
75 loop->add ([&counter] ()
79 }, interval, priority);
81 for (
int i = 0; i < 4; i++) {
83 while (loop->pending())
87 TCHECK (counter == 1,
"add_timer() callback should be called once");
101 auto promise = loop->make_promise ([=] (
std::function<
void()> resolve)
104 loop->add ([=]() { resolve();
return false; });
110 loop->add (coroutine);
112 for (
int i = 0; i < 500 && !*completedp; i++) {
114 while (loop->pending())
115 loop->iterate (
true);
117 TCHECK (*completedp,
"CoTask<void> should complete");
122cotask_int64_result_test()
130 loop->add ([=]() { resolve (42);
return false; });
132 *result =
co_await promise;
136 loop->add (coroutine);
138 for (
int i = 0; i < 500 && *result == 0; i++) {
140 while (loop->pending())
141 loop->iterate (
true);
143 TCHECK (*result == 42,
"CoTask<int64_t> should return 42");
148cotask_string_result_test()
155 loop->add ([=]() { resolve (
std::string {
"hello"});
return false; });
157 *result =
co_await promise;
161 loop->add (coroutine);
163 for (
int i = 0; i < 500 && result->empty(); i++) {
165 while (loop->pending())
166 loop->iterate (
true);
168 TCHECK (*result ==
"hello",
"CoTask<std::string> should return 'hello'");
170TEST_ADD (cotask_string_result_test);
178 auto promise = loop->make_promise ([=] (
std::function<
void()> resolve)
180 loop->add ([=]() { resolve();
return false; });
190 loop->add (coroutine);
192 for (
int i = 0; i < 500 && !*completed; i++) {
194 while (loop->pending())
195 loop->iterate (
true);
197 TCHECK (*completed,
"Promise<void> should resolve");
209 loop->add ([=]() { resolve (123);
return false; });
214 *result =
co_await promise;
218 loop->add (coroutine);
220 for (
int i = 0; i < 500 && *result == 0; i++) {
222 while (loop->pending())
223 loop->iterate (
true);
225 TCHECK (*result == 123,
"Promise<int64_t> should resolve with 123");
237 loop->add ([=]() { resolve (
std::string {
"world"});
return false; });
242 *result =
co_await promise;
246 loop->add (coroutine);
248 for (
int i = 0; i < 500 && result->empty(); i++) {
250 while (loop->pending())
251 loop->iterate (
true);
253 TCHECK (*result ==
"world",
"Promise<std::string> should resolve with 'world'");
258promise_multi_waiter_test()
267 *waiter1_done =
co_await promise;
273 *waiter2_done =
co_await promise;
279 loop->add ([=]() { promise->resolve (99);
return false; });
281 for (
int i = 0; i < 500 && (*waiter1_done == 0 || *waiter2_done == 0); i++) {
283 while (loop->pending())
284 loop->iterate (
true);
286 TCHECK (*waiter1_done == 99,
"First waiter should get 99");
287 TCHECK (*waiter2_done == 99,
"Second waiter should get 99");
289TEST_ADD (promise_multi_waiter_test);
292promise_exception_test()
309 *caught_exception =
true;
314 loop->add (coroutine);
316 for (
int i = 0; i < 500 && !*caught_exception; i++) {
318 while (loop->pending())
319 loop->iterate (
true);
321 TCHECK (*caught_exception,
"Promise rejection should propagate exception");
326inner_int64_task (
Ase::LoopP loop, int64_t value)
328 auto promise = loop->make_promise<
int64_t> ([loop, value] (
std::function<void(int64_t)> resolve)
330 loop->add ([resolve, value]() { resolve (value * 2);
return false; });
332 co_return co_await promise;
343 auto v1 =
co_await inner_int64_task (loop, 10);
344 TCHECK (v1 == 20,
"Nested CoTask should chain results: 10 -> 20");
345 auto v2 =
co_await inner_int64_task (loop, v1);
350 loop->add (coroutine);
352 for (
int i = 0; i < 500 && *result == 0; i++) {
354 while (loop->pending())
355 loop->iterate (
true);
357 TCHECK (*result == 40,
"Nested CoTask should chain results: 10 -> 20 -> 40");
362promise_already_resolved_test()
374 *result =
co_await promise;
378 loop->add (coroutine);
380 for (
int i = 0; i < 500 && *result == 0; i++) {
382 while (loop->pending())
383 loop->iterate (
true);
385 TCHECK (*result == 77,
"Already-resolved promise should return value immediately");
387TEST_ADD (promise_already_resolved_test);
401 loop->add (coroutine);
403 for (
int i = 0; i < 500 && -1 == *elapsed_ms; i++) {
405 while (loop->pending())
406 loop->iterate (
true);
408 TCHECK (*elapsed_ms >= 0,
"delay promise should resolve");
409 TCHECK (*elapsed_ms >= 50 - 1,
"delay should wait at least 50ms");
410 TCHECK (*elapsed_ms < 1000,
"delay should last less than a second");
static LoopP current()
Return the thread-local singleton loop, created on first call.
T make_exception_ptr(T... args)
The Anklang C++ API namespace.
@ NORMAL
Normal importantance, GUI event processing, RPC.
Like CoTask<Result> without return type.
General purpose coroutine task.
#define TEST_ADD(fun)
Register a function to run as part of the unit test suite.
#define TCHECK(cond,...)
Verbose assertion, calls TPASS() on success./*#end#*/.