Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / beast / test / beast / websocket / timer.cpp
1
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9
10 // Test that header file is self-contained.
11 #include <boost/beast/websocket/stream.hpp>
12
13 #include <boost/beast/_experimental/test/stream.hpp>
14 #include <boost/beast/_experimental/test/tcp.hpp>
15 #include <boost/beast/_experimental/unit_test/suite.hpp>
16 #include <boost/beast/core/flat_buffer.hpp>
17 #include <boost/asio/ip/tcp.hpp>
18 #include <boost/asio/detached.hpp>
19
20 namespace boost {
21 namespace beast {
22 namespace websocket {
23
24 struct timer_test : unit_test::suite
25 {
26     using tcp = boost::asio::ip::tcp;
27
28     void
29     testIdlePing()
30     {
31         net::io_context ioc;
32
33         // idle ping, no timeout
34
35         {
36             stream<tcp::socket> ws1(ioc);
37             stream<tcp::socket> ws2(ioc);
38             test::connect(ws1.next_layer(), ws2.next_layer());
39             ws1.async_accept(test::success_handler());
40             ws2.async_handshake("test", "/", test::success_handler());
41             test::run(ioc);
42
43             ws2.set_option(stream_base::timeout{
44                 stream_base::none(),
45                 std::chrono::milliseconds(100),
46                 true});
47             flat_buffer b1;
48             flat_buffer b2;
49             bool received = false;
50             ws1.control_callback(
51                 [&received](frame_type ft, string_view)
52                 {
53                     received = true;
54                     BEAST_EXPECT(ft == frame_type::ping);
55                 });
56             ws1.async_read(b1, test::fail_handler(
57                 net::error::operation_aborted));
58             ws2.async_read(b2, test::fail_handler(
59                 net::error::operation_aborted));
60             test::run_for(ioc, std::chrono::milliseconds(500));
61             BEAST_EXPECT(received);
62         }
63
64         test::run(ioc);
65
66         // idle ping, timeout
67
68         {
69             stream<tcp::socket> ws1(ioc);
70             stream<tcp::socket> ws2(ioc);
71             test::connect(ws1.next_layer(), ws2.next_layer());
72             ws1.async_accept(test::success_handler());
73             ws2.async_handshake("test", "/", test::success_handler());
74             test::run(ioc);
75
76             ws2.set_option(stream_base::timeout{
77                 stream_base::none(),
78                 std::chrono::milliseconds(50),
79                 true});
80             flat_buffer b;
81             ws2.async_read(b,
82                 test::fail_handler(beast::error::timeout));
83             test::run(ioc);
84         }
85
86         test::run(ioc);
87     }
88
89     // https://github.com/boostorg/beast/issues/1729
90     void
91     testIssue1729()
92     {
93         {
94             net::io_context ioc;
95             stream<tcp::socket> ws1(ioc);
96             stream<tcp::socket> ws2(ioc);
97             test::connect(ws1.next_layer(), ws2.next_layer());
98
99             ws1.set_option(websocket::stream_base::timeout{
100                 std::chrono::milliseconds(50),
101                 websocket::stream_base::none(),
102                 false});
103
104             ws1.async_accept(net::detached);
105             ws2.async_handshake(
106                 "localhost", "/", net::detached);
107             ioc.run();
108             ioc.restart();
109
110             flat_buffer b;
111             error_code ec1, ec2;
112             ws1.async_close({},
113                 [&ec2](error_code ec)
114                 {
115                     ec2 = ec;
116                 });
117             ioc.run();
118             BEAST_EXPECT(
119                 ec1 == beast::error::timeout ||
120                 ec2 == beast::error::timeout);
121         }
122         {
123             net::io_context ioc;
124             stream<tcp::socket> ws1(ioc);
125             stream<tcp::socket> ws2(ioc);
126             test::connect(ws1.next_layer(), ws2.next_layer());
127
128             ws1.set_option(websocket::stream_base::timeout{
129                 std::chrono::milliseconds(50),
130                 websocket::stream_base::none(),
131                 false});
132
133             ws1.async_accept(net::detached);
134             ws2.async_handshake(
135                 "localhost", "/", net::detached);
136             ioc.run();
137             ioc.restart();
138
139             flat_buffer b;
140             error_code ec1, ec2;
141             ws1.async_read(b,
142                 [&ec1](error_code ec, std::size_t)
143                 {
144                     ec1 = ec;
145                 });
146             ws1.async_close({},
147                 [&ec2](error_code ec)
148                 {
149                     ec2 = ec;
150                 });
151             ioc.run();
152             BEAST_EXPECT(
153                 ec1 == beast::error::timeout ||
154                 ec2 == beast::error::timeout);
155         }
156     }
157
158     // https://github.com/boostorg/beast/issues/1729#issuecomment-540481056
159     void
160     testCloseWhileRead()
161     {
162         net::io_context ioc;
163         stream<tcp::socket> ws1(ioc);
164         stream<tcp::socket> ws2(ioc);
165         test::connect(ws1.next_layer(), ws2.next_layer());
166
167         ws1.set_option(websocket::stream_base::timeout{
168             std::chrono::milliseconds(50),
169             websocket::stream_base::none(),
170             false});
171
172         ws1.async_accept(net::detached);
173         ws2.async_handshake(
174             "localhost", "/", net::detached);
175         ioc.run();
176         ioc.restart();
177
178         flat_buffer b;
179         ws1.async_read(b, test::fail_handler(
180             beast::error::timeout));
181         ws1.async_close({}, test::fail_handler(
182             net::error::operation_aborted));
183         ioc.run();
184     }
185
186     void
187     run() override
188     {
189         testIdlePing();
190         testIssue1729();
191         testCloseWhileRead();
192     }
193 };
194
195 BEAST_DEFINE_TESTSUITE(beast,websocket,timer);
196
197 } // websocket
198 } // beast
199 } // boost