encryption_test: Make PyKMIP run under seastar::experimental::process
Removes the requirement of boost::process, and all its non-seastar-ness. Hopefully also makes the IO and shutdown handling a bit more reliable.
This commit is contained in:
@@ -2134,7 +2134,6 @@ def kmip_arch():
|
||||
|
||||
kmipc_dir = f'kmipc/kmipc-2.1.0t-{kmiplib()}_{kmip_arch()}'
|
||||
kmipc_lib = f'{kmipc_dir}/lib/libkmip.a'
|
||||
libs += ' -lboost_filesystem'
|
||||
if os.path.exists(kmipc_lib):
|
||||
libs += f' {kmipc_lib}'
|
||||
user_cflags += f' -I{kmipc_dir}/include -DHAVE_KMIP'
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/process.hpp>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <random>
|
||||
@@ -32,6 +31,7 @@
|
||||
#include "test/lib/cql_test_env.hh"
|
||||
#include "test/lib/cql_assertions.hh"
|
||||
#include "test/lib/log.hh"
|
||||
#include "test/lib/proc_utils.hh"
|
||||
#include "db/config.hh"
|
||||
#include "db/extensions.hh"
|
||||
#include "db/commitlog/commitlog.hh"
|
||||
@@ -309,16 +309,9 @@ struct kmip_test_info {
|
||||
std::string prio;
|
||||
};
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
static future<> kmip_test_helper(const std::function<future<>(const kmip_test_info&, const tmpdir&)>& f) {
|
||||
tmpdir tmp;
|
||||
bool host_set = false;
|
||||
bp::child python;
|
||||
bp::group gp;
|
||||
bp::ipstream is;
|
||||
|
||||
std::future<void> pykmip_status;
|
||||
|
||||
static const char* def_resourcedir = "./test/resource/certs";
|
||||
const char* resourcedir = std::getenv("KMIP_RESOURCE_DIR");
|
||||
@@ -334,14 +327,6 @@ static future<> kmip_test_helper(const std::function<future<>(const kmip_test_in
|
||||
.prio = get_var_or_default("KMIP_PRIO", "SECURE128:+RSA:-VERS-TLS1.0:-ECDHE-ECDSA")
|
||||
};
|
||||
|
||||
auto cleanup = defer([&] {
|
||||
if (python.running()) {
|
||||
BOOST_TEST_MESSAGE("Stopping PyKMIP server"); // debug print. Why not.
|
||||
gp.terminate();
|
||||
pykmip_status.get();
|
||||
}
|
||||
});
|
||||
|
||||
// note: default kmip port = 5696;
|
||||
|
||||
if (!host_set) {
|
||||
@@ -370,74 +355,89 @@ database_path={}/pykmip.db
|
||||
of << cfg;
|
||||
}
|
||||
|
||||
auto pyexec = bp::search_path("python");
|
||||
auto pyexec = tests::proc::find_file_in_path("python");
|
||||
|
||||
BOOST_TEST_MESSAGE("Starting PyKMIP server"); // debug print. Why not.
|
||||
promise<int> port_promise;
|
||||
auto port_future = port_promise.get_future();
|
||||
|
||||
python = bp::child(pyexec, gp,
|
||||
"test/boost/kmip_wrapper.py",
|
||||
"-l", log,
|
||||
"-f", cfgfile,
|
||||
"-v", "DEBUG",
|
||||
(bp::std_out & bp::std_err) > is, bp::std_in.close(),
|
||||
bp::env["TMPDIR"]=tmp.path().string()
|
||||
auto python = co_await tests::proc::process_fixture::create(pyexec,
|
||||
{ // args
|
||||
pyexec.string(),
|
||||
"test/boost/kmip_wrapper.py",
|
||||
"-l", log,
|
||||
"-f", cfgfile,
|
||||
"-v", "DEBUG",
|
||||
},
|
||||
{ // env
|
||||
fmt::format("TMPDIR={}", tmp.path().string())
|
||||
},
|
||||
// stdout handler
|
||||
[port_promise = std::move(port_promise), b = false](std::string_view line) mutable -> future<consumption_result<char>> {
|
||||
static std::regex port_ex("Listening on (\\d+)");
|
||||
|
||||
std::cout << line << std::endl;
|
||||
std::match_results<typename std::string_view::const_iterator> m;
|
||||
if (!b && std::regex_match(line.begin(), line.end(), m, port_ex)) {
|
||||
port_promise.set_value(std::stoi(m[1].str()));
|
||||
BOOST_TEST_MESSAGE("Matched PyKMIP port: " + m[1].str());
|
||||
b = true;
|
||||
}
|
||||
co_return continue_consuming{};
|
||||
},
|
||||
// stderr handler
|
||||
tests::proc::process_fixture::create_copy_handler(std::cerr)
|
||||
);
|
||||
|
||||
std::promise<int> port_promise;
|
||||
auto f = port_promise.get_future();
|
||||
std::exception_ptr ep;
|
||||
|
||||
pykmip_status = std::async([&] {
|
||||
static std::regex port_ex("Listening on (\\d+)");
|
||||
try {
|
||||
// arbitrary timeout of 20s for the server to make some output. Very generous.
|
||||
auto port = co_await with_timeout(std::chrono::steady_clock::now() + 20s, std::move(port_future));
|
||||
|
||||
std::string line;
|
||||
bool b = false;
|
||||
if (port <= 0) {
|
||||
throw std::runtime_error("Invalid port");
|
||||
}
|
||||
|
||||
do {
|
||||
while (std::getline(is, line)) {
|
||||
std::cout << line << std::endl;
|
||||
std::smatch m;
|
||||
if (!b && std::regex_match(line, m, port_ex)) {
|
||||
port_promise.set_value(std::stoi(m[1].str()));
|
||||
b = true;
|
||||
}
|
||||
tls::credentials_builder b;
|
||||
co_await b.set_x509_trust_file(info.ca, seastar::tls::x509_crt_format::PEM);
|
||||
co_await b.set_x509_key_file(info.cert, info.key, seastar::tls::x509_crt_format::PEM);
|
||||
auto certs = b.build_certificate_credentials();
|
||||
|
||||
// wait for port.
|
||||
for (;;) {
|
||||
try {
|
||||
// TODO: seastar does not have a connect with timeout. That would be helpful here. But alas...
|
||||
auto c = co_await seastar::tls::connect(certs, socket_address(net::inet_address("127.0.0.1"), port));
|
||||
BOOST_TEST_MESSAGE("PyKMIP server up and available"); // debug print. Why not.
|
||||
co_await tls::check_session_is_resumed(c); // forces handshake. Make python ssl happy.
|
||||
c.shutdown_output();
|
||||
break;
|
||||
} catch (...) {
|
||||
}
|
||||
} while (python.running());
|
||||
|
||||
if (!b) {
|
||||
port_promise.set_value(-1);
|
||||
co_await sleep(100ms);
|
||||
}
|
||||
});
|
||||
// arbitrary timeout of 20s for the server to make some output. Very generous.
|
||||
if (f.wait_for(20s) == std::future_status::timeout) {
|
||||
throw std::runtime_error("Could not start pykmip");
|
||||
}
|
||||
auto port = f.get();
|
||||
if (port <= 0) {
|
||||
throw std::runtime_error("Invalid port");
|
||||
}
|
||||
// wait for port.
|
||||
tls::credentials_builder b;
|
||||
co_await b.set_x509_trust_file(info.ca, seastar::tls::x509_crt_format::PEM);
|
||||
co_await b.set_x509_key_file(info.cert, info.key, seastar::tls::x509_crt_format::PEM);
|
||||
auto certs = b.build_certificate_credentials();
|
||||
|
||||
for (;;) {
|
||||
try {
|
||||
// TODO: seastar does not have a connect with timeout. That would be helpful here. But alas...
|
||||
auto c = co_await seastar::tls::connect(certs, socket_address(net::inet_address("127.0.0.1"), port));
|
||||
BOOST_TEST_MESSAGE("PyKMIP server up and available"); // debug print. Why not.
|
||||
co_await tls::check_session_is_resumed(c); // forces handshake. Make python ssl happy.
|
||||
c.shutdown_output();
|
||||
break;
|
||||
} catch (...) {
|
||||
}
|
||||
co_await sleep(100ms);
|
||||
info.host = fmt::format("127.0.0.1:{}", port);
|
||||
|
||||
co_await f(info, tmp);
|
||||
|
||||
} catch (timed_out_error&) {
|
||||
ep = std::make_exception_ptr(std::runtime_error("Could not start pykmip"));
|
||||
} catch (...) {
|
||||
ep = std::current_exception();
|
||||
}
|
||||
|
||||
info.host = fmt::format("127.0.0.1:{}", port);
|
||||
BOOST_TEST_MESSAGE("Stopping PyKMIP server"); // debug print. Why not.
|
||||
|
||||
python.terminate();
|
||||
co_await python.wait();
|
||||
|
||||
if (ep) {
|
||||
std::rethrow_exception(ep);
|
||||
}
|
||||
} else {
|
||||
co_await f(info, tmp);
|
||||
}
|
||||
|
||||
co_await f(info, tmp);
|
||||
}
|
||||
|
||||
SEASTAR_TEST_CASE(test_kmip_provider, *check_run_test_decorator("ENABLE_KMIP_TEST", true)) {
|
||||
|
||||
Reference in New Issue
Block a user