blob: fe273d167a4b54daef8f0c74f6768cce07e08868 [file] [log] [blame]
#include <sdbusplus/async.hpp>
#include <gtest/gtest.h>
struct Context : public testing::Test
{
~Context() noexcept = default;
void TearDown() override
{
// Destructing the context can throw, so we have to do it in
// the TearDown in order to make our destructor noexcept.
ctx.reset();
}
void runToStop()
{
ctx->run(std::execution::just() |
std::execution::then([this]() { ctx->request_stop(); }));
}
std::optional<sdbusplus::async::context> ctx{std::in_place};
};
TEST_F(Context, RunSimple)
{
runToStop();
}
TEST_F(Context, SpawnedTask)
{
ctx->spawn(std::execution::just());
runToStop();
}
TEST_F(Context, SpawnDelayedTask)
{
using namespace std::literals;
static constexpr auto timeout = 500ms;
auto start = std::chrono::steady_clock::now();
bool ran = false;
ctx->spawn(sdbusplus::async::sleep_for(*ctx, timeout) |
std::execution::then([&ran]() { ran = true; }));
runToStop();
auto stop = std::chrono::steady_clock::now();
EXPECT_TRUE(ran);
EXPECT_GT(stop - start, timeout);
EXPECT_LT(stop - start, timeout * 2);
}
TEST_F(Context, DestructMatcherWithPendingAwait)
{
using namespace std::literals;
bool ran = false;
auto m = std::make_optional<sdbusplus::async::match>(
*ctx, sdbusplus::bus::match::rules::interfacesAdded(
"/this/is/a/bogus/path/for/SpawnMatcher"));
// Await the match completion (which will never happen).
ctx->spawn(m->next() | std::execution::then([&ran](...) { ran = true; }));
// Destruct the match.
ctx->spawn(sdbusplus::async::sleep_for(*ctx, 1ms) |
std::execution::then([&m](...) { m.reset(); }));
runToStop();
EXPECT_FALSE(ran);
}
TEST_F(Context, DestructMatcherWithPendingAwaitAsTask)
{
using namespace std::literals;
auto m = std::make_optional<sdbusplus::async::match>(
*ctx, sdbusplus::bus::match::rules::interfacesAdded(
"/this/is/a/bogus/path/for/SpawnMatcher"));
struct _
{
static auto fn(decltype(m->next()) snd, bool& ran)
-> sdbusplus::async::task<>
{
co_await std::move(snd);
ran = true;
co_return;
}
};
bool ran = false;
ctx->spawn(_::fn(m->next(), ran));
ctx->spawn(sdbusplus::async::sleep_for(*ctx, 1ms) |
std::execution::then([&]() { m.reset(); }));
runToStop();
EXPECT_FALSE(ran);
}