Add server-framework tests

This commit is contained in:
Vinnie Falco
2017-06-19 09:01:56 -07:00
parent e4ed62df0b
commit 79eb97fbd6
10 changed files with 382 additions and 49 deletions

View File

@@ -2,6 +2,7 @@ Version 62:
* Remove libssl-dev from a Travis matrix item * Remove libssl-dev from a Travis matrix item
* Increase detail::static_ostream coverage * Increase detail::static_ostream coverage
* Add server-framework tests
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -138,8 +138,7 @@ private:
this->log_, this->log_,
this->services_, this->services_,
this->id_, this->id_,
ep ep)->handshake(buffer_.data());
)->handshake(buffer_.data());
// When we return the last shared pointer to this // When we return the last shared pointer to this
// object will go away and `*this` will be destroyed. // object will go away and `*this` will be destroyed.
@@ -318,8 +317,7 @@ public:
log_, log_,
instance_.next_id(), instance_.next_id(),
ep, ep,
cb2_ cb2_)->run(std::move(req));
)->run(std::move(req));
} }
}; };
@@ -388,8 +386,7 @@ public:
log_, log_,
services_, services_,
instance_.next_id(), instance_.next_id(),
ep ep)->detect();
)->detect();
} }
}; };

View File

@@ -15,6 +15,7 @@ compile websocket.cpp : : ;
compile zlib.cpp : : ; compile zlib.cpp : : ;
build-project server ; build-project server ;
build-project websocket ;
unit-test core-tests : unit-test core-tests :
../extras/beast/unit_test/main.cpp ../extras/beast/unit_test/main.cpp
@@ -76,19 +77,6 @@ unit-test http-bench :
http/parser_bench.cpp http/parser_bench.cpp
; ;
unit-test websocket-tests :
../extras/beast/unit_test/main.cpp
websocket/doc_snippets.cpp
websocket/error.cpp
websocket/option.cpp
websocket/rfc6455.cpp
websocket/stream.cpp
websocket/teardown.cpp
websocket/frame.cpp
websocket/mask.cpp
websocket/utf8_checker.cpp
;
unit-test zlib-tests : unit-test zlib-tests :
../extras/beast/unit_test/main.cpp ../extras/beast/unit_test/main.cpp
zlib/zlib-1.2.8/adler32.c zlib/zlib-1.2.8/adler32.c

View File

