diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/fiber/test/test_future_post.cpp | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/fiber/test/test_future_post.cpp')
-rw-r--r-- | src/boost/libs/fiber/test/test_future_post.cpp | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/src/boost/libs/fiber/test/test_future_post.cpp b/src/boost/libs/fiber/test/test_future_post.cpp new file mode 100644 index 00000000..01deb26f --- /dev/null +++ b/src/boost/libs/fiber/test/test_future_post.cpp @@ -0,0 +1,569 @@ +// (C) Copyright 2008-10 Anthony Williams +// 2015 Oliver Kowalke +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <chrono> +#include <memory> +#include <stdexcept> +#include <string> +#include <utility> + +#include <boost/test/unit_test.hpp> + +#include <boost/fiber/all.hpp> + +typedef std::chrono::milliseconds ms; +typedef std::chrono::high_resolution_clock Clock; + +int gi = 7; + +struct my_exception : public std::runtime_error { + my_exception() : + std::runtime_error("my_exception") { + } +}; + +struct A { + A() = default; + + A( A const&) = delete; + A( A &&) = default; + + A & operator=( A const&) = delete; + A & operator=( A &&) = default; + + int value; +}; + +void fn1( boost::fibers::promise< int > * p, int i) { + boost::this_fiber::yield(); + p->set_value( i); +} + +void fn2() { + boost::fibers::promise< int > p; + boost::fibers::future< int > f( p.get_future() ); + boost::this_fiber::yield(); + boost::fibers::fiber( boost::fibers::launch::post, fn1, & p, 7).detach(); + boost::this_fiber::yield(); + BOOST_CHECK( 7 == f.get() ); +} + +int fn3() { + return 3; +} + +void fn4() { +} + +int fn5() { + boost::throw_exception( my_exception() ); + return 3; +} + +void fn6() { + boost::throw_exception( my_exception() ); +} + +int & fn7() { + return gi; +} + +int fn8( int i) { + return i; +} + +A fn9() { + A a; + a.value = 3; + return a; +} + +A fn10() { + boost::throw_exception( my_exception() ); + return A(); +} + +void fn11( boost::fibers::promise< int > p) { + boost::this_fiber::sleep_for( ms(500) ); + p.set_value(3); +} + +void fn12( boost::fibers::promise< int& > p) { + boost::this_fiber::sleep_for( ms(500) ); + gi = 5; + p.set_value( gi); +} + +void fn13( boost::fibers::promise< void > p) { + boost::this_fiber::sleep_for( ms(400) ); + p.set_value(); +} + +// future +void test_future_create() { + // default constructed future is not valid + boost::fibers::future< int > f1; + BOOST_CHECK( ! f1.valid() ); + + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int > p2; + boost::fibers::future< int > f2 = p2.get_future(); + BOOST_CHECK( f2.valid() ); +} + +void test_future_create_ref() { + // default constructed future is not valid + boost::fibers::future< int& > f1; + BOOST_CHECK( ! f1.valid() ); + + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int& > p2; + boost::fibers::future< int& > f2 = p2.get_future(); + BOOST_CHECK( f2.valid() ); +} + +void test_future_create_void() { + // default constructed future is not valid + boost::fibers::future< void > f1; + BOOST_CHECK( ! f1.valid() ); + + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< void > p2; + boost::fibers::future< void > f2 = p2.get_future(); + BOOST_CHECK( f2.valid() ); +} + +void test_future_move() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int > p1; + boost::fibers::future< int > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // move construction + boost::fibers::future< int > f2( std::move( f1) ); + BOOST_CHECK( ! f1.valid() ); + BOOST_CHECK( f2.valid() ); + + // move assignment + f1 = std::move( f2); + BOOST_CHECK( f1.valid() ); + BOOST_CHECK( ! f2.valid() ); +} + +void test_future_move_ref() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int& > p1; + boost::fibers::future< int& > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // move construction + boost::fibers::future< int& > f2( std::move( f1) ); + BOOST_CHECK( ! f1.valid() ); + BOOST_CHECK( f2.valid() ); + + // move assignment + f1 = std::move( f2); + BOOST_CHECK( f1.valid() ); + BOOST_CHECK( ! f2.valid() ); +} + +void test_future_move_void() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< void > p1; + boost::fibers::future< void > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // move construction + boost::fibers::future< void > f2( std::move( f1) ); + BOOST_CHECK( ! f1.valid() ); + BOOST_CHECK( f2.valid() ); + + // move assignment + f1 = std::move( f2); + BOOST_CHECK( f1.valid() ); + BOOST_CHECK( ! f2.valid() ); +} + +void test_future_get() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int > p1; + p1.set_value( 7); + + boost::fibers::future< int > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // get + BOOST_CHECK( ! f1.get_exception_ptr() ); + BOOST_CHECK( 7 == f1.get() ); + BOOST_CHECK( ! f1.valid() ); + + // throw broken_promise if promise is destroyed without set + { + boost::fibers::promise< int > p2; + f1 = p2.get_future(); + } + bool thrown = false; + try { + f1.get(); + } catch ( boost::fibers::broken_promise const&) { + thrown = true; + } + BOOST_CHECK( ! f1.valid() ); + BOOST_CHECK( thrown); +} + +void test_future_get_move() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< A > p1; + A a; a.value = 7; + p1.set_value( std::move( a) ); + + boost::fibers::future< A > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // get + BOOST_CHECK( ! f1.get_exception_ptr() ); + BOOST_CHECK( 7 == f1.get().value); + BOOST_CHECK( ! f1.valid() ); + + // throw broken_promise if promise is destroyed without set + { + boost::fibers::promise< A > p2; + f1 = p2.get_future(); + } + bool thrown = false; + try { + f1.get(); + } catch ( boost::fibers::broken_promise const&) { + thrown = true; + } + BOOST_CHECK( ! f1.valid() ); + BOOST_CHECK( thrown); +} + +void test_future_get_ref() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int& > p1; + int i = 7; + p1.set_value( i); + + boost::fibers::future< int& > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // get + BOOST_CHECK( ! f1.get_exception_ptr() ); + int & j = f1.get(); + BOOST_CHECK( &i == &j); + BOOST_CHECK( ! f1.valid() ); + + // throw broken_promise if promise is destroyed without set + { + boost::fibers::promise< int& > p2; + f1 = p2.get_future(); + } + bool thrown = false; + try { + f1.get(); + } catch ( boost::fibers::broken_promise const&) { + thrown = true; + } + BOOST_CHECK( ! f1.valid() ); + BOOST_CHECK( thrown); +} + + +void test_future_get_void() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< void > p1; + p1.set_value(); + + boost::fibers::future< void > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // get + BOOST_CHECK( ! f1.get_exception_ptr() ); + f1.get(); + BOOST_CHECK( ! f1.valid() ); + + // throw broken_promise if promise is destroyed without set + { + boost::fibers::promise< void > p2; + f1 = p2.get_future(); + } + bool thrown = false; + try { + f1.get(); + } catch ( boost::fibers::broken_promise const&) { + thrown = true; + } + BOOST_CHECK( ! f1.valid() ); + BOOST_CHECK( thrown); +} + +void test_future_share() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int > p1; + int i = 7; + p1.set_value( i); + + boost::fibers::future< int > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // share + boost::fibers::shared_future< int > sf1 = f1.share(); + BOOST_CHECK( sf1.valid() ); + BOOST_CHECK( ! f1.valid() ); + + // get + BOOST_CHECK( ! sf1.get_exception_ptr() ); + int j = sf1.get(); + BOOST_CHECK_EQUAL( i, j); + BOOST_CHECK( sf1.valid() ); +} + +void test_future_share_ref() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int& > p1; + int i = 7; + p1.set_value( i); + + boost::fibers::future< int& > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // share + boost::fibers::shared_future< int& > sf1 = f1.share(); + BOOST_CHECK( sf1.valid() ); + BOOST_CHECK( ! f1.valid() ); + + // get + BOOST_CHECK( ! sf1.get_exception_ptr() ); + int & j = sf1.get(); + BOOST_CHECK( &i == &j); + BOOST_CHECK( sf1.valid() ); +} + +void test_future_share_void() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< void > p1; + p1.set_value(); + + boost::fibers::future< void > f1 = p1.get_future(); + BOOST_CHECK( f1.valid() ); + + // share + boost::fibers::shared_future< void > sf1 = f1.share(); + BOOST_CHECK( sf1.valid() ); + BOOST_CHECK( ! f1.valid() ); + + // get + BOOST_CHECK( ! sf1.get_exception_ptr() ); + sf1.get(); + BOOST_CHECK( sf1.valid() ); +} + +void test_future_wait() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int > p1; + boost::fibers::future< int > f1 = p1.get_future(); + + // wait on future + p1.set_value( 7); + f1.wait(); + BOOST_CHECK( 7 == f1.get() ); +} + +void test_future_wait_ref() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int& > p1; + boost::fibers::future< int& > f1 = p1.get_future(); + + // wait on future + int i = 7; + p1.set_value( i); + f1.wait(); + int & j = f1.get(); + BOOST_CHECK( &i == &j); +} + +void test_future_wait_void() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< void > p1; + boost::fibers::future< void > f1 = p1.get_future(); + + // wait on future + p1.set_value(); + f1.wait(); + f1.get(); + BOOST_CHECK( ! f1.valid() ); +} + +void test_future_wait_for() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int > p1; + boost::fibers::future< int > f1 = p1.get_future(); + + boost::fibers::fiber( boost::fibers::launch::post, fn11, std::move( p1) ).detach(); + + // wait on future + BOOST_CHECK( f1.valid() ); + boost::fibers::future_status status = f1.wait_for( ms(300) ); + BOOST_CHECK( boost::fibers::future_status::timeout == status); + + BOOST_CHECK( f1.valid() ); + status = f1.wait_for( ms(400) ); + BOOST_CHECK( boost::fibers::future_status::ready == status); + + BOOST_CHECK( f1.valid() ); + f1.wait(); +} + +void test_future_wait_for_ref() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int& > p1; + boost::fibers::future< int& > f1 = p1.get_future(); + + boost::fibers::fiber( boost::fibers::launch::post, fn12, std::move( p1) ).detach(); + + // wait on future + BOOST_CHECK( f1.valid() ); + boost::fibers::future_status status = f1.wait_for( ms(300) ); + BOOST_CHECK( boost::fibers::future_status::timeout == status); + + BOOST_CHECK( f1.valid() ); + status = f1.wait_for( ms(400) ); + BOOST_CHECK( boost::fibers::future_status::ready == status); + + BOOST_CHECK( f1.valid() ); + f1.wait(); +} + +void test_future_wait_for_void() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< void > p1; + boost::fibers::future< void > f1 = p1.get_future(); + + boost::fibers::fiber( boost::fibers::launch::post, fn13, std::move( p1) ).detach(); + + // wait on future + BOOST_CHECK( f1.valid() ); + boost::fibers::future_status status = f1.wait_for( ms(300) ); + BOOST_CHECK( boost::fibers::future_status::timeout == status); + + BOOST_CHECK( f1.valid() ); + status = f1.wait_for( ms(400) ); + BOOST_CHECK( boost::fibers::future_status::ready == status); + + BOOST_CHECK( f1.valid() ); + f1.wait(); +} + +void test_future_wait_until() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int > p1; + boost::fibers::future< int > f1 = p1.get_future(); + + boost::fibers::fiber( boost::fibers::launch::post, fn11, std::move( p1) ).detach(); + + // wait on future + BOOST_CHECK( f1.valid() ); + boost::fibers::future_status status = f1.wait_until( Clock::now() + ms(300) ); + BOOST_CHECK( boost::fibers::future_status::timeout == status); + + BOOST_CHECK( f1.valid() ); + status = f1.wait_until( Clock::now() + ms(400) ); + BOOST_CHECK( boost::fibers::future_status::ready == status); + + BOOST_CHECK( f1.valid() ); + f1.wait(); +} + +void test_future_wait_until_ref() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< int& > p1; + boost::fibers::future< int& > f1 = p1.get_future(); + + boost::fibers::fiber( boost::fibers::launch::post, fn12, std::move( p1) ).detach(); + + // wait on future + BOOST_CHECK( f1.valid() ); + boost::fibers::future_status status = f1.wait_until( Clock::now() + ms(300) ); + BOOST_CHECK( boost::fibers::future_status::timeout == status); + + BOOST_CHECK( f1.valid() ); + status = f1.wait_until( Clock::now() + ms(400) ); + BOOST_CHECK( boost::fibers::future_status::ready == status); + + BOOST_CHECK( f1.valid() ); + f1.wait(); +} + +void test_future_wait_until_void() { + // future retrieved from promise is valid (if it is the first) + boost::fibers::promise< void > p1; + boost::fibers::future< void > f1 = p1.get_future(); + + boost::fibers::fiber( boost::fibers::launch::post, fn13, std::move( p1) ).detach(); + + // wait on future + BOOST_CHECK( f1.valid() ); + boost::fibers::future_status status = f1.wait_until( Clock::now() + ms(300) ); + BOOST_CHECK( boost::fibers::future_status::timeout == status); + + BOOST_CHECK( f1.valid() ); + status = f1.wait_until( Clock::now() + ms(400) ); + BOOST_CHECK( boost::fibers::future_status::ready == status); + + BOOST_CHECK( f1.valid() ); + f1.wait(); +} + +void test_future_wait_with_fiber_1() { + boost::fibers::promise< int > p1; + boost::fibers::fiber( boost::fibers::launch::post, fn1, & p1, 7).detach(); + + boost::fibers::future< int > f1 = p1.get_future(); + + // wait on future + BOOST_CHECK( 7 == f1.get() ); +} + +void test_future_wait_with_fiber_2() { + boost::fibers::fiber( boost::fibers::launch::post, fn2).join(); +} + + +boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) { + boost::unit_test_framework::test_suite* test = + BOOST_TEST_SUITE("Boost.Fiber: future test suite"); + + test->add(BOOST_TEST_CASE(test_future_create)); + test->add(BOOST_TEST_CASE(test_future_create_ref)); + test->add(BOOST_TEST_CASE(test_future_create_void)); + test->add(BOOST_TEST_CASE(test_future_move)); + test->add(BOOST_TEST_CASE(test_future_move_ref)); + test->add(BOOST_TEST_CASE(test_future_move_void)); + test->add(BOOST_TEST_CASE(test_future_get)); + test->add(BOOST_TEST_CASE(test_future_get_move)); + test->add(BOOST_TEST_CASE(test_future_get_ref)); + test->add(BOOST_TEST_CASE(test_future_get_void)); + test->add(BOOST_TEST_CASE(test_future_share)); + test->add(BOOST_TEST_CASE(test_future_share_ref)); + test->add(BOOST_TEST_CASE(test_future_share_void)); + test->add(BOOST_TEST_CASE(test_future_wait)); + test->add(BOOST_TEST_CASE(test_future_wait_ref)); + test->add(BOOST_TEST_CASE(test_future_wait_void)); + test->add(BOOST_TEST_CASE(test_future_wait_for)); + test->add(BOOST_TEST_CASE(test_future_wait_for_ref)); + test->add(BOOST_TEST_CASE(test_future_wait_for_void)); + test->add(BOOST_TEST_CASE(test_future_wait_until)); + test->add(BOOST_TEST_CASE(test_future_wait_until_ref)); + test->add(BOOST_TEST_CASE(test_future_wait_until_void)); + test->add(BOOST_TEST_CASE(test_future_wait_with_fiber_1)); + test->add(BOOST_TEST_CASE(test_future_wait_with_fiber_2)); + + return test; +} |