mirror of
https://codeberg.org/wownero/wownero-lws
synced 2026-01-09 23:25:16 -08:00
Switch from epee http client to boost::beast. All HTTP now non-blocking. (#150)
This commit is contained in:
committed by
Lee *!* Clagett
parent
66b7497a34
commit
29358f1323
@@ -31,6 +31,7 @@ target_include_directories(monero-lws-unit-framework PUBLIC ${CMAKE_CURRENT_SOUR
|
||||
target_link_libraries(monero-lws-unit-framework)
|
||||
|
||||
add_subdirectory(db)
|
||||
add_subdirectory(net)
|
||||
add_subdirectory(rpc)
|
||||
add_subdirectory(wire)
|
||||
|
||||
@@ -40,6 +41,8 @@ target_link_libraries(monero-lws-unit
|
||||
monero-lws-daemon-common
|
||||
monero-lws-unit-db
|
||||
monero-lws-unit-framework
|
||||
monero-lws-unit-net
|
||||
monero-lws-unit-net-http
|
||||
monero-lws-unit-rpc
|
||||
monero-lws-unit-wire
|
||||
monero-lws-unit-wire-json
|
||||
|
||||
32
tests/unit/net/CMakeLists.txt
Normal file
32
tests/unit/net/CMakeLists.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright (c) 2024, The Monero Project
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification, are
|
||||
# permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other
|
||||
# materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
add_subdirectory(http)
|
||||
|
||||
add_library(monero-lws-unit-net)
|
||||
target_link_libraries(monero-lws-unit-net monero-lws-unit-net-http)
|
||||
34
tests/unit/net/http/CMakeLists.txt
Normal file
34
tests/unit/net/http/CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright (c) 2024, The Monero Project
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification, are
|
||||
# permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other
|
||||
# materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
add_library(monero-lws-unit-net-http OBJECT client.test.cpp)
|
||||
target_link_libraries(
|
||||
monero-lws-unit-net-http
|
||||
monero-lws-net-http
|
||||
monero-lws-unit-framework
|
||||
monero::libraries)
|
||||
166
tests/unit/net/http/client.test.cpp
Normal file
166
tests/unit/net/http/client.test.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
// Copyright (c) 2024, The Monero Project
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "framework.test.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <string>
|
||||
#include "crypto/crypto.h" // monero/src
|
||||
#include "net/http/client.h"
|
||||
#include "net/http_server_impl_base.h" // monero/contrib/epee/include
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const std::uint16_t server_port = 10000;
|
||||
constexpr const std::uint16_t invalid_server_port = 10001;
|
||||
|
||||
namespace enet = epee::net_utils;
|
||||
struct context : enet::connection_context_base
|
||||
{
|
||||
context()
|
||||
: enet::connection_context_base()
|
||||
{}
|
||||
};
|
||||
|
||||
struct handler : epee::http_server_impl_base<handler, context>
|
||||
{
|
||||
handler()
|
||||
: epee::http_server_impl_base<handler, context>()
|
||||
{}
|
||||
|
||||
virtual bool
|
||||
handle_http_request(const enet::http::http_request_info& query, enet::http::http_response_info& response, context&)
|
||||
override final
|
||||
{
|
||||
if (query.m_URI == "/")
|
||||
response.m_response_code = 404;
|
||||
else
|
||||
response.m_response_code = 200;
|
||||
response.m_body = query.m_URI;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
LWS_CASE("net::http::client")
|
||||
{
|
||||
|
||||
boost::asio::io_context io;
|
||||
handler server{};
|
||||
server.init(&crypto::generate_random_bytes_thread_safe, std::to_string(server_port));
|
||||
server.run(1, false);
|
||||
|
||||
SETUP("server and client")
|
||||
{
|
||||
net::http::client client{epee::net_utils::ssl_verification_t::none};
|
||||
|
||||
SECTION("GET 200 OK")
|
||||
{
|
||||
std::atomic<bool> done = false;
|
||||
const auto handler = [&done, &lest_env] (boost::system::error_code error, std::string body)
|
||||
{
|
||||
EXPECT(!error);
|
||||
EXPECT(body == "/some_endpoint");
|
||||
done = true;
|
||||
};
|
||||
client.get_async(
|
||||
io, "http://127.0.0.1:" + std::to_string(server_port) + "/some_endpoint", handler
|
||||
);
|
||||
|
||||
while (!done)
|
||||
{
|
||||
io.run_one();
|
||||
io.restart();
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("GET 200 OK Twice")
|
||||
{
|
||||
std::atomic<unsigned> done = 0;
|
||||
const auto handler = [&done, &lest_env] (boost::system::error_code error, std::string body)
|
||||
{
|
||||
EXPECT(!error);
|
||||
EXPECT(body == "/some_endpoint");
|
||||
++done;
|
||||
};
|
||||
client.get_async(
|
||||
io, "http://127.0.0.1:" + std::to_string(server_port) + "/some_endpoint", handler
|
||||
);
|
||||
client.get_async(
|
||||
io, "http://127.0.0.1:" + std::to_string(server_port) + "/some_endpoint", handler
|
||||
);
|
||||
|
||||
while (done != 2)
|
||||
{
|
||||
io.run_one();
|
||||
io.restart();
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("GET 404 NOT FOUND")
|
||||
{
|
||||
std::atomic<bool> done = false;
|
||||
const auto handler = [&done, &lest_env] (boost::system::error_code error, std::string body)
|
||||
{
|
||||
EXPECT(error == boost::asio::error::operation_not_supported);
|
||||
EXPECT(body.empty());
|
||||
done = true;
|
||||
};
|
||||
client.get_async(
|
||||
io, "http://127.0.0.1:" + std::to_string(server_port), handler
|
||||
);
|
||||
|
||||
while (!done)
|
||||
{
|
||||
io.run_one();
|
||||
io.restart();
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("GET (Invalid server address)")
|
||||
{
|
||||
std::atomic<bool> done = false;
|
||||
const auto handler = [&done, &lest_env] (boost::system::error_code error, std::string body)
|
||||
{
|
||||
EXPECT(error == boost::asio::error::connection_refused);
|
||||
EXPECT(body.empty());
|
||||
done = true;
|
||||
};
|
||||
client.get_async(
|
||||
io, "http://127.0.0.1:" + std::to_string(invalid_server_port), handler
|
||||
);
|
||||
|
||||
while (!done)
|
||||
{
|
||||
io.run_one();
|
||||
io.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,7 +350,7 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||
std::vector<epee::byte_slice> messages{};
|
||||
messages.push_back(to_json_rpc(1));
|
||||
|
||||
lws::scanner scanner{db.clone()};
|
||||
lws::scanner scanner{db.clone(), epee::net_utils::ssl_verification_t::none};
|
||||
|
||||
boost::thread server_thread(&scanner_thread, std::ref(scanner), rpc.zmq_context(), std::cref(messages));
|
||||
const join on_scope_exit{server_thread};
|
||||
@@ -384,7 +384,7 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||
|
||||
lws_test::test_chain(lest_env, MONERO_UNWRAP(db.start_read()), last_block.id, {hashes.data(), 1});
|
||||
{
|
||||
lws::scanner scanner{db.clone()};
|
||||
lws::scanner scanner{db.clone(), epee::net_utils::ssl_verification_t::none};
|
||||
boost::thread server_thread(&scanner_thread, std::ref(scanner), rpc.zmq_context(), std::cref(messages));
|
||||
const join on_scope_exit{server_thread};
|
||||
EXPECT(scanner.sync(MONERO_UNWRAP(rpc.connect())));
|
||||
@@ -408,7 +408,7 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||
message.hashes.resize(1);
|
||||
messages.push_back(daemon_response(message));
|
||||
|
||||
lws::scanner scanner{db.clone()};
|
||||
lws::scanner scanner{db.clone(), epee::net_utils::ssl_verification_t::none};
|
||||
boost::thread server_thread(&scanner_thread, std::ref(scanner), rpc.zmq_context(), std::cref(messages));
|
||||
const join on_scope_exit{server_thread};
|
||||
EXPECT(scanner.sync(MONERO_UNWRAP(rpc.connect())));
|
||||
@@ -516,7 +516,7 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||
messages.push_back(daemon_response(hmessage));
|
||||
|
||||
{
|
||||
lws::scanner scanner{db.clone()};
|
||||
lws::scanner scanner{db.clone(), epee::net_utils::ssl_verification_t::none};
|
||||
boost::thread server_thread(&scanner_thread, std::ref(scanner), rpc.zmq_context(), std::cref(messages));
|
||||
const join on_scope_exit{server_thread};
|
||||
EXPECT(scanner.sync(MONERO_UNWRAP(rpc.connect())));
|
||||
@@ -534,10 +534,8 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||
bmessage.output_indices.resize(1);
|
||||
messages.push_back(daemon_response(bmessage));
|
||||
{
|
||||
static constexpr const lws::scanner_options opts{
|
||||
epee::net_utils::ssl_verification_t::none, true, false
|
||||
};
|
||||
lws::scanner scanner{db.clone()};
|
||||
static constexpr const lws::scanner_options opts{true, false};
|
||||
lws::scanner scanner{db.clone(), epee::net_utils::ssl_verification_t::none};
|
||||
boost::thread server_thread(&scanner_thread, std::ref(scanner), rpc.zmq_context(), std::cref(messages));
|
||||
const join on_scope_exit{server_thread};
|
||||
scanner.run(std::move(rpc), 1, {}, {}, opts);
|
||||
|
||||
Reference in New Issue
Block a user