#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common/utils/Coroutine.h" namespace hf3fs::test { namespace { TEST(TestRequestContext, FibersBaton) { folly::CPUThreadPoolExecutor exec(folly::Random::rand32(1) + 1); folly::fibers::Baton baton; auto producer = folly::coro::co_invoke([&]() -> CoTask { co_await folly::coro::sleep(std::chrono::seconds(1)); folly::RequestContext::create(); baton.post(); co_return; }) .scheduleOn(&exec) .start(); auto consumer = folly::coro::co_invoke([&]() -> CoTask { EXPECT_EQ(folly::RequestContext::try_get(), nullptr); co_await baton; EXPECT_EQ(folly::RequestContext::try_get(), nullptr); }) .scheduleOn(&exec) .start(); producer.wait(); consumer.wait(); } TEST(TestRequestContext, CoroBaton) { folly::CPUThreadPoolExecutor exec(folly::Random::rand32(1) + 1); folly::coro::Baton baton; auto producer = folly::coro::co_invoke([&]() -> CoTask { co_await folly::coro::sleep(std::chrono::seconds(1)); folly::RequestContext::create(); baton.post(); co_return; }) .scheduleOn(&exec) .start(); auto consumer = folly::coro::co_invoke([&]() -> CoTask { EXPECT_EQ(folly::RequestContext::try_get(), nullptr); co_await baton; EXPECT_EQ(folly::RequestContext::try_get(), nullptr); }) .scheduleOn(&exec) .start(); producer.wait(); consumer.wait(); } TEST(TestRequestContext, Semaphore) { folly::CPUThreadPoolExecutor exec(folly::Random::rand32(1, 8)); folly::fibers::Semaphore semaphore(folly::Random::rand32(1, 8)); auto worker = [&]() -> CoTask { for (size_t i = 0; i < folly::Random::rand32(1000, 2000); i++) { std::optional guard; if (folly::Random::oneIn(2)) { guard.emplace(); } auto ctx = folly::RequestContext::try_get(); co_await semaphore.co_wait(); SCOPE_EXIT { semaphore.signal(); }; CO_ASSERT_EQ(ctx, folly::RequestContext::try_get()); } }; std::vector> tasks; for (size_t i = 0; i < 64; i++) { tasks.push_back(folly::coro::co_invoke(worker).scheduleOn(&exec).start()); } for (auto &task : tasks) { task.wait(); } } } // namespace } // namespace hf3fs::test