view tests/libcommon/socket/main.cpp @ 192:74afc5a41c83

Common: rewrite socket class, closes #911 @2h
author David Demelier <markand@malikania.fr>
date Sat, 27 Oct 2018 07:11:03 +0200
parents
children
line wrap: on
line source

/*
 * main.cpp -- test socket
 *
 * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#define BOOST_TEST_MODULE "socket"
#include <boost/test/unit_test.hpp>

#include <malikania/socket.hpp>

using boost::asio::io_context;
using boost::asio::ip::make_address;
using boost::asio::ip::tcp;
using boost::asio::ssl::context;
using boost::asio::ssl::stream_base;

namespace mlk {

namespace {

class socket_fixture {
private:
	auto init() -> context;
	void handshake();
	void pair();

protected:
	// SSL and Asio context.
	context ssl_context_{init()};
	io_context ctx_;

	// two connected sockets.
	socket server_{ctx_, ssl_context_};
	socket client_{ctx_, ssl_context_};

	socket_fixture();
};

auto socket_fixture::init() -> context
{
	context ret{context::sslv23};

	ret.use_private_key_file(CMAKE_SOURCE_DIR "/tests/assets/test.key", context::pem);
	ret.use_certificate_file(CMAKE_SOURCE_DIR "/tests/assets/test.crt", context::pem);

	return ret;
}

void socket_fixture::handshake()
{
	server_.get_socket().async_handshake(stream_base::server, [] (auto code) {
		if (code)
			throw std::system_error(code);
	});
	client_.get_socket().async_handshake(stream_base::client, [] (auto code) {
		if (code)
			throw std::system_error(code);
	});

	ctx_.run();
	ctx_.reset();
}

void socket_fixture::pair()
{
	tcp::acceptor acc(ctx_, tcp::endpoint(tcp::v4(), 0U));

	acc.async_accept(server_.get_socket().lowest_layer(), [] (auto code) {
		if (code)
			throw std::system_error(code);
	});

	tcp::endpoint ep(make_address("127.0.0.1"), acc.local_endpoint().port());

	client_.get_socket().lowest_layer().async_connect(ep, [] (auto code) {
		if (code)
			throw std::system_error(code);
	});

	ctx_.run();
	ctx_.reset();
}

socket_fixture::socket_fixture()
{
	pair();
	handshake();
}

BOOST_FIXTURE_TEST_SUITE(socket_suite, socket_fixture)

BOOST_AUTO_TEST_CASE(simple)
{
	server_.recv([] (auto code, auto json) {
		BOOST_TEST(!code);
		BOOST_TEST(json["hello"].template get<std::string>() == "world");
	});
	client_.send({{ "hello", "world" }}, [] (auto code) {
		BOOST_TEST(!code);
	});
	ctx_.run();
}

BOOST_AUTO_TEST_CASE(multiple)
{
	server_.recv([] (auto code, auto json) {
		BOOST_TEST(!code);
		BOOST_TEST(json["hello"].template get<std::string>() == "world");
	});
	client_.send({{ "hello", "world" }}, [] (auto code) {
		BOOST_TEST(!code);
	});
	ctx_.run();
	ctx_.reset();

	server_.recv([] (auto code, auto json) {
		BOOST_TEST(!code);
		BOOST_TEST(json["hello"].template get<std::string>() == "what's up?");
	});
	client_.send({{ "hello", "what's up?" }}, [] (auto code) {
		BOOST_TEST(!code);
	});
	ctx_.run();
}

BOOST_AUTO_TEST_CASE(simple_then_too_big)
{
	std::string big(102400, 'a');

	server_.recv([] (auto code, auto json) {
		BOOST_TEST(!code);
		BOOST_TEST(json["hello"].template get<std::string>() == "world");
	});
	client_.send({{ "hello", "world" }}, [] (auto code) {
		BOOST_TEST(!code);
	});
	ctx_.run();
	ctx_.reset();

	server_.recv([] (auto code, auto json) {
		BOOST_TEST(code.value() == static_cast<int>(std::errc::argument_list_too_long));
		BOOST_TEST(json.is_null());
	});
	client_.send({{ "hello", std::move(big) }}, [] (auto code) {
		BOOST_TEST(!code);
	});
	ctx_.run();
}

BOOST_AUTO_TEST_SUITE_END()

} // !namespace

} // !mlk