fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / websocketpp-0.7.0 / test / transport / iostream / connection.cpp
1 /*
2  * Copyright (c) 2014, Peter Thorson. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above copyright
9  *       notice, this list of conditions and the following disclaimer in the
10  *       documentation and/or other materials provided with the distribution.
11  *     * Neither the name of the WebSocket++ Project nor the
12  *       names of its contributors may be used to endorse or promote products
13  *       derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 //#define BOOST_TEST_DYN_LINK
28 #define BOOST_TEST_MODULE transport_iostream_connection
29 #include <boost/test/unit_test.hpp>
30
31 #include <iostream>
32 #include <cstring>
33 #include <string>
34
35 #include <websocketpp/common/memory.hpp>
36
37 #include <websocketpp/error.hpp>
38 #include <websocketpp/transport/iostream/connection.hpp>
39
40 // Policies
41 #include <websocketpp/concurrency/basic.hpp>
42 #include <websocketpp/logger/basic.hpp>
43
44 struct config {
45     typedef websocketpp::concurrency::basic concurrency_type;
46     typedef websocketpp::log::basic<concurrency_type,
47         websocketpp::log::elevel> elog_type;
48     typedef websocketpp::log::basic<concurrency_type,
49         websocketpp::log::alevel> alog_type;
50 };
51
52 typedef websocketpp::transport::iostream::connection<config> iostream_con;
53
54 using websocketpp::transport::iostream::error::make_error_code;
55
56 struct stub_con : public iostream_con {
57     typedef stub_con type;
58     typedef websocketpp::lib::shared_ptr<type> ptr;
59     typedef iostream_con::timer_ptr timer_ptr;
60
61     stub_con(bool is_server, config::alog_type & a, config::elog_type & e)
62         : iostream_con(is_server,a,e)
63         // Set the error to a known code that is unused by the library
64         // This way we can easily confirm that the handler was run at all.
65         , ec(websocketpp::error::make_error_code(websocketpp::error::test))
66         , indef_read_total(0)
67     {}
68
69     /// Get a shared pointer to this component
70     ptr get_shared() {
71         return websocketpp::lib::static_pointer_cast<type>(iostream_con::get_shared());
72     }
73
74     void write(std::string msg) {
75         iostream_con::async_write(
76             msg.data(),
77             msg.size(),
78             websocketpp::lib::bind(
79                 &stub_con::handle_op,
80                 type::get_shared(),
81                 websocketpp::lib::placeholders::_1
82             )
83         );
84     }
85
86     void write(std::vector<websocketpp::transport::buffer> & bufs) {
87         iostream_con::async_write(
88             bufs,
89             websocketpp::lib::bind(
90                 &stub_con::handle_op,
91                 type::get_shared(),
92                 websocketpp::lib::placeholders::_1
93             )
94         );
95     }
96
97     void async_read_at_least(size_t num_bytes, char *buf, size_t len)
98     {
99         iostream_con::async_read_at_least(
100             num_bytes,
101             buf,
102             len,
103             websocketpp::lib::bind(
104                 &stub_con::handle_op,
105                 type::get_shared(),
106                 websocketpp::lib::placeholders::_1
107             )
108         );
109     }
110
111     void handle_op(websocketpp::lib::error_code const & e) {
112         ec = e;
113     }
114
115     void async_read_indef(size_t num_bytes, char *buf, size_t len)
116     {
117         indef_read_size = num_bytes;
118         indef_read_buf = buf;
119         indef_read_len = len;
120
121         indef_read();
122     }
123
124     void indef_read() {
125         iostream_con::async_read_at_least(
126             indef_read_size,
127             indef_read_buf,
128             indef_read_len,
129             websocketpp::lib::bind(
130                 &stub_con::handle_indef,
131                 type::get_shared(),
132                 websocketpp::lib::placeholders::_1,
133                 websocketpp::lib::placeholders::_2
134             )
135         );
136     }
137
138     void handle_indef(websocketpp::lib::error_code const & e, size_t amt_read) {
139         ec = e;
140         indef_read_total += amt_read;
141
142         indef_read();
143     }
144
145     void shutdown() {
146         iostream_con::async_shutdown(
147             websocketpp::lib::bind(
148                 &stub_con::handle_async_shutdown,
149                 type::get_shared(),
150                 websocketpp::lib::placeholders::_1
151             )
152         );
153     }
154
155     void handle_async_shutdown(websocketpp::lib::error_code const & e) {
156         ec = e;
157     }
158
159     websocketpp::lib::error_code ec;
160     size_t indef_read_size;
161     char * indef_read_buf;
162     size_t indef_read_len;
163     size_t indef_read_total;
164 };
165
166 // Stubs
167 config::alog_type alogger;
168 config::elog_type elogger;
169
170 BOOST_AUTO_TEST_CASE( const_methods ) {
171     iostream_con::ptr con(new iostream_con(true,alogger,elogger));
172
173     BOOST_CHECK( !con->is_secure() );
174     BOOST_CHECK_EQUAL( con->get_remote_endpoint(), "iostream transport" );
175 }
176
177 BOOST_AUTO_TEST_CASE( write_before_output_method_set ) {
178     stub_con::ptr con(new stub_con(true,alogger,elogger));
179
180     con->write("foo");
181     BOOST_CHECK( con->ec == make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
182
183     std::vector<websocketpp::transport::buffer> bufs;
184     con->write(bufs);
185     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
186 }
187
188 BOOST_AUTO_TEST_CASE( async_write_ostream ) {
189     stub_con::ptr con(new stub_con(true,alogger,elogger));
190
191     std::stringstream output;
192
193     con->register_ostream(&output);
194
195     con->write("foo");
196
197     BOOST_CHECK( !con->ec );
198     BOOST_CHECK_EQUAL( output.str(), "foo" );
199 }
200
201 websocketpp::lib::error_code write_handler(std::string & o, websocketpp::connection_hdl, char const * buf, size_t len) {
202     o += std::string(buf,len);
203     return websocketpp::lib::error_code();
204 }
205
206 websocketpp::lib::error_code vector_write_handler(std::string & o, websocketpp::connection_hdl, std::vector<websocketpp::transport::buffer> const & bufs) {
207     std::vector<websocketpp::transport::buffer>::const_iterator it;
208     for (it = bufs.begin(); it != bufs.end(); it++) {
209         o += std::string((*it).buf, (*it).len);
210     }
211
212     return websocketpp::lib::error_code();
213 }
214
215 websocketpp::lib::error_code write_handler_error(websocketpp::connection_hdl, char const *, size_t) {
216     return make_error_code(websocketpp::transport::error::general);
217 }
218
219 BOOST_AUTO_TEST_CASE( async_write_handler ) {
220     stub_con::ptr con(new stub_con(true,alogger,elogger));
221     std::string output;
222
223     con->set_write_handler(websocketpp::lib::bind(
224         &write_handler,
225         websocketpp::lib::ref(output),
226         websocketpp::lib::placeholders::_1,
227         websocketpp::lib::placeholders::_2,
228         websocketpp::lib::placeholders::_3
229     ));
230     con->write("foo");
231     BOOST_CHECK( !con->ec );
232     BOOST_CHECK_EQUAL(output, "foo");
233 }
234
235 BOOST_AUTO_TEST_CASE( async_write_handler_error ) {
236     stub_con::ptr con(new stub_con(true,alogger,elogger));
237
238     con->set_write_handler(&write_handler_error);
239     con->write("foo");
240     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::general) );
241 }
242
243 BOOST_AUTO_TEST_CASE( async_write_vector_0_ostream ) {
244     std::stringstream output;
245
246     stub_con::ptr con(new stub_con(true,alogger,elogger));
247     con->register_ostream(&output);
248
249     std::vector<websocketpp::transport::buffer> bufs;
250
251     con->write(bufs);
252
253     BOOST_CHECK( !con->ec );
254     BOOST_CHECK_EQUAL( output.str(), "" );
255 }
256
257 BOOST_AUTO_TEST_CASE( async_write_vector_0_write_handler ) {
258     std::string output;
259
260     stub_con::ptr con(new stub_con(true,alogger,elogger));
261
262     con->set_write_handler(websocketpp::lib::bind(
263         &write_handler,
264         websocketpp::lib::ref(output),
265         websocketpp::lib::placeholders::_1,
266         websocketpp::lib::placeholders::_2,
267         websocketpp::lib::placeholders::_3
268     ));
269
270     std::vector<websocketpp::transport::buffer> bufs;
271
272     con->write(bufs);
273
274     BOOST_CHECK( !con->ec );
275     BOOST_CHECK_EQUAL( output, "" );
276 }
277
278 BOOST_AUTO_TEST_CASE( async_write_vector_1_ostream ) {
279     std::stringstream output;
280
281     stub_con::ptr con(new stub_con(true,alogger,elogger));
282     con->register_ostream(&output);
283
284     std::vector<websocketpp::transport::buffer> bufs;
285
286     std::string foo = "foo";
287
288     bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
289
290     con->write(bufs);
291
292     BOOST_CHECK( !con->ec );
293     BOOST_CHECK_EQUAL( output.str(), "foo" );
294 }
295
296 BOOST_AUTO_TEST_CASE( async_write_vector_1_write_handler ) {
297     std::string output;
298
299     stub_con::ptr con(new stub_con(true,alogger,elogger));
300     con->set_write_handler(websocketpp::lib::bind(
301         &write_handler,
302         websocketpp::lib::ref(output),
303         websocketpp::lib::placeholders::_1,
304         websocketpp::lib::placeholders::_2,
305         websocketpp::lib::placeholders::_3
306     ));
307
308     std::vector<websocketpp::transport::buffer> bufs;
309
310     std::string foo = "foo";
311
312     bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
313
314     con->write(bufs);
315
316     BOOST_CHECK( !con->ec );
317     BOOST_CHECK_EQUAL( output, "foo" );
318 }
319
320 BOOST_AUTO_TEST_CASE( async_write_vector_2_ostream ) {
321     std::stringstream output;
322
323     stub_con::ptr con(new stub_con(true,alogger,elogger));
324     con->register_ostream(&output);
325
326     std::vector<websocketpp::transport::buffer> bufs;
327
328     std::string foo = "foo";
329     std::string bar = "bar";
330
331     bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
332     bufs.push_back(websocketpp::transport::buffer(bar.data(),bar.size()));
333
334     con->write(bufs);
335
336     BOOST_CHECK( !con->ec );
337     BOOST_CHECK_EQUAL( output.str(), "foobar" );
338 }
339
340 BOOST_AUTO_TEST_CASE( async_write_vector_2_write_handler ) {
341     std::string output;
342
343     stub_con::ptr con(new stub_con(true,alogger,elogger));
344     con->set_write_handler(websocketpp::lib::bind(
345         &write_handler,
346         websocketpp::lib::ref(output),
347         websocketpp::lib::placeholders::_1,
348         websocketpp::lib::placeholders::_2,
349         websocketpp::lib::placeholders::_3
350     ));
351
352     std::vector<websocketpp::transport::buffer> bufs;
353
354     std::string foo = "foo";
355     std::string bar = "bar";
356
357     bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
358     bufs.push_back(websocketpp::transport::buffer(bar.data(),bar.size()));
359
360     con->write(bufs);
361
362     BOOST_CHECK( !con->ec );
363     BOOST_CHECK_EQUAL( output, "foobar" );
364 }
365
366 BOOST_AUTO_TEST_CASE( async_write_vector_2_vector_write_handler ) {
367     std::string output;
368
369     stub_con::ptr con(new stub_con(true,alogger,elogger));
370     con->set_vector_write_handler(websocketpp::lib::bind(
371         &vector_write_handler,
372         websocketpp::lib::ref(output),
373         websocketpp::lib::placeholders::_1,
374         websocketpp::lib::placeholders::_2
375     ));
376
377     std::vector<websocketpp::transport::buffer> bufs;
378
379     std::string foo = "foo";
380     std::string bar = "bar";
381
382     bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
383     bufs.push_back(websocketpp::transport::buffer(bar.data(),bar.size()));
384
385     con->write(bufs);
386
387     BOOST_CHECK( !con->ec );
388     BOOST_CHECK_EQUAL( output, "foobar" );
389 }
390
391 BOOST_AUTO_TEST_CASE( async_read_at_least_too_much ) {
392     stub_con::ptr con(new stub_con(true,alogger,elogger));
393
394     char buf[10];
395
396     con->async_read_at_least(11,buf,10);
397     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::iostream::error::invalid_num_bytes) );
398 }
399
400 BOOST_AUTO_TEST_CASE( async_read_at_least_double_read ) {
401     stub_con::ptr con(new stub_con(true,alogger,elogger));
402
403     char buf[10];
404
405     con->async_read_at_least(5,buf,10);
406     con->async_read_at_least(5,buf,10);
407     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::iostream::error::double_read) );
408 }
409
410 BOOST_AUTO_TEST_CASE( async_read_at_least ) {
411     stub_con::ptr con(new stub_con(true,alogger,elogger));
412
413     char buf[10];
414
415     memset(buf,'x',10);
416
417     con->async_read_at_least(5,buf,10);
418     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
419
420     std::stringstream channel;
421     channel << "abcd";
422     channel >> *con;
423     BOOST_CHECK_EQUAL( channel.tellg(), -1 );
424     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
425
426     std::stringstream channel2;
427     channel2 << "e";
428     channel2 >> *con;
429     BOOST_CHECK_EQUAL( channel2.tellg(), -1 );
430     BOOST_CHECK( !con->ec );
431     BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
432
433     std::stringstream channel3;
434     channel3 << "f";
435     channel3 >> *con;
436     BOOST_CHECK_EQUAL( channel3.tellg(), 0 );
437     BOOST_CHECK( !con->ec );
438     BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
439     con->async_read_at_least(1,buf+5,5);
440     channel3 >> *con;
441     BOOST_CHECK_EQUAL( channel3.tellg(), -1 );
442     BOOST_CHECK( !con->ec );
443     BOOST_CHECK_EQUAL( std::string(buf,10), "abcdefxxxx" );
444 }
445
446 BOOST_AUTO_TEST_CASE( async_read_at_least2 ) {
447     stub_con::ptr con(new stub_con(true,alogger,elogger));
448
449     char buf[10];
450
451     memset(buf,'x',10);
452
453     con->async_read_at_least(5,buf,5);
454     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
455
456     std::stringstream channel;
457     channel << "abcdefg";
458     channel >> *con;
459     BOOST_CHECK_EQUAL( channel.tellg(), 5 );
460     BOOST_CHECK( !con->ec );
461     BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
462
463     con->async_read_at_least(1,buf+5,5);
464     channel >> *con;
465     BOOST_CHECK_EQUAL( channel.tellg(), -1 );
466     BOOST_CHECK( !con->ec );
467     BOOST_CHECK_EQUAL( std::string(buf,10), "abcdefgxxx" );
468 }
469
470 void timer_callback_stub(websocketpp::lib::error_code const &) {}
471
472 BOOST_AUTO_TEST_CASE( set_timer ) {
473    stub_con::ptr con(new stub_con(true,alogger,elogger));
474
475     stub_con::timer_ptr tp = con->set_timer(1000,timer_callback_stub);
476
477     BOOST_CHECK( !tp );
478 }
479
480 BOOST_AUTO_TEST_CASE( async_read_at_least_read_some ) {
481     stub_con::ptr con(new stub_con(true,alogger,elogger));
482
483     char buf[10];
484     memset(buf,'x',10);
485
486     con->async_read_at_least(5,buf,5);
487     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
488
489     char input[10] = "abcdefg";
490     BOOST_CHECK_EQUAL(con->read_some(input,5), 5);
491     BOOST_CHECK( !con->ec );
492     BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
493
494     BOOST_CHECK_EQUAL(con->read_some(input+5,2), 0);
495     BOOST_CHECK( !con->ec );
496     BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
497
498     con->async_read_at_least(1,buf+5,5);
499     BOOST_CHECK_EQUAL(con->read_some(input+5,2), 2);
500     BOOST_CHECK( !con->ec );
501     BOOST_CHECK_EQUAL( std::string(buf,10), "abcdefgxxx" );
502 }
503
504 BOOST_AUTO_TEST_CASE( async_read_at_least_read_some_indef ) {
505     stub_con::ptr con(new stub_con(true,alogger,elogger));
506
507     char buf[20];
508     memset(buf,'x',20);
509
510     con->async_read_indef(5,buf,5);
511     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
512
513     // here we expect to return early from read some because the outstanding
514     // read was for 5 bytes and we were called with 10.
515     char input[11] = "aaaaabbbbb";
516     BOOST_CHECK_EQUAL(con->read_some(input,10), 5);
517     BOOST_CHECK( !con->ec );
518     BOOST_CHECK_EQUAL( std::string(buf,10), "aaaaaxxxxx" );
519     BOOST_CHECK_EQUAL( con->indef_read_total, 5 );
520
521     // A subsequent read should read 5 more because the indef read refreshes
522     // itself. The new read will start again at the beginning of the buffer.
523     BOOST_CHECK_EQUAL(con->read_some(input+5,5), 5);
524     BOOST_CHECK( !con->ec );
525     BOOST_CHECK_EQUAL( std::string(buf,10), "bbbbbxxxxx" );
526     BOOST_CHECK_EQUAL( con->indef_read_total, 10 );
527 }
528
529 BOOST_AUTO_TEST_CASE( async_read_at_least_read_all ) {
530     stub_con::ptr con(new stub_con(true,alogger,elogger));
531
532     char buf[20];
533     memset(buf,'x',20);
534
535     con->async_read_indef(5,buf,5);
536     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
537
538     char input[11] = "aaaaabbbbb";
539     BOOST_CHECK_EQUAL(con->read_all(input,10), 10);
540     BOOST_CHECK( !con->ec );
541     BOOST_CHECK_EQUAL( std::string(buf,10), "bbbbbxxxxx" );
542     BOOST_CHECK_EQUAL( con->indef_read_total, 10 );
543 }
544
545 BOOST_AUTO_TEST_CASE( eof_flag ) {
546     stub_con::ptr con(new stub_con(true,alogger,elogger));
547     char buf[10];
548     con->async_read_at_least(5,buf,5);
549     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
550     con->eof();
551     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::eof) );
552 }
553
554 BOOST_AUTO_TEST_CASE( fatal_error_flag ) {
555     stub_con::ptr con(new stub_con(true,alogger,elogger));
556     char buf[10];
557     con->async_read_at_least(5,buf,5);
558     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
559     con->fatal_error();
560     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::pass_through) );
561 }
562
563 BOOST_AUTO_TEST_CASE( shutdown ) {
564     stub_con::ptr con(new stub_con(true,alogger,elogger));
565     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
566     con->shutdown();
567     BOOST_CHECK_EQUAL( con->ec, websocketpp::lib::error_code() );
568 }
569
570 websocketpp::lib::error_code sd_handler(websocketpp::connection_hdl) {
571     return make_error_code(websocketpp::transport::error::general);
572 }
573
574 BOOST_AUTO_TEST_CASE( shutdown_handler ) {
575     stub_con::ptr con(new stub_con(true,alogger,elogger));
576
577     con->set_shutdown_handler(&sd_handler);
578     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
579     con->shutdown();
580     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::general) );
581 }
582
583 BOOST_AUTO_TEST_CASE( shared_pointer_memory_cleanup ) {
584     stub_con::ptr con(new stub_con(true,alogger,elogger));
585
586     BOOST_CHECK_EQUAL(con.use_count(), 1);
587
588     char buf[10];
589     memset(buf,'x',10);
590     con->async_read_at_least(5,buf,5);
591     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
592     BOOST_CHECK_EQUAL(con.use_count(), 2);
593
594     char input[10] = "foo";
595     con->read_some(input,3);
596     BOOST_CHECK_EQUAL(con.use_count(), 2);
597
598     con->read_some(input,2);
599     BOOST_CHECK_EQUAL( std::string(buf,10), "foofoxxxxx" );
600     BOOST_CHECK_EQUAL(con.use_count(), 1);
601
602     con->async_read_at_least(5,buf,5);
603     BOOST_CHECK_EQUAL(con.use_count(), 2);
604
605     con->eof();
606     BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::eof) );
607     BOOST_CHECK_EQUAL(con.use_count(), 1);
608 }
609