libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
coroutine_task_channel_test.cpp
Go to the documentation of this file.
1// Copyright 2025 owent
2
6#include <libcotask/task.h>
7
8#include <cstdio>
9#include <cstring>
10#include <iostream>
11#include <memory>
12#include <set>
13#include <vector>
14
15#include "frame/test_macros.h"
16
17#ifdef LIBCOTASK_MACRO_ENABLED
18static int g_test_coroutine_task_channel_status = 0;
19static int g_test_coroutine_task_channel_on_finished = 0;
20class test_context_task_channel_action : public cotask::impl::task_action_impl {
21 public:
22 test_context_task_channel_action(bool transform_error = false) : last_value(0), transform_error_(transform_error) {}
23
24 copp::stackful_channel_receiver<int> create_channel() {
25 auto ret = copp::make_stackful_channel<int>();
26 sender = copp::memory::make_strong_rc<copp::stackful_channel_sender<int>>(ret.second);
27 return std::move(ret.first);
28 }
29
30 int operator()(void *priv_data) override {
31 ++g_test_coroutine_task_channel_status;
32
33 CASE_EXPECT_EQ(&g_test_coroutine_task_channel_status, priv_data);
34
35 if (transform_error_) {
36 last_value =
37 cotask::task<>::this_task()->await_value(create_channel(), [](copp::copp_error_code) { return -17; });
38 } else {
39 last_value = cotask::task<>::this_task()->await_value(create_channel());
40 }
41
42 ++g_test_coroutine_task_channel_status;
43
44 return 0;
45 }
46
47 int on_finished(cotask::impl::task_impl &) override {
48 ++g_test_coroutine_task_channel_on_finished;
49 return 0;
50 }
51
52 copp::memory::strong_rc_ptr<copp::stackful_channel_sender<int>> sender;
53 int last_value;
54 bool transform_error_;
55};
56
57CASE_TEST(coroutine_task_channel, basic_int_channel) {
58 typedef cotask::task<>::ptr_t task_ptr_type;
59 g_test_coroutine_task_channel_status = 0;
60 g_test_coroutine_task_channel_on_finished = 0;
61
62 {
63 task_ptr_type co_task = cotask::task<>::create(test_context_task_channel_action());
64 task_ptr_type co_another_task = cotask::task<>::create(test_context_task_channel_action(true));
65
66 CASE_EXPECT_EQ(cotask::EN_TS_CREATED, co_task->get_status());
67 CASE_EXPECT_EQ(cotask::EN_TS_CREATED, co_another_task->get_status());
68
69 CASE_EXPECT_EQ(0, co_task->start(&g_test_coroutine_task_channel_status));
70
71 CASE_EXPECT_EQ(g_test_coroutine_task_channel_status, 1);
72 CASE_EXPECT_FALSE(co_task->is_completed());
73 CASE_EXPECT_FALSE(co_task->is_canceled());
74 CASE_EXPECT_FALSE(co_task->is_faulted());
75
76 CASE_EXPECT_EQ(0, co_another_task->start(&g_test_coroutine_task_channel_status));
77 CASE_EXPECT_EQ(g_test_coroutine_task_channel_status, 2);
78
79 CASE_EXPECT_EQ(cotask::EN_TS_WAITING, co_task->get_status());
80 CASE_EXPECT_EQ(cotask::EN_TS_WAITING, co_another_task->get_status());
81
82 static_cast<test_context_task_channel_action *>(co_task->get_raw_action())->sender->set_value(357);
83 CASE_EXPECT_EQ(g_test_coroutine_task_channel_status, 3);
84 CASE_EXPECT_EQ(static_cast<test_context_task_channel_action *>(co_task->get_raw_action())->last_value, 357);
85
86 static_cast<test_context_task_channel_action *>(co_another_task->get_raw_action())->sender->reset_value();
87 static_cast<test_context_task_channel_action *>(co_another_task->get_raw_action())->sender->set_value(579);
88 CASE_EXPECT_EQ(g_test_coroutine_task_channel_status, 4);
89 CASE_EXPECT_EQ(static_cast<test_context_task_channel_action *>(co_another_task->get_raw_action())->last_value, 579);
90
91 CASE_EXPECT_TRUE(co_task->is_completed());
92 CASE_EXPECT_TRUE(co_another_task->is_completed());
93 CASE_EXPECT_FALSE(co_task->is_canceled());
94 CASE_EXPECT_FALSE(co_task->is_faulted());
95
96 CASE_EXPECT_EQ(co_task->get_status(), cotask::EN_TS_DONE);
97 CASE_EXPECT_EQ(co_another_task->get_status(), cotask::EN_TS_DONE);
98 }
99
100 CASE_EXPECT_EQ(g_test_coroutine_task_channel_on_finished, 2);
101}
102
103CASE_TEST(coroutine_task_channel, transform_error_for_int_channel) {
104 typedef cotask::task<>::ptr_t task_ptr_type;
105 g_test_coroutine_task_channel_status = 0;
106 g_test_coroutine_task_channel_on_finished = 0;
107
108 {
109 task_ptr_type co_task = cotask::task<>::create(test_context_task_channel_action());
110 task_ptr_type co_another_task = cotask::task<>::create(test_context_task_channel_action(true));
111
112 CASE_EXPECT_EQ(cotask::EN_TS_CREATED, co_task->get_status());
113 CASE_EXPECT_EQ(cotask::EN_TS_CREATED, co_another_task->get_status());
114
115 CASE_EXPECT_EQ(0, co_task->start(&g_test_coroutine_task_channel_status));
116
117 CASE_EXPECT_EQ(g_test_coroutine_task_channel_status, 1);
118 CASE_EXPECT_FALSE(co_task->is_completed());
119 CASE_EXPECT_FALSE(co_task->is_canceled());
120 CASE_EXPECT_FALSE(co_task->is_faulted());
121
122 CASE_EXPECT_EQ(0, co_another_task->start(&g_test_coroutine_task_channel_status));
123 CASE_EXPECT_EQ(g_test_coroutine_task_channel_status, 2);
124
125 CASE_EXPECT_EQ(cotask::EN_TS_WAITING, co_task->get_status());
126 CASE_EXPECT_EQ(cotask::EN_TS_WAITING, co_another_task->get_status());
127
128 co_task->kill();
129 CASE_EXPECT_EQ(g_test_coroutine_task_channel_status, 3);
130 CASE_EXPECT_EQ(static_cast<test_context_task_channel_action *>(co_task->get_raw_action())->last_value,
131 copp::COPP_EC_OPERATION_CANCLE);
132
133 static_cast<test_context_task_channel_action *>(co_another_task->get_raw_action())->sender->reset_value();
134 co_another_task->kill();
135
136 CASE_EXPECT_EQ(g_test_coroutine_task_channel_status, 4);
137 CASE_EXPECT_EQ(static_cast<test_context_task_channel_action *>(co_another_task->get_raw_action())->last_value, -17);
138
139 CASE_EXPECT_TRUE(co_task->is_completed());
140 CASE_EXPECT_TRUE(co_another_task->is_completed());
141 CASE_EXPECT_FALSE(co_task->is_canceled());
142 CASE_EXPECT_TRUE(co_task->is_faulted());
143
144 CASE_EXPECT_EQ(co_task->get_status(), cotask::EN_TS_KILLED);
145 CASE_EXPECT_EQ(co_another_task->get_status(), cotask::EN_TS_KILLED);
146 }
147
148 CASE_EXPECT_EQ(g_test_coroutine_task_channel_on_finished, 2);
149}
150
151#endif
my_task_t::ptr_t task_ptr_type
#define CASE_EXPECT_FALSE(c)
Definition test_macros.h:98
#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