|
|
|
@ -7,15 +7,17 @@
|
|
|
|
|
|
|
|
|
|
#define TEST_FILENAME "test_logs/async_test.log"
|
|
|
|
|
|
|
|
|
|
using spdlog::sinks::async_sink_mt;
|
|
|
|
|
using spdlog::sinks::async_sink;
|
|
|
|
|
using spdlog::sinks::sink;
|
|
|
|
|
using spdlog::sinks::test_sink_mt;
|
|
|
|
|
|
|
|
|
|
auto creat_async_logger(size_t queue_size, std::shared_ptr<sink> backend_sink) {
|
|
|
|
|
auto async_sink = std::make_shared<async_sink_mt>(queue_size);
|
|
|
|
|
async_sink->add_sink(std::move(backend_sink));
|
|
|
|
|
auto logger = std::make_shared<spdlog::logger>("async_logger", async_sink);
|
|
|
|
|
return std::make_tuple(logger, async_sink);
|
|
|
|
|
async_sink::config cfg;
|
|
|
|
|
cfg.queue_size = queue_size;
|
|
|
|
|
cfg.sinks.push_back(std::move(backend_sink));
|
|
|
|
|
auto s = std::make_shared<async_sink>(cfg);
|
|
|
|
|
auto logger = std::make_shared<spdlog::logger>("async_logger", s);
|
|
|
|
|
return std::make_tuple(logger, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("basic async test ", "[async]") {
|
|
|
|
@ -40,41 +42,46 @@ TEST_CASE("basic async test ", "[async]") {
|
|
|
|
|
TEST_CASE("discard policy ", "[async]") {
|
|
|
|
|
auto test_sink = std::make_shared<test_sink_mt>();
|
|
|
|
|
test_sink->set_delay(std::chrono::milliseconds(1));
|
|
|
|
|
size_t queue_size = 4;
|
|
|
|
|
async_sink::config config;
|
|
|
|
|
config.queue_size = 4;
|
|
|
|
|
config.policy = async_sink::overflow_policy::overrun_oldest;
|
|
|
|
|
config.sinks.push_back(test_sink);
|
|
|
|
|
size_t messages = 1024;
|
|
|
|
|
|
|
|
|
|
auto [logger, async_sink] = creat_async_logger(queue_size, test_sink);
|
|
|
|
|
async_sink->set_overflow_policy(async_sink_mt::overflow_policy::overrun_oldest);
|
|
|
|
|
REQUIRE(async_sink->get_overflow_policy() == async_sink_mt::overflow_policy::overrun_oldest);
|
|
|
|
|
REQUIRE(async_sink->get_discard_counter() == 0);
|
|
|
|
|
REQUIRE(async_sink->get_overrun_counter() == 0);
|
|
|
|
|
auto as = std::make_shared<async_sink>(config);
|
|
|
|
|
auto logger = std::make_shared<spdlog::logger>("async_logger", as);
|
|
|
|
|
REQUIRE(as->get_discard_counter() == 0);
|
|
|
|
|
REQUIRE(as->get_overrun_counter() == 0);
|
|
|
|
|
for (size_t i = 0; i < messages; i++) {
|
|
|
|
|
logger->info("Hello message");
|
|
|
|
|
}
|
|
|
|
|
REQUIRE(test_sink->msg_counter() < messages);
|
|
|
|
|
REQUIRE(async_sink->get_overrun_counter() > 0);
|
|
|
|
|
async_sink->reset_overrun_counter();
|
|
|
|
|
REQUIRE(async_sink->get_overrun_counter() == 0);
|
|
|
|
|
REQUIRE(as->get_overrun_counter() > 0);
|
|
|
|
|
as->reset_overrun_counter();
|
|
|
|
|
REQUIRE(as->get_overrun_counter() == 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("discard policy discard_new ", "[async]") {
|
|
|
|
|
auto test_sink = std::make_shared<test_sink_mt>();
|
|
|
|
|
test_sink->set_delay(std::chrono::milliseconds(1));
|
|
|
|
|
size_t queue_size = 4;
|
|
|
|
|
async_sink::config config;
|
|
|
|
|
config.queue_size = 4;
|
|
|
|
|
config.policy = async_sink::overflow_policy::discard_new;
|
|
|
|
|
config.sinks.push_back(test_sink);
|
|
|
|
|
size_t messages = 1024;
|
|
|
|
|
auto as = std::make_shared<async_sink>(config);
|
|
|
|
|
auto logger = std::make_shared<spdlog::logger>("async_logger", as);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto [logger, async_sink] = creat_async_logger(queue_size, test_sink);
|
|
|
|
|
async_sink->set_overflow_policy(async_sink_mt::overflow_policy::discard_new);
|
|
|
|
|
REQUIRE(async_sink->get_overflow_policy() == async_sink_mt::overflow_policy::discard_new);
|
|
|
|
|
REQUIRE(async_sink->get_discard_counter() == 0);
|
|
|
|
|
REQUIRE(async_sink->get_overrun_counter() == 0);
|
|
|
|
|
REQUIRE(as->get_config().policy == async_sink::overflow_policy::discard_new);
|
|
|
|
|
REQUIRE(as->get_discard_counter() == 0);
|
|
|
|
|
REQUIRE(as->get_overrun_counter() == 0);
|
|
|
|
|
for (size_t i = 0; i < messages; i++) {
|
|
|
|
|
logger->info("Hello message");
|
|
|
|
|
}
|
|
|
|
|
REQUIRE(test_sink->msg_counter() < messages);
|
|
|
|
|
REQUIRE(async_sink->get_discard_counter() > 0);
|
|
|
|
|
async_sink->reset_discard_counter();
|
|
|
|
|
REQUIRE(async_sink->get_discard_counter() == 0);
|
|
|
|
|
REQUIRE(as->get_discard_counter() > 0);
|
|
|
|
|
as->reset_discard_counter();
|
|
|
|
|
REQUIRE(as->get_discard_counter() == 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("flush", "[async]") {
|
|
|
|
@ -86,7 +93,6 @@ TEST_CASE("flush", "[async]") {
|
|
|
|
|
for (size_t i = 0; i < messages; i++) {
|
|
|
|
|
logger->info("Hello message #{}", i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger->flush();
|
|
|
|
|
}
|
|
|
|
|
// std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
|
|
|
@ -95,19 +101,22 @@ TEST_CASE("flush", "[async]") {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("wait_dtor ", "[async]") {
|
|
|
|
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
|
|
|
|
auto test_sink = std::make_shared<test_sink_mt>();
|
|
|
|
|
test_sink->set_delay(std::chrono::milliseconds(5));
|
|
|
|
|
async_sink::config config;
|
|
|
|
|
config.sinks.push_back(test_sink);
|
|
|
|
|
config.queue_size = 4;
|
|
|
|
|
config.policy = async_sink::overflow_policy::block;
|
|
|
|
|
size_t messages = 100;
|
|
|
|
|
{
|
|
|
|
|
auto [logger, async_sink] = creat_async_logger(messages, test_sink);
|
|
|
|
|
async_sink->set_overflow_policy(async_sink_mt::overflow_policy::block);
|
|
|
|
|
|
|
|
|
|
auto as = std::make_shared<async_sink>(config);
|
|
|
|
|
auto logger = std::make_shared<spdlog::logger>("async_logger", as);
|
|
|
|
|
for (size_t i = 0; i < messages; i++) {
|
|
|
|
|
logger->info("Hello message #{}", i);
|
|
|
|
|
}
|
|
|
|
|
logger->flush();
|
|
|
|
|
REQUIRE(async_sink->get_overrun_counter() == 0);
|
|
|
|
|
REQUIRE(async_sink->get_discard_counter() == 0);
|
|
|
|
|
REQUIRE(as->get_overrun_counter() == 0);
|
|
|
|
|
REQUIRE(as->get_discard_counter() == 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
REQUIRE(test_sink->msg_counter() == messages);
|
|
|
|
@ -158,15 +167,27 @@ TEST_CASE("to_file", "[async]") {
|
|
|
|
|
REQUIRE(ends_with(contents, spdlog::fmt_lib::format("Hello message #1023{}", default_eol)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("bad_ctor", "[async]") { REQUIRE_THROWS_AS(std::make_shared<async_sink_mt>(0), spdlog::spdlog_ex); }
|
|
|
|
|
|
|
|
|
|
TEST_CASE("bad_ctor2", "[async]") { REQUIRE_THROWS_AS(std::make_shared<async_sink_mt>(-1), spdlog::spdlog_ex); }
|
|
|
|
|
TEST_CASE("bad_ctor", "[async]") {
|
|
|
|
|
async_sink::config cfg;
|
|
|
|
|
cfg.queue_size = 0;
|
|
|
|
|
REQUIRE_THROWS_AS(std::make_shared<async_sink>(cfg), spdlog::spdlog_ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("bad_ctor2", "[async]") {
|
|
|
|
|
async_sink::config cfg;
|
|
|
|
|
cfg.queue_size = async_sink::max_queue_size + 1;
|
|
|
|
|
REQUIRE_THROWS_AS(std::make_shared<async_sink>(cfg), spdlog::spdlog_ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("start_stop_clbks", "[async]") {
|
|
|
|
|
bool start_called = false;
|
|
|
|
|
bool stop_called = false;
|
|
|
|
|
{
|
|
|
|
|
auto sink = std::make_shared<async_sink_mt>([&] { start_called = true; }, [&] { stop_called = true; });
|
|
|
|
|
async_sink::config cfg;
|
|
|
|
|
cfg.on_thread_start = [&] { start_called = true; };
|
|
|
|
|
cfg.on_thread_stop = [&] { stop_called = true; };
|
|
|
|
|
auto sink = std::make_shared<async_sink>(cfg);
|
|
|
|
|
}
|
|
|
|
|
REQUIRE(start_called);
|
|
|
|
|
REQUIRE(stop_called);
|
|
|
|
@ -176,7 +197,9 @@ TEST_CASE("start_stop_clbks2", "[async]") {
|
|
|
|
|
bool start_called = false;
|
|
|
|
|
bool stop_called = false;
|
|
|
|
|
{
|
|
|
|
|
auto sink = std::make_shared<async_sink_mt>([&] { start_called = true; }, nullptr);
|
|
|
|
|
async_sink::config cfg;
|
|
|
|
|
cfg.on_thread_start = [&] { start_called = true; };
|
|
|
|
|
auto sink = std::make_shared<async_sink>(cfg);
|
|
|
|
|
}
|
|
|
|
|
REQUIRE(start_called);
|
|
|
|
|
REQUIRE_FALSE(stop_called);
|
|
|
|
@ -186,7 +209,10 @@ TEST_CASE("start_stop_clbks3", "[async]") {
|
|
|
|
|
bool start_called = false;
|
|
|
|
|
bool stop_called = false;
|
|
|
|
|
{
|
|
|
|
|
auto sink = std::make_shared<async_sink_mt>(nullptr, [&] { stop_called = true; });
|
|
|
|
|
async_sink::config cfg;
|
|
|
|
|
cfg.on_thread_start = nullptr;
|
|
|
|
|
cfg.on_thread_stop = [&] { stop_called = true; };
|
|
|
|
|
auto sink = std::make_shared<async_sink>(cfg);
|
|
|
|
|
}
|
|
|
|
|
REQUIRE_FALSE(start_called);
|
|
|
|
|
REQUIRE(stop_called);
|
|
|
|
@ -196,17 +222,26 @@ TEST_CASE("start_stop_clbks4", "[async]") {
|
|
|
|
|
bool start_called = false;
|
|
|
|
|
bool stop_called = false;
|
|
|
|
|
{
|
|
|
|
|
auto sink = std::make_shared<async_sink_mt>(128, [&] { start_called = true; }, [&] { stop_called = true; });
|
|
|
|
|
async_sink::config cfg;
|
|
|
|
|
cfg.on_thread_start = [&] { start_called = true; };
|
|
|
|
|
cfg.on_thread_stop = [&] { stop_called = true; };
|
|
|
|
|
cfg.queue_size = 128;
|
|
|
|
|
auto sink = std::make_shared<async_sink>(cfg);
|
|
|
|
|
}
|
|
|
|
|
REQUIRE(start_called);
|
|
|
|
|
REQUIRE(stop_called);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// should not start threads if queue size is invalid
|
|
|
|
|
TEST_CASE("start_stop_clbks5", "[async]") {
|
|
|
|
|
bool start_called = false;
|
|
|
|
|
bool stop_called = false;
|
|
|
|
|
{
|
|
|
|
|
REQUIRE_THROWS(std::make_shared<async_sink_mt>(0, [&] { start_called = true; }, [&] { stop_called = true; }));
|
|
|
|
|
async_sink::config cfg;
|
|
|
|
|
cfg.on_thread_start = [&] { start_called = true; };
|
|
|
|
|
cfg.on_thread_stop = [&] { stop_called = true; };
|
|
|
|
|
cfg.queue_size = 0;
|
|
|
|
|
REQUIRE_THROWS_AS(std::make_shared<async_sink>(cfg), spdlog::spdlog_ex);
|
|
|
|
|
}
|
|
|
|
|
REQUIRE_FALSE(start_called);
|
|
|
|
|
REQUIRE_FALSE(stop_called);
|
|
|
|
@ -214,17 +249,20 @@ TEST_CASE("start_stop_clbks5", "[async]") {
|
|
|
|
|
|
|
|
|
|
TEST_CASE("multi-sinks", "[async]") {
|
|
|
|
|
prepare_logdir();
|
|
|
|
|
auto test_sink1 = std::make_shared<spdlog::sinks::test_sink_mt>();
|
|
|
|
|
auto test_sink2 = std::make_shared<spdlog::sinks::test_sink_mt>();
|
|
|
|
|
auto test_sink3 = std::make_shared<spdlog::sinks::test_sink_mt>();
|
|
|
|
|
auto test_sink1 = std::make_shared<test_sink_mt>();
|
|
|
|
|
auto test_sink2 = std::make_shared<test_sink_mt>();
|
|
|
|
|
auto test_sink3 = std::make_shared<test_sink_mt>();
|
|
|
|
|
size_t messages = 1024;
|
|
|
|
|
{
|
|
|
|
|
auto [logger, async_sink] = creat_async_logger(messages, test_sink1);
|
|
|
|
|
async_sink->add_sink(test_sink2);
|
|
|
|
|
async_sink->add_sink(test_sink3);
|
|
|
|
|
async_sink::config cfg;
|
|
|
|
|
cfg.sinks.push_back(test_sink1);
|
|
|
|
|
cfg.sinks.push_back(test_sink2);
|
|
|
|
|
cfg.sinks.push_back(test_sink3);
|
|
|
|
|
auto as = std::make_shared<async_sink>(cfg);
|
|
|
|
|
spdlog::logger l("async_logger", as);
|
|
|
|
|
|
|
|
|
|
for (size_t j = 0; j < messages; j++) {
|
|
|
|
|
logger->info("Hello message #{}", j);
|
|
|
|
|
l.info("Hello message #{}", j);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
REQUIRE(test_sink1->msg_counter() == messages);
|
|
|
|
|