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/core/flat_stream.hpp> 12 13 #include "stream_tests.hpp" 14 15 #include <boost/beast/_experimental/unit_test/suite.hpp> 16 #include <boost/beast/_experimental/test/stream.hpp> 17 #include <boost/beast/core/role.hpp> 18 #include <initializer_list> 19 #include <vector> 20 21 namespace boost { 22 namespace beast { 23 24 class flat_stream_test : public unit_test::suite 25 { 26 public: 27 void testMembers()28 testMembers() 29 { 30 net::io_context ioc; 31 32 test_sync_stream<flat_stream<test::stream>>(); 33 34 test_async_stream<flat_stream<test::stream>>(); 35 36 // read/write 37 38 { 39 error_code ec; 40 flat_stream<test::stream> s(ioc); 41 { 42 // VFALCO Hack to make test stream code = eof 43 test::stream ts(ioc); 44 s.next_layer().connect(ts); 45 } 46 char buf[1]; 47 net::mutable_buffer m1 = net::buffer(buf); 48 49 BEAST_EXPECT(s.read_some(net::mutable_buffer{}) == 0); 50 BEAST_EXPECT(s.read_some(net::mutable_buffer{}, ec) == 0); 51 BEAST_EXPECTS(! ec, ec.message()); 52 53 try 54 { 55 s.read_some(m1); 56 BEAST_FAIL(); 57 } 58 catch(std::exception const&) 59 { 60 BEAST_PASS(); 61 } 62 catch(...) 63 { 64 BEAST_FAIL(); 65 } 66 67 BEAST_EXPECT(s.write_some(net::const_buffer{}) == 0); 68 BEAST_EXPECT(s.write_some(net::const_buffer{}, ec) == 0); 69 BEAST_EXPECTS(! ec, ec.message()); 70 71 try 72 { 73 s.write_some(m1); 74 BEAST_FAIL(); 75 } 76 catch(std::exception const&) 77 { 78 BEAST_PASS(); 79 } 80 catch(...) 81 { 82 BEAST_FAIL(); 83 } 84 85 bool invoked; 86 87 invoked = false; 88 s.async_read_some(net::mutable_buffer{}, 89 [&](error_code ec, std::size_t) 90 { 91 invoked = true; 92 BEAST_EXPECTS(! ec, ec.message()); 93 }); 94 ioc.run(); 95 ioc.restart(); 96 BEAST_EXPECT(invoked); 97 98 invoked = false; 99 s.async_write_some(net::const_buffer{}, 100 [&](error_code ec, std::size_t) 101 { 102 invoked = true; 103 BEAST_EXPECTS(! ec, ec.message()); 104 }); 105 ioc.run(); 106 ioc.restart(); 107 BEAST_EXPECT(invoked); 108 } 109 110 // stack_write_some 111 112 { 113 char b[detail::flat_stream_base::max_size]; 114 std::array<net::const_buffer, 3> bs; 115 bs[0] = net::const_buffer(b, 100); 116 bs[1] = net::const_buffer(b + 100, 200); 117 bs[2] = net::const_buffer(b + 100 + 200, 300); 118 BEAST_EXPECT(buffer_bytes(bs) <= 119 detail::flat_stream_base::max_stack); 120 flat_stream<test::stream> s(ioc); 121 error_code ec; 122 s.write_some(bs, ec); 123 } 124 125 // write_some 126 127 { 128 char b[detail::flat_stream_base::max_size]; 129 std::array<net::const_buffer, 2> bs; 130 bs[0] = net::const_buffer(b, 131 detail::flat_stream_base::max_stack); 132 bs[1] = net::const_buffer(b + bs[0].size(), 1024); 133 BEAST_EXPECT(buffer_bytes(bs) <= 134 detail::flat_stream_base::max_size); 135 flat_stream<test::stream> s(ioc); 136 error_code ec; 137 s.write_some(bs, ec); 138 } 139 140 // async_write_some 141 142 { 143 char b[detail::flat_stream_base::max_size]; 144 std::array<net::const_buffer, 2> bs; 145 bs[0] = net::const_buffer(b, 146 detail::flat_stream_base::max_stack); 147 bs[1] = net::const_buffer(b + bs[0].size(), 1024); 148 BEAST_EXPECT(buffer_bytes(bs) <= 149 detail::flat_stream_base::max_size); 150 flat_stream<test::stream> s(ioc); 151 s.async_write_some(bs, 152 [](error_code, std::size_t) 153 { 154 }); 155 } 156 157 // teardown 158 159 { 160 test::stream ts(ioc); 161 flat_stream<test::stream> s(ioc); 162 ts.connect(s.next_layer()); 163 error_code ec; 164 teardown(role_type::client, s, ec); 165 } 166 167 { 168 test::stream ts(ioc); 169 flat_stream<test::stream> s(ioc); 170 ts.connect(s.next_layer()); 171 async_teardown(role_type::client, s, 172 [](error_code) 173 { 174 }); 175 } 176 } 177 178 void testSplit()179 testSplit() 180 { 181 auto const check = 182 [&]( 183 std::initializer_list<int> v0, 184 std::size_t limit, 185 unsigned long count, 186 bool copy) 187 { 188 std::vector<net::const_buffer> v; 189 v.reserve(v0.size()); 190 for(auto const n : v0) 191 v.emplace_back("", n); 192 auto const result = 193 boost::beast::detail::flat_stream_base::flatten(v, limit); 194 BEAST_EXPECT(result.size == count); 195 BEAST_EXPECT(result.flatten == copy); 196 return result; 197 }; 198 check({}, 1, 0, false); 199 check({1,2}, 1, 1, false); 200 check({1,2}, 2, 1, false); 201 check({1,2}, 3, 3, true); 202 check({1,2}, 4, 3, true); 203 check({1,2,3}, 1, 1, false); 204 check({1,2,3}, 2, 1, false); 205 check({1,2,3}, 3, 3, true); 206 check({1,2,3}, 4, 3, true); 207 check({1,2,3}, 7, 6, true); 208 check({1,2,3,4}, 3, 3, true); 209 } 210 211 void run()212 run() override 213 { 214 testMembers(); 215 testSplit(); 216 } 217 }; 218 219 BEAST_DEFINE_TESTSUITE(beast,core,flat_stream); 220 221 } // beast 222 } // boost 223