]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | // Copyright Oliver Kowalke 2013. | |
3 | // Distributed under the Boost Software License, Version 1.0. | |
4 | // (See accompanying file LICENSE_1_0.txt or copy at | |
5 | // http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | #include <chrono> | |
8 | #include <sstream> | |
9 | #include <string> | |
10 | ||
11 | #include <boost/assert.hpp> | |
12 | #include <boost/test/unit_test.hpp> | |
13 | ||
14 | #include <boost/fiber/all.hpp> | |
15 | ||
16 | struct moveable { | |
17 | bool state; | |
18 | int value; | |
19 | ||
20 | moveable() : | |
21 | state( false), | |
22 | value( -1) { | |
23 | } | |
24 | ||
25 | moveable( int v) : | |
26 | state( true), | |
27 | value( v) { | |
28 | } | |
29 | ||
30 | moveable( moveable && other) : | |
31 | state( other.state), | |
32 | value( other.value) { | |
33 | other.state = false; | |
34 | other.value = -1; | |
35 | } | |
36 | ||
37 | moveable & operator=( moveable && other) { | |
38 | if ( this == & other) return * this; | |
39 | state = other.state; | |
40 | other.state = false; | |
41 | value = other.value; | |
42 | other.value = -1; | |
43 | return * this; | |
44 | } | |
45 | }; | |
46 | ||
47 | void test_push() { | |
48 | boost::fibers::unbounded_channel< int > c; | |
49 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) ); | |
50 | } | |
51 | ||
52 | void test_push_closed() { | |
53 | boost::fibers::unbounded_channel< int > c; | |
54 | c.close(); | |
55 | BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push( 1) ); | |
56 | } | |
57 | ||
58 | void test_pop() { | |
59 | boost::fibers::unbounded_channel< int > c; | |
60 | int v1 = 2, v2 = 0; | |
61 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
62 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) ); | |
63 | BOOST_CHECK_EQUAL( v1, v2); | |
64 | } | |
65 | ||
66 | void test_pop_closed() { | |
67 | boost::fibers::unbounded_channel< int > c; | |
68 | int v1 = 2, v2 = 0; | |
69 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
70 | c.close(); | |
71 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) ); | |
72 | BOOST_CHECK_EQUAL( v1, v2); | |
73 | BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop( v2) ); | |
74 | } | |
75 | ||
76 | void test_pop_success() { | |
77 | boost::fibers::unbounded_channel< int > c; | |
78 | int v1 = 2, v2 = 0; | |
79 | boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){ | |
80 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) ); | |
81 | }); | |
82 | boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){ | |
83 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
84 | }); | |
85 | f1.join(); | |
86 | f2.join(); | |
87 | BOOST_CHECK_EQUAL( v1, v2); | |
88 | } | |
89 | ||
90 | void test_value_pop() { | |
91 | boost::fibers::unbounded_channel< int > c; | |
92 | int v1 = 2, v2 = 0; | |
93 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
94 | v2 = c.value_pop(); | |
95 | BOOST_CHECK_EQUAL( v1, v2); | |
96 | } | |
97 | ||
98 | void test_value_pop_closed() { | |
99 | boost::fibers::unbounded_channel< int > c; | |
100 | int v1 = 2, v2 = 0; | |
101 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
102 | c.close(); | |
103 | v2 = c.value_pop(); | |
104 | BOOST_CHECK_EQUAL( v1, v2); | |
105 | bool thrown = false; | |
106 | try { | |
107 | c.value_pop(); | |
108 | } catch ( boost::fibers::fiber_error const&) { | |
109 | thrown = true; | |
110 | } | |
111 | BOOST_CHECK( thrown); | |
112 | } | |
113 | ||
114 | void test_value_pop_success() { | |
115 | boost::fibers::unbounded_channel< int > c; | |
116 | int v1 = 2, v2 = 0; | |
117 | boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){ | |
118 | v2 = c.value_pop(); | |
119 | }); | |
120 | boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){ | |
121 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
122 | }); | |
123 | f1.join(); | |
124 | f2.join(); | |
125 | BOOST_CHECK_EQUAL( v1, v2); | |
126 | } | |
127 | ||
128 | void test_try_pop() { | |
129 | boost::fibers::unbounded_channel< int > c; | |
130 | int v1 = 2, v2 = 0; | |
131 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
132 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.try_pop( v2) ); | |
133 | BOOST_CHECK_EQUAL( v1, v2); | |
134 | } | |
135 | ||
136 | void test_try_pop_closed() { | |
137 | boost::fibers::unbounded_channel< int > c; | |
138 | int v1 = 2, v2 = 0; | |
139 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
140 | c.close(); | |
141 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.try_pop( v2) ); | |
142 | BOOST_CHECK_EQUAL( v1, v2); | |
143 | BOOST_CHECK( boost::fibers::channel_op_status::closed == c.try_pop( v2) ); | |
144 | } | |
145 | ||
146 | void test_try_pop_success() { | |
147 | boost::fibers::unbounded_channel< int > c; | |
148 | int v1 = 2, v2 = 0; | |
149 | boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){ | |
150 | while ( boost::fibers::channel_op_status::success != c.try_pop( v2) ); | |
151 | }); | |
152 | boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){ | |
153 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
154 | }); | |
155 | f1.join(); | |
156 | f2.join(); | |
157 | BOOST_CHECK_EQUAL( v1, v2); | |
158 | } | |
159 | ||
160 | void test_pop_wait_for() { | |
161 | boost::fibers::unbounded_channel< int > c; | |
162 | int v1 = 2, v2 = 0; | |
163 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
164 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) ); | |
165 | BOOST_CHECK_EQUAL( v1, v2); | |
166 | } | |
167 | ||
168 | void test_pop_wait_for_closed() { | |
169 | boost::fibers::unbounded_channel< int > c; | |
170 | int v1 = 2, v2 = 0; | |
171 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
172 | c.close(); | |
173 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) ); | |
174 | BOOST_CHECK_EQUAL( v1, v2); | |
175 | BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop_wait_for( v2, std::chrono::seconds( 1) ) ); | |
176 | } | |
177 | ||
178 | void test_pop_wait_for_success() { | |
179 | boost::fibers::unbounded_channel< int > c; | |
180 | int v1 = 2, v2 = 0; | |
181 | boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){ | |
182 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) ); | |
183 | }); | |
184 | boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){ | |
185 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
186 | }); | |
187 | f1.join(); | |
188 | f2.join(); | |
189 | BOOST_CHECK_EQUAL( v1, v2); | |
190 | } | |
191 | ||
192 | void test_pop_wait_for_timeout() { | |
193 | boost::fibers::unbounded_channel< int > c; | |
194 | int v = 0; | |
195 | boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v](){ | |
196 | BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.pop_wait_for( v, std::chrono::seconds( 1) ) ); | |
197 | }); | |
198 | f.join(); | |
199 | } | |
200 | ||
201 | void test_pop_wait_until() { | |
202 | boost::fibers::unbounded_channel< int > c; | |
203 | int v1 = 2, v2 = 0; | |
204 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
205 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2, | |
206 | std::chrono::system_clock::now() + std::chrono::seconds( 1) ) ); | |
207 | BOOST_CHECK_EQUAL( v1, v2); | |
208 | } | |
209 | ||
210 | void test_pop_wait_until_closed() { | |
211 | boost::fibers::unbounded_channel< int > c; | |
212 | int v1 = 2, v2 = 0; | |
213 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
214 | c.close(); | |
215 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2, | |
216 | std::chrono::system_clock::now() + std::chrono::seconds( 1) ) ); | |
217 | BOOST_CHECK_EQUAL( v1, v2); | |
218 | BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop_wait_until( v2, | |
219 | std::chrono::system_clock::now() + std::chrono::seconds( 1) ) ); | |
220 | } | |
221 | ||
222 | void test_pop_wait_until_success() { | |
223 | boost::fibers::unbounded_channel< int > c; | |
224 | int v1 = 2, v2 = 0; | |
225 | boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){ | |
226 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2, | |
227 | std::chrono::system_clock::now() + std::chrono::seconds( 1) ) ); | |
228 | }); | |
229 | boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){ | |
230 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) ); | |
231 | }); | |
232 | f1.join(); | |
233 | f2.join(); | |
234 | BOOST_CHECK_EQUAL( v1, v2); | |
235 | } | |
236 | ||
237 | void test_pop_wait_until_timeout() { | |
238 | boost::fibers::unbounded_channel< int > c; | |
239 | int v = 0; | |
240 | boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v](){ | |
241 | BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.pop_wait_until( v, | |
242 | std::chrono::system_clock::now() + std::chrono::seconds( 1) ) ); | |
243 | }); | |
244 | f.join(); | |
245 | } | |
246 | ||
247 | void test_moveable() { | |
248 | boost::fibers::unbounded_channel< moveable > c; | |
249 | moveable m1( 3), m2; | |
250 | BOOST_CHECK( m1.state); | |
251 | BOOST_CHECK_EQUAL( 3, m1.value); | |
252 | BOOST_CHECK( ! m2.state); | |
253 | BOOST_CHECK_EQUAL( -1, m2.value); | |
254 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( std::move( m1) ) ); | |
255 | BOOST_CHECK( ! m1.state); | |
256 | BOOST_CHECK( ! m2.state); | |
257 | BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( m2) ); | |
258 | BOOST_CHECK( ! m1.state); | |
259 | BOOST_CHECK_EQUAL( -1, m1.value); | |
260 | BOOST_CHECK( m2.state); | |
261 | BOOST_CHECK_EQUAL( 3, m2.value); | |
262 | } | |
263 | ||
264 | boost::unit_test::test_suite * init_unit_test_suite( int, char* []) { | |
265 | boost::unit_test::test_suite * test = | |
266 | BOOST_TEST_SUITE("Boost.Fiber: unbounded_channel test suite"); | |
267 | ||
268 | test->add( BOOST_TEST_CASE( & test_push) ); | |
269 | test->add( BOOST_TEST_CASE( & test_push_closed) ); | |
270 | test->add( BOOST_TEST_CASE( & test_pop) ); | |
271 | test->add( BOOST_TEST_CASE( & test_pop_closed) ); | |
272 | test->add( BOOST_TEST_CASE( & test_pop_success) ); | |
273 | test->add( BOOST_TEST_CASE( & test_value_pop) ); | |
274 | test->add( BOOST_TEST_CASE( & test_value_pop_closed) ); | |
275 | test->add( BOOST_TEST_CASE( & test_value_pop_success) ); | |
276 | test->add( BOOST_TEST_CASE( & test_try_pop) ); | |
277 | test->add( BOOST_TEST_CASE( & test_try_pop_closed) ); | |
278 | test->add( BOOST_TEST_CASE( & test_try_pop_success) ); | |
279 | test->add( BOOST_TEST_CASE( & test_pop_wait_for) ); | |
280 | test->add( BOOST_TEST_CASE( & test_pop_wait_for_closed) ); | |
281 | test->add( BOOST_TEST_CASE( & test_pop_wait_for_success) ); | |
282 | test->add( BOOST_TEST_CASE( & test_pop_wait_for_timeout) ); | |
283 | test->add( BOOST_TEST_CASE( & test_pop_wait_until) ); | |
284 | test->add( BOOST_TEST_CASE( & test_pop_wait_until_closed) ); | |
285 | test->add( BOOST_TEST_CASE( & test_pop_wait_until_success) ); | |
286 | test->add( BOOST_TEST_CASE( & test_pop_wait_until_timeout) ); | |
287 | test->add( BOOST_TEST_CASE( & test_moveable) ); | |
288 | ||
289 | return test; | |
290 | } |