diff options
author | Håvard Pettersen <havardpe@yahooinc.com> | 2022-10-12 09:40:03 +0000 |
---|---|---|
committer | Håvard Pettersen <havardpe@yahooinc.com> | 2022-10-12 15:24:29 +0000 |
commit | 8568274e54d065ae904907537dcf4ce6a9581bfa (patch) | |
tree | bf3ad64563670aca5bfc98c88171fe9bc7443280 /vespalib/src/tests/coro/lazy | |
parent | 0d6d4159ba109f78fd9fea0c6b5e8d940ffc7e90 (diff) |
more coroutines
Diffstat (limited to 'vespalib/src/tests/coro/lazy')
-rw-r--r-- | vespalib/src/tests/coro/lazy/lazy_test.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/vespalib/src/tests/coro/lazy/lazy_test.cpp b/vespalib/src/tests/coro/lazy/lazy_test.cpp index a715e473aaf..4ba1c950ad0 100644 --- a/vespalib/src/tests/coro/lazy/lazy_test.cpp +++ b/vespalib/src/tests/coro/lazy/lazy_test.cpp @@ -2,11 +2,35 @@ #include <vespa/vespalib/coro/lazy.h> #include <vespa/vespalib/coro/sync_wait.h> +#include <vespa/vespalib/util/require.h> #include <vespa/vespalib/gtest/gtest.h> +#include <thread> + using vespalib::coro::Lazy; using vespalib::coro::sync_wait; +std::vector<std::thread> threads; +struct JoinThreads { + ~JoinThreads() { + for (auto &thread: threads) { + thread.join(); + } + threads.clear(); + } +}; + +auto run_in_other_thread() { + struct awaiter { + bool await_ready() const noexcept { return false; } + void await_suspend(std::coroutine_handle<> handle) const { + threads.push_back(std::thread(handle)); + } + void await_resume() const noexcept {} + }; + return awaiter(); +} + Lazy<int> make_lazy(int value) { co_return value; } @@ -21,6 +45,33 @@ Lazy<int> async_sum(Lazy<int> a, Lazy<int> b) { co_return (co_await a + co_await b); } +Lazy<std::unique_ptr<int>> move_only_int() { + co_return std::make_unique<int>(123); +} + +Lazy<int> extract_rvalue() { + auto res = co_await move_only_int(); + co_return *res; +} + +Lazy<int> will_throw() { + REQUIRE_FAILED("failed on purpose"); + co_return 123; +} + +template<typename T> +Lazy<T> forward_value(Lazy<T> value) { + co_return co_await std::move(value); +} + +template <typename T> +Lazy<T> switch_thread(Lazy<T> value) { + std::cerr << "switching from thread " << std::this_thread::get_id() << std::endl; + co_await run_in_other_thread(); + std::cerr << "........... to thread " << std::this_thread::get_id() << std::endl; + co_return co_await value; +} + TEST(LazyTest, simple_lazy_value) { auto lazy = make_lazy(42); auto result = sync_wait(lazy); @@ -41,4 +92,27 @@ TEST(LazyTest, async_sum_of_external_async_values) { EXPECT_EQ(result, 300); } +TEST(LazyTest, extract_rvalue_from_lazy_in_coroutine) { + auto lazy = extract_rvalue(); + auto result = sync_wait(lazy); + EXPECT_EQ(result, 123); +} + +TEST(LazyTest, extract_rvalue_from_lazy_in_sync_wait) { + auto result = sync_wait(move_only_int()); + EXPECT_EQ(*result, 123); +} + +TEST(LazyTest, calculate_result_in_another_thread) { + JoinThreads thread_guard; + auto result = sync_wait(switch_thread(make_lazy(7))); + EXPECT_EQ(result, 7); +} + +TEST(LazyTest, exceptions_are_propagated) { + JoinThreads thread_guard; + auto lazy = switch_thread(forward_value(will_throw())); + EXPECT_THROW(sync_wait(lazy), vespalib::RequireFailedException); +} + GTEST_MAIN_RUN_ALL_TESTS() |