@@ -1,23 +1,19 @@
# Part of Beast # Part of Beast
GroupSources(example/server-framework framework) GroupSources(example/server-framework framework)
GroupSources(extras/beast extras)
GroupSources(include/beast beast) GroupSources(include/beast beast)
GroupSources(test/server "/") GroupSources(test/server "/")
if (OPENSSL_FOUND) if (OPENSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR}) include_directories(${OPENSSL_INCLUDE_DIR})
set(SSL_SOURCES
https_ports.cpp
ssl_stream.cpp
)
else ()
set(SSL_SOURCES "")
endif() endif()
add_executable (server-test add_executable (server-test
${BEAST_INCLUDES} ${BEAST_INCLUDES}
${SERVER_INCLUDES} ${SERVER_INCLUDES}
../../extras/beast/unit_test/main.cpp
file_body.cpp file_body.cpp
file_service.cpp file_service.cpp
framework.cpp framework.cpp
@@ -25,21 +21,25 @@ add_executable (server-test
http_base.cpp http_base.cpp
http_sync_port.cpp http_sync_port.cpp
https_ports.cpp https_ports.cpp
main.cpp
multi_port.cpp multi_port.cpp
rfc7231.cpp rfc7231.cpp
server.cpp server.cpp
service_list.cpp service_list.cpp
ssl_certificate ssl_certificate
ssl_stream.cpp
tests.cpp
write_msg.cpp write_msg.cpp
ws_async_port.cpp ws_async_port.cpp
ws_sync_port.cpp ws_sync_port.cpp
ws_upgrade_service.cpp ws_upgrade_service.cpp
wss_ports.cpp wss_ports.cpp
${SSL_SOURCES}
) )
target_link_libraries(server-test Beast) target_link_libraries(server-test
Beast
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
)
if (OPENSSL_FOUND) if (OPENSSL_FOUND)
target_link_libraries(server-test ${OPENSSL_LIBRARIES}) target_link_libraries(server-test ${OPENSSL_LIBRARIES})

View File

@@ -5,23 +5,24 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# #
exe server-test : unit-test server-test :
../../extras/beast/unit_test/main.cpp
file_body.cpp file_body.cpp
file_service.cpp file_service.cpp
framework.cpp framework.cpp
http_async_port.cpp http_async_port.cpp
http_base.cpp http_base.cpp
http_sync_port.cpp http_sync_port.cpp
main.cpp https_ports.cpp
multi_port.cpp
rfc7231.cpp rfc7231.cpp
server.cpp server.cpp
service_list.cpp service_list.cpp
ssl_certificate.cpp
ssl_stream.cpp
tests.cpp
write_msg.cpp write_msg.cpp
ws_async_port.cpp ws_async_port.cpp
ws_sync_port.cpp ws_sync_port.cpp
ws_upgrade_service.cpp ws_upgrade_service.cpp
#https_ports.cpp
#multi_port.cpp
#ssl_certificate.cpp
#ssl_stream.cpp
; ;

View File

@@ -1,10 +0,0 @@
//
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
int main(int argc, char** argv)
{
}

View File

@@ -5,6 +5,10 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
#if BEAST_USE_OPENSSL
// Test that header file is self-contained. // Test that header file is self-contained.
#include "../../example/server-framework/multi_port.hpp" #include "../../example/server-framework/multi_port.hpp"
#endif

328
test/server/tests.cpp Normal file
View File

@@ -0,0 +1,328 @@
//
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include "example/server-framework/http_sync_port.hpp"
#include "example/server-framework/http_async_port.hpp"
#include "example/server-framework/ws_sync_port.hpp"
#include "example/server-framework/ws_async_port.hpp"
#include "example/server-framework/ws_upgrade_service.hpp"
#if BEAST_USE_OPENSSL
# include "example/server-framework/https_ports.hpp"
# include "example/server-framework/multi_port.hpp"
# include "example/server-framework/ssl_certificate.hpp"
# include "example/server-framework/wss_ports.hpp"
#endif
#include <beast/core/drain_buffer.hpp>
#include <beast/websocket.hpp>
#include <beast/test/yield_to.hpp>
#include <beast/unit_test/suite.hpp>
namespace beast {
namespace websocket {
class server_test
: public beast::unit_test::suite
, public test::enable_yield_to
{
public:
static unsigned short constexpr port_num = 6000;
class set_ws_options
{
beast::websocket::permessage_deflate pmd_;
public:
set_ws_options(beast::websocket::permessage_deflate const& pmd)
: pmd_(pmd)
{
}
template<class NextLayer>
void
operator()(beast::websocket::stream<NextLayer>& ws) const
{
ws.auto_fragment(false);
ws.set_option(pmd_);
ws.read_message_max(64 * 1024 * 1024);
}
};
set_ws_options
get_ws_options()
{
beast::websocket::permessage_deflate pmd;
pmd.client_enable = true;
pmd.server_enable = true;
pmd.compLevel = 3;
return set_ws_options{pmd};
}
template<class Stream>
void
doOptions(Stream& stream, error_code& ec)
{
beast::http::request<beast::http::empty_body> req;
req.version = 11;
req.method(beast::http::verb::options);
req.target("*");
req.set(beast::http::field::user_agent, "test");
req.set(beast::http::field::connection, "close");
beast::http::write(stream, req, ec);
if(! BEAST_EXPECTS(
ec == beast::http::error::end_of_stream,
ec.message()))
return;
beast::flat_buffer b;
beast::http::response<beast::http::string_body> res;
beast::http::read(stream, b, res, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
}
template<class NextLayer>
void
doHello(stream<NextLayer>& ws, error_code& ec)
{
ws.handshake("localhost", "/", ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
ws.write(boost::asio::buffer(std::string("Hello, world!")), ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
beast::multi_buffer b;
ws.read(b, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
ws.close(beast::websocket::close_code::normal, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
// VFALCO Verify the buffer's contents
drain_buffer drain;
for(;;)
{
ws.read(drain, ec);
if(ec == beast::websocket::error::closed)
break;
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
}
}
void
httpClient(framework::endpoint_type const& ep)
{
error_code ec;
boost::asio::ip::tcp::socket con{ios_};
con.connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
doOptions(con, ec);
}
void
wsClient(framework::endpoint_type const& ep)
{
error_code ec;
stream<boost::asio::ip::tcp::socket> ws{ios_};
ws.next_layer().connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
doHello(ws, ec);
}
void
testPlain()
{
using namespace framework;
// ws sync
{
error_code ec;
server instance;
auto const ep1 = endpoint_type{
address_type::from_string("127.0.0.1"), port_num};
auto const wsp = instance.make_port<ws_sync_port>(
ec, ep1, instance, log, get_ws_options());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
auto const ep2 = endpoint_type{
address_type::from_string("127.0.0.1"),
static_cast<unsigned short>(port_num + 1)};
auto const sp = instance.make_port<
http_sync_port<ws_upgrade_service<ws_sync_port>>>(
ec, ep2, instance, log);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
sp->template init<0>(ec, *wsp);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wsClient(ep1);
wsClient(ep2);
httpClient(ep2);
}
// ws async
{
error_code ec;
server instance;
auto const ep1 = endpoint_type{
address_type::from_string("127.0.0.1"), port_num};
auto const wsp = instance.make_port<ws_async_port>(
ec, ep1, instance, log, get_ws_options());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
auto const ep2 = endpoint_type{
address_type::from_string("127.0.0.1"),
static_cast<unsigned short>(port_num + 1)};
auto const sp = instance.make_port<
http_async_port<ws_upgrade_service<ws_async_port>>>(
ec, ep2, instance, log);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
sp->template init<0>(ec, *wsp);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wsClient(ep1);
wsClient(ep2);
httpClient(ep2);
}
}
#if BEAST_USE_OPENSSL
//
// OpenSSL enabled ports
//
void
httpsClient(framework::endpoint_type const& ep,
boost::asio::ssl::context& ctx)
{
error_code ec;
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> con{ios_, ctx};
con.next_layer().connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
con.handshake(
boost::asio::ssl::stream_base::client, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
doOptions(con, ec);
if(ec)
return;
con.shutdown(ec);
// VFALCO No idea why we get eof in the normal case
if(ec == boost::asio::error::eof)
ec = {};
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
}
void
wssClient(framework::endpoint_type const& ep,
boost::asio::ssl::context& ctx)
{
error_code ec;
stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> wss{ios_, ctx};
wss.next_layer().next_layer().connect(ep, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wss.next_layer().handshake(
boost::asio::ssl::stream_base::client, ec);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
doHello(wss, ec);
}
void
testSSL()
{
using namespace framework;
ssl_certificate cert;
// wss sync
{
error_code ec;
server instance;
auto const ep1 = endpoint_type{
address_type::from_string("127.0.0.1"), port_num};
auto const wsp = instance.make_port<wss_sync_port>(
ec, ep1, instance, log, cert.get(), get_ws_options());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
auto const ep2 = endpoint_type{
address_type::from_string("127.0.0.1"),
static_cast<unsigned short>(port_num + 1)};
auto const sp = instance.make_port<
https_sync_port<ws_upgrade_service<wss_sync_port>>>(
ec, ep2, instance, log, cert.get());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
sp->template init<0>(ec, *wsp);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wssClient(ep1, cert.get());
wssClient(ep2, cert.get());
httpsClient(ep2, cert.get());
}
// wss async
{
error_code ec;
server instance;
auto const ep1 = endpoint_type{
address_type::from_string("127.0.0.1"), port_num};
auto const wsp = instance.make_port<wss_async_port>(
ec, ep1, instance, log, cert.get(), get_ws_options());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
auto const ep2 = endpoint_type{
address_type::from_string("127.0.0.1"),
static_cast<unsigned short>(port_num + 1)};
auto const sp = instance.make_port<
https_async_port<ws_upgrade_service<wss_async_port>>>(
ec, ep2, instance, log, cert.get());
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
sp->template init<0>(ec, *wsp);
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
wssClient(ep1, cert.get());
wssClient(ep2, cert.get());
httpsClient(ep2, cert.get());
}
}
#endif
void
run() override
{
testPlain();
#if BEAST_USE_OPENSSL
testSSL();
#endif
}
};
BEAST_DEFINE_TESTSUITE(server,websocket,beast);
} // websocket
} // beast

View File

@@ -4,6 +4,8 @@ GroupSources(extras/beast extras)
GroupSources(include/beast beast) GroupSources(include/beast beast)
GroupSources(test/websocket "/") GroupSources(test/websocket "/")
include_directories(../../example/)
add_executable (websocket-tests add_executable (websocket-tests
${BEAST_INCLUDES} ${BEAST_INCLUDES}
${EXTRAS_INCLUDES} ${EXTRAS_INCLUDES}
@@ -21,8 +23,11 @@ add_executable (websocket-tests
utf8_checker.cpp utf8_checker.cpp
) )
target_link_libraries(websocket-tests Beast ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_COROUTINE_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY}) target_link_libraries(websocket-tests
Beast
if (MINGW) ${Boost_PROGRAM_OPTIONS_LIBRARY}
set_target_properties(websocket-tests PROPERTIES COMPILE_FLAGS "-Wa,-mbig-obj -Og") ${Boost_FILESYSTEM_LIBRARY}
endif() ${Boost_COROUTINE_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_CONTEXT_LIBRARY}
)

19
test/websocket/Jamfile Normal file
View File

@@ -0,0 +1,19 @@
#
# Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
unit-test websocket-tests :
../../extras/beast/unit_test/main.cpp
doc_snippets.cpp
error.cpp
option.cpp
rfc6455.cpp
stream.cpp
teardown.cpp
frame.cpp
mask.cpp
utf8_checker.cpp
;