mirror of https://github.com/oxen-io/oxen-mq.git
Merge branch 'dev' into stable
This commit is contained in:
commit
95d7e0964f
|
@ -1,7 +1,7 @@
|
|||
cmake_minimum_required(VERSION 3.7)
|
||||
|
||||
# Has to be set before `project()`, and ignored on non-macos:
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14 CACHE STRING "macOS deployment target (Apple clang only)")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12 CACHE STRING "macOS deployment target (Apple clang only)")
|
||||
|
||||
project(liblokimq CXX C)
|
||||
|
||||
|
@ -9,7 +9,7 @@ include(GNUInstallDirs)
|
|||
|
||||
set(LOKIMQ_VERSION_MAJOR 1)
|
||||
set(LOKIMQ_VERSION_MINOR 2)
|
||||
set(LOKIMQ_VERSION_PATCH 0)
|
||||
set(LOKIMQ_VERSION_PATCH 1)
|
||||
set(LOKIMQ_VERSION "${LOKIMQ_VERSION_MAJOR}.${LOKIMQ_VERSION_MINOR}.${LOKIMQ_VERSION_PATCH}")
|
||||
message(STATUS "lokimq v${LOKIMQ_VERSION}")
|
||||
|
||||
|
@ -153,6 +153,7 @@ install(
|
|||
lokimq/lokimq.h
|
||||
lokimq/message.h
|
||||
lokimq/string_view.h
|
||||
lokimq/variant.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lokimq/version.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lokimq
|
||||
)
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <ostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
#include "variant.h"
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
@ -428,8 +428,8 @@ struct bt_deserialize_try_variant_impl<std::enable_if_t<!is_bt_deserializable<T>
|
|||
// Serialization of a variant; all variant types must be bt-serializable.
|
||||
template <typename... Ts>
|
||||
struct bt_serialize<std::variant<Ts...>, std::void_t<bt_serialize<Ts>...>> {
|
||||
void operator()(std::ostream &os, const std::variant<Ts...>& val) {
|
||||
std::visit(
|
||||
void operator()(std::ostream& os, const std::variant<Ts...>& val) {
|
||||
var::visit(
|
||||
[&os] (const auto& val) {
|
||||
using T = std::remove_cv_t<std::remove_reference_t<decltype(val)>>;
|
||||
bt_serialize<T>{}(os, val);
|
||||
|
@ -556,15 +556,14 @@ inline bt_value bt_get(std::string_view s) {
|
|||
/// auto v = get_int<uint32_t>(val); // throws if the decoded value doesn't fit in a uint32_t
|
||||
template <typename IntType, std::enable_if_t<std::is_integral_v<IntType>, int> = 0>
|
||||
IntType get_int(const bt_value &v) {
|
||||
if (std::holds_alternative<uint64_t>(v)) {
|
||||
uint64_t value = std::get<uint64_t>(v);
|
||||
if (auto* value = std::get_if<uint64_t>(&v)) {
|
||||
if constexpr (!std::is_same_v<IntType, uint64_t>)
|
||||
if (value > static_cast<uint64_t>(std::numeric_limits<IntType>::max()))
|
||||
if (*value > static_cast<uint64_t>(std::numeric_limits<IntType>::max()))
|
||||
throw std::overflow_error("Unable to extract integer value: stored value is too large for the requested type");
|
||||
return static_cast<IntType>(value);
|
||||
return static_cast<IntType>(*value);
|
||||
}
|
||||
|
||||
int64_t value = std::get<int64_t>(v);
|
||||
int64_t value = var::get<int64_t>(v); // throws if no int contained
|
||||
if constexpr (!std::is_same_v<IntType, int64_t>)
|
||||
if (value > static_cast<int64_t>(std::numeric_limits<IntType>::max())
|
||||
|| value < static_cast<int64_t>(std::numeric_limits<IntType>::min()))
|
||||
|
@ -589,7 +588,7 @@ Tuple get_tuple(const bt_list& x) {
|
|||
}
|
||||
template <typename Tuple>
|
||||
Tuple get_tuple(const bt_value& x) {
|
||||
return get_tuple<Tuple>(std::get<bt_list>(static_cast<const bt_variant&>(x)));
|
||||
return get_tuple<Tuple>(var::get<bt_list>(static_cast<const bt_variant&>(x)));
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
@ -601,15 +600,15 @@ void get_tuple_impl_one(T& t, It& it) {
|
|||
} else if constexpr (is_bt_tuple<T>) {
|
||||
if (std::holds_alternative<bt_list>(v))
|
||||
throw std::invalid_argument{"Unable to convert tuple: cannot create sub-tuple from non-bt_list"};
|
||||
t = get_tuple<T>(std::get<bt_list>(v));
|
||||
t = get_tuple<T>(var::get<bt_list>(v));
|
||||
} else if constexpr (std::is_same_v<std::string, T> || std::is_same_v<std::string_view, T>) {
|
||||
// If we request a string/string_view, we might have the other one and need to copy/view it.
|
||||
if (std::holds_alternative<std::string_view>(v))
|
||||
t = std::get<std::string_view>(v);
|
||||
t = var::get<std::string_view>(v);
|
||||
else
|
||||
t = std::get<std::string>(v);
|
||||
t = var::get<std::string>(v);
|
||||
} else {
|
||||
t = std::get<T>(v);
|
||||
t = var::get<T>(v);
|
||||
}
|
||||
}
|
||||
template <typename Tuple, size_t... Is>
|
||||
|
|
|
@ -378,7 +378,7 @@ LokiMQ::run_info& LokiMQ::run_info::load(pending_command&& pending) {
|
|||
|
||||
assert(pending.callback.index() == 0);
|
||||
return load(&pending.cat, std::move(pending.command), std::move(pending.conn), std::move(pending.access),
|
||||
std::move(pending.remote), std::move(pending.data_parts), std::get<0>(pending.callback));
|
||||
std::move(pending.remote), std::move(pending.data_parts), var::get<0>(pending.callback));
|
||||
}
|
||||
|
||||
LokiMQ::run_info& LokiMQ::run_info::load(batch_job&& bj, bool reply_job, int tagged_thread) {
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
#pragma once
|
||||
// Workarounds for macos compatibility. On macOS we aren't allowed to touch anything in
|
||||
// std::variant that could throw if compiling with a target <10.14 because Apple fails hard at
|
||||
// properly updating their STL. Thus, if compiling in such a mode, we have to introduce
|
||||
// workarounds.
|
||||
//
|
||||
// This header defines a `var` namespace with `var::get` and `var::visit` implementations. On
|
||||
// everything except broken backwards macos, this is just an alias to `std`. On broken backwards
|
||||
// macos, we provide implementations that throw std::runtime_error in failure cases since the
|
||||
// std::bad_variant_access exception can't be touched.
|
||||
//
|
||||
// You also get a BROKEN_APPLE_VARIANT macro defined if targetting a problematic mac architecture.
|
||||
|
||||
#include <variant>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <AvailabilityVersions.h>
|
||||
# if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_14
|
||||
# define BROKEN_APPLE_VARIANT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BROKEN_APPLE_VARIANT
|
||||
|
||||
namespace var = std; // Oh look, actual C++17 support
|
||||
|
||||
#else
|
||||
|
||||
// Oh look, apple.
|
||||
|
||||
namespace var {
|
||||
|
||||
// Apple won't let us use std::visit or std::get if targetting some version of macos earlier than
|
||||
// 10.14 because Apple is awful about not updating their STL. So we have to provide our own, and
|
||||
// then call these without `std::` -- on crappy macos we'll come here, on everything else we'll ADL
|
||||
// to the std:: implementation.
|
||||
template <typename T, typename... Types>
|
||||
constexpr T& get(std::variant<Types...>& var) {
|
||||
if (auto* v = std::get_if<T>(&var)) return *v;
|
||||
throw std::runtime_error{"Bad variant access -- variant does not contain the requested type"};
|
||||
}
|
||||
template <typename T, typename... Types>
|
||||
constexpr const T& get(const std::variant<Types...>& var) {
|
||||
if (auto* v = std::get_if<T>(&var)) return *v;
|
||||
throw std::runtime_error{"Bad variant access -- variant does not contain the requested type"};
|
||||
}
|
||||
template <typename T, typename... Types>
|
||||
constexpr const T&& get(const std::variant<Types...>&& var) {
|
||||
if (auto* v = std::get_if<T>(&var)) return std::move(*v);
|
||||
throw std::runtime_error{"Bad variant access -- variant does not contain the requested type"};
|
||||
}
|
||||
template <typename T, typename... Types>
|
||||
constexpr T&& get(std::variant<Types...>&& var) {
|
||||
if (auto* v = std::get_if<T>(&var)) return std::move(*v);
|
||||
throw std::runtime_error{"Bad variant access -- variant does not contain the requested type"};
|
||||
}
|
||||
template <size_t I, typename... Types>
|
||||
constexpr auto& get(std::variant<Types...>& var) {
|
||||
if (auto* v = std::get_if<I>(&var)) return *v;
|
||||
throw std::runtime_error{"Bad variant access -- variant does not contain the requested type"};
|
||||
}
|
||||
template <size_t I, typename... Types>
|
||||
constexpr const auto& get(const std::variant<Types...>& var) {
|
||||
if (auto* v = std::get_if<I>(&var)) return *v;
|
||||
throw std::runtime_error{"Bad variant access -- variant does not contain the requested type"};
|
||||
}
|
||||
template <size_t I, typename... Types>
|
||||
constexpr const auto&& get(const std::variant<Types...>&& var) {
|
||||
if (auto* v = std::get_if<I>(&var)) return std::move(*v);
|
||||
throw std::runtime_error{"Bad variant access -- variant does not contain the requested type"};
|
||||
}
|
||||
template <size_t I, typename... Types>
|
||||
constexpr auto&& get(std::variant<Types...>&& var) {
|
||||
if (auto* v = std::get_if<I>(&var)) return std::move(*v);
|
||||
throw std::runtime_error{"Bad variant access -- variant does not contain the requested type"};
|
||||
}
|
||||
|
||||
template <size_t I, size_t... More, class Visitor, class Variant>
|
||||
constexpr auto visit_helper(Visitor&& vis, Variant&& var) {
|
||||
if (var.index() == I)
|
||||
return vis(var::get<I>(std::forward<Variant>(var)));
|
||||
else if constexpr (sizeof...(More) > 0)
|
||||
return visit_helper<More...>(std::forward<Visitor>(vis), std::forward<Variant>(var));
|
||||
else
|
||||
throw std::runtime_error{"Bad visit -- variant is valueless"};
|
||||
}
|
||||
|
||||
template <size_t... Is, class Visitor, class Variant>
|
||||
constexpr auto visit_helper(Visitor&& vis, Variant&& var, std::index_sequence<Is...>) {
|
||||
return visit_helper<Is...>(std::forward<Visitor>(vis), std::forward<Variant>(var));
|
||||
}
|
||||
|
||||
// Only handle a single variant here because multi-variant invocation is notably harder (and we
|
||||
// don't need it).
|
||||
template <class Visitor, class Variant>
|
||||
constexpr auto visit(Visitor&& vis, Variant&& var) {
|
||||
return visit_helper(std::forward<Visitor>(vis), std::forward<Variant>(var),
|
||||
std::make_index_sequence<std::variant_size_v<std::remove_reference_t<Variant>>>{});
|
||||
}
|
||||
|
||||
} // namespace var
|
||||
|
||||
#endif
|
|
@ -99,7 +99,7 @@ void LokiMQ::worker_thread(unsigned int index, std::optional<std::string> tagged
|
|||
|
||||
try {
|
||||
if (run.is_batch_job) {
|
||||
auto* batch = std::get<detail::Batch*>(run.to_run);
|
||||
auto* batch = var::get<detail::Batch*>(run.to_run);
|
||||
if (run.batch_jobno >= 0) {
|
||||
LMQ_TRACE("worker thread ", worker_id, " running batch ", batch, "#", run.batch_jobno);
|
||||
batch->run_job(run.batch_jobno);
|
||||
|
@ -108,7 +108,7 @@ void LokiMQ::worker_thread(unsigned int index, std::optional<std::string> tagged
|
|||
batch->job_completion();
|
||||
}
|
||||
} else if (run.is_injected) {
|
||||
auto& func = std::get<std::function<void()>>(run.to_run);
|
||||
auto& func = var::get<std::function<void()>>(run.to_run);
|
||||
LMQ_TRACE("worker thread ", worker_id, " invoking injected command ", run.command);
|
||||
func();
|
||||
func = nullptr;
|
||||
|
@ -120,7 +120,7 @@ void LokiMQ::worker_thread(unsigned int index, std::optional<std::string> tagged
|
|||
|
||||
LMQ_TRACE("Got incoming command from ", message.remote, "/", message.conn, message.conn.route.empty() ? " (outgoing)" : " (incoming)");
|
||||
|
||||
auto& [callback, is_request] = *std::get<const std::pair<CommandCallback, bool>*>(run.to_run);
|
||||
auto& [callback, is_request] = *var::get<const std::pair<CommandCallback, bool>*>(run.to_run);
|
||||
if (is_request) {
|
||||
message.reply_tag = {run.data_parts[0].data<char>(), run.data_parts[0].size()};
|
||||
for (auto it = run.data_parts.begin() + 1; it != run.data_parts.end(); ++it)
|
||||
|
@ -137,9 +137,11 @@ void LokiMQ::worker_thread(unsigned int index, std::optional<std::string> tagged
|
|||
catch (const bt_deserialize_invalid& e) {
|
||||
LMQ_LOG(warn, worker_id, " deserialization failed: ", e.what(), "; ignoring request");
|
||||
}
|
||||
#ifndef BROKEN_APPLE_VARIANT
|
||||
catch (const std::bad_variant_access& e) {
|
||||
LMQ_LOG(warn, worker_id, " deserialization failed: found unexpected serialized type (", e.what(), "); ignoring request");
|
||||
}
|
||||
#endif
|
||||
catch (const std::out_of_range& e) {
|
||||
LMQ_LOG(warn, worker_id, " deserialization failed: invalid data - required field missing (", e.what(), "); ignoring request");
|
||||
}
|
||||
|
@ -208,7 +210,7 @@ void LokiMQ::proxy_worker_message(std::vector<zmq::message_t>& parts) {
|
|||
active--;
|
||||
}
|
||||
bool clear_job = false;
|
||||
auto* batch = std::get<detail::Batch*>(run.to_run);
|
||||
auto* batch = var::get<detail::Batch*>(run.to_run);
|
||||
if (run.batch_jobno == -1) {
|
||||
// Returned from the completion function
|
||||
clear_job = true;
|
||||
|
|
|
@ -6,6 +6,16 @@ using namespace lokimq;
|
|||
|
||||
static auto startup = std::chrono::steady_clock::now();
|
||||
|
||||
/// Returns a localhost connection string to listen on. It can be considered random, though in
|
||||
/// practice in the current implementation is sequential starting at 4500.
|
||||
inline std::string random_localhost() {
|
||||
static uint16_t last = 4499;
|
||||
last++;
|
||||
assert(last); // We should never call this enough to overflow
|
||||
return "tcp://127.0.0.1:" + std::to_string(last);
|
||||
}
|
||||
|
||||
|
||||
/// Waits up to 100ms for something to happen.
|
||||
template <typename Func>
|
||||
inline void wait_for(Func f) {
|
||||
|
|
|
@ -125,10 +125,10 @@ TEST_CASE("bt_value serialization", "[bt][serialization][bt_value]") {
|
|||
TEST_CASE("bt_value deserialization", "[bt][deserialization][bt_value]") {
|
||||
auto dna1 = bt_deserialize<bt_value>("i42e");
|
||||
auto dna2 = bt_deserialize<bt_value>("i-42e");
|
||||
REQUIRE( std::get<uint64_t>(dna1) == 42 );
|
||||
REQUIRE( std::get<int64_t>(dna2) == -42 );
|
||||
REQUIRE_THROWS( std::get<int64_t>(dna1) );
|
||||
REQUIRE_THROWS( std::get<uint64_t>(dna2) );
|
||||
REQUIRE( var::get<uint64_t>(dna1) == 42 );
|
||||
REQUIRE( var::get<int64_t>(dna2) == -42 );
|
||||
REQUIRE_THROWS( var::get<int64_t>(dna1) );
|
||||
REQUIRE_THROWS( var::get<uint64_t>(dna2) );
|
||||
REQUIRE( lokimq::get_int<int>(dna1) == 42 );
|
||||
REQUIRE( lokimq::get_int<int>(dna2) == -42 );
|
||||
REQUIRE( lokimq::get_int<unsigned>(dna1) == 42 );
|
||||
|
@ -136,19 +136,19 @@ TEST_CASE("bt_value deserialization", "[bt][deserialization][bt_value]") {
|
|||
|
||||
bt_value x = bt_deserialize<bt_value>("d3:barle3:foold1:ali1ei2ei3ee1:bleed1:cli-5ei4eeeee");
|
||||
REQUIRE( std::holds_alternative<bt_dict>(x) );
|
||||
bt_dict& a = std::get<bt_dict>(x);
|
||||
bt_dict& a = var::get<bt_dict>(x);
|
||||
REQUIRE( a.count("bar") );
|
||||
REQUIRE( a.count("foo") );
|
||||
REQUIRE( a.size() == 2 );
|
||||
bt_list& foo = std::get<bt_list>(a["foo"]);
|
||||
bt_list& foo = var::get<bt_list>(a["foo"]);
|
||||
REQUIRE( foo.size() == 2 );
|
||||
bt_dict& foo1 = std::get<bt_dict>(foo.front());
|
||||
bt_dict& foo2 = std::get<bt_dict>(foo.back());
|
||||
bt_dict& foo1 = var::get<bt_dict>(foo.front());
|
||||
bt_dict& foo2 = var::get<bt_dict>(foo.back());
|
||||
REQUIRE( foo1.size() == 2 );
|
||||
REQUIRE( foo2.size() == 1 );
|
||||
bt_list& foo1a = std::get<bt_list>(foo1.at("a"));
|
||||
bt_list& foo1b = std::get<bt_list>(foo1.at("b"));
|
||||
bt_list& foo2c = std::get<bt_list>(foo2.at("c"));
|
||||
bt_list& foo1a = var::get<bt_list>(foo1.at("a"));
|
||||
bt_list& foo1b = var::get<bt_list>(foo1.at("b"));
|
||||
bt_list& foo2c = var::get<bt_list>(foo2.at("c"));
|
||||
std::list<int> foo1a_vals, foo1b_vals, foo2c_vals;
|
||||
for (auto& v : foo1a) foo1a_vals.push_back(lokimq::get_int<int>(v));
|
||||
for (auto& v : foo1b) foo1b_vals.push_back(lokimq::get_int<int>(v));
|
||||
|
@ -157,7 +157,7 @@ TEST_CASE("bt_value deserialization", "[bt][deserialization][bt_value]") {
|
|||
REQUIRE( foo1b_vals == std::list<int>{} );
|
||||
REQUIRE( foo2c_vals == std::list{{-5, 4}} );
|
||||
|
||||
REQUIRE( std::get<bt_list>(a.at("bar")).empty() );
|
||||
REQUIRE( var::get<bt_list>(a.at("bar")).empty() );
|
||||
}
|
||||
|
||||
TEST_CASE("bt tuple serialization", "[bt][tuple][serialization]") {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
using namespace lokimq;
|
||||
|
||||
TEST_CASE("basic commands", "[commands]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -76,7 +76,7 @@ TEST_CASE("basic commands", "[commands]") {
|
|||
}
|
||||
|
||||
TEST_CASE("outgoing auth level", "[commands][auth]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -158,7 +158,7 @@ TEST_CASE("deferred replies on incoming connections", "[commands][hey google]")
|
|||
// Tests that the ConnectionID from a Message can be stored and reused later to contact the
|
||||
// original node.
|
||||
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -270,7 +270,7 @@ TEST_CASE("deferred replies on incoming connections", "[commands][hey google]")
|
|||
}
|
||||
|
||||
TEST_CASE("send failure callbacks", "[commands][queue_full]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -364,7 +364,7 @@ TEST_CASE("send failure callbacks", "[commands][queue_full]") {
|
|||
}
|
||||
|
||||
TEST_CASE("data parts", "[send][data_parts]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
|
|
@ -6,7 +6,7 @@ extern "C" {
|
|||
|
||||
|
||||
TEST_CASE("connections with curve authentication", "[curve][connect]") {
|
||||
std::string listen = "tcp://127.0.0.1:4455";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -53,16 +53,17 @@ TEST_CASE("self-connection SN optimization", "[connect][self]") {
|
|||
pubkey.resize(crypto_box_PUBLICKEYBYTES);
|
||||
privkey.resize(crypto_box_SECRETKEYBYTES);
|
||||
REQUIRE(sodium_init() != -1);
|
||||
auto listen_addr = random_localhost();
|
||||
crypto_box_keypair(reinterpret_cast<unsigned char*>(&pubkey[0]), reinterpret_cast<unsigned char*>(&privkey[0]));
|
||||
LokiMQ sn{
|
||||
pubkey, privkey,
|
||||
true,
|
||||
[&](auto pk) { if (pk == pubkey) return "tcp://127.0.0.1:5544"; else return ""; },
|
||||
[&](auto pk) { if (pk == pubkey) return listen_addr; else return ""s; },
|
||||
get_logger("S» "),
|
||||
LogLevel::trace
|
||||
};
|
||||
|
||||
sn.listen_curve("tcp://127.0.0.1:5544", [&](auto ip, auto pk, auto sn) {
|
||||
sn.listen_curve(listen_addr, [&](auto ip, auto pk, auto sn) {
|
||||
auto lock = catch_lock();
|
||||
REQUIRE(ip == "127.0.0.1");
|
||||
REQUIRE(sn == (pk == pubkey));
|
||||
|
@ -90,7 +91,7 @@ TEST_CASE("self-connection SN optimization", "[connect][self]") {
|
|||
}
|
||||
|
||||
TEST_CASE("plain-text connections", "[plaintext][connect]") {
|
||||
std::string listen = "tcp://127.0.0.1:4455";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{get_logger("S» "), LogLevel::trace};
|
||||
|
||||
server.add_category("public", Access{AuthLevel::none});
|
||||
|
@ -129,7 +130,7 @@ TEST_CASE("plain-text connections", "[plaintext][connect]") {
|
|||
}
|
||||
|
||||
TEST_CASE("unique connection IDs", "[connect][id]") {
|
||||
std::string listen = "tcp://127.0.0.1:4455";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{get_logger("S» "), LogLevel::trace};
|
||||
|
||||
ConnectionID first, second;
|
||||
|
@ -195,7 +196,7 @@ TEST_CASE("SN disconnections", "[connect][disconnect]") {
|
|||
pubkey[i].resize(crypto_box_PUBLICKEYBYTES);
|
||||
privkey[i].resize(crypto_box_SECRETKEYBYTES);
|
||||
crypto_box_keypair(reinterpret_cast<unsigned char*>(&pubkey[i][0]), reinterpret_cast<unsigned char*>(&privkey[i][0]));
|
||||
conn.emplace(pubkey[i], "tcp://127.0.0.1:" + std::to_string(4450 + i));
|
||||
conn.emplace(pubkey[i], random_localhost());
|
||||
}
|
||||
std::atomic<int> his{0};
|
||||
for (int i = 0; i < pubkey.size(); i++) {
|
||||
|
@ -231,7 +232,7 @@ TEST_CASE("SN auth checks", "[sandwich][auth]") {
|
|||
// isn't recognized as a SN but tries to invoke a SN command it'll be told to disconnect; if it
|
||||
// tries to send again it should reconnect and reauthenticate. This test is meant to test this
|
||||
// pattern where the reconnection/reauthentication now authenticates it as a SN.
|
||||
std::string listen = "tcp://127.0.0.1:4455";
|
||||
std::string listen = random_localhost();
|
||||
std::string pubkey, privkey;
|
||||
pubkey.resize(crypto_box_PUBLICKEYBYTES);
|
||||
privkey.resize(crypto_box_SECRETKEYBYTES);
|
||||
|
@ -350,7 +351,7 @@ TEST_CASE("SN auth checks", "[sandwich][auth]") {
|
|||
TEST_CASE("SN single worker test", "[connect][worker]") {
|
||||
// Tests a failure case that could trigger when all workers are allocated (here we make that
|
||||
// simpler by just having one worker).
|
||||
std::string listen = "tcp://127.0.0.1:4455";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "",
|
||||
false, // service node
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
using namespace lokimq;
|
||||
|
||||
TEST_CASE("failure responses - UNKNOWNCOMMAND", "[failure][UNKNOWNCOMMAND]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -47,7 +47,7 @@ TEST_CASE("failure responses - UNKNOWNCOMMAND", "[failure][UNKNOWNCOMMAND]") {
|
|||
}
|
||||
|
||||
TEST_CASE("failure responses - NO_REPLY_TAG", "[failure][NO_REPLY_TAG]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -108,7 +108,7 @@ TEST_CASE("failure responses - NO_REPLY_TAG", "[failure][NO_REPLY_TAG]") {
|
|||
}
|
||||
|
||||
TEST_CASE("failure responses - FORBIDDEN", "[failure][FORBIDDEN]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -191,7 +191,7 @@ TEST_CASE("failure responses - FORBIDDEN", "[failure][FORBIDDEN]") {
|
|||
}
|
||||
|
||||
TEST_CASE("failure responses - NOT_A_SERVICE_NODE", "[failure][NOT_A_SERVICE_NODE]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -258,7 +258,7 @@ TEST_CASE("failure responses - NOT_A_SERVICE_NODE", "[failure][NOT_A_SERVICE_NOD
|
|||
}
|
||||
|
||||
TEST_CASE("failure responses - FORBIDDEN_SN", "[failure][FORBIDDEN_SN]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
using namespace lokimq;
|
||||
|
||||
TEST_CASE("injected external commands", "[injected]") {
|
||||
std::string listen = "tcp://127.0.0.1:4567";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
using namespace lokimq;
|
||||
|
||||
TEST_CASE("basic requests", "[requests]") {
|
||||
std::string listen = "tcp://127.0.0.1:5678";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -61,7 +61,7 @@ TEST_CASE("basic requests", "[requests]") {
|
|||
}
|
||||
|
||||
TEST_CASE("request from server to client", "[requests]") {
|
||||
std::string listen = "tcp://127.0.0.1:5678";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
@ -124,7 +124,7 @@ TEST_CASE("request from server to client", "[requests]") {
|
|||
}
|
||||
|
||||
TEST_CASE("request timeouts", "[requests][timeout]") {
|
||||
std::string listen = "tcp://127.0.0.1:5678";
|
||||
std::string listen = random_localhost();
|
||||
LokiMQ server{
|
||||
"", "", // generate ephemeral keys
|
||||
false, // not a service node
|
||||
|
|
Loading…
Reference in New Issue