2
0
mirror of https://github.com/boostorg/cobalt.git synced 2026-01-19 04:02:16 +00:00
Files
cobalt/test/left_race.cpp
Klemens Morgenstern a0ca8a497f switched to boost.test
2023-10-19 01:57:50 +08:00

159 lines
4.4 KiB
C++

//
// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
//
// 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 <boost/cobalt/race.hpp>
#include <boost/cobalt/generator.hpp>
#include <boost/cobalt/promise.hpp>
#include <boost/cobalt/op.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/test/unit_test.hpp>
#include "test.hpp"
using namespace boost;
static cobalt::promise<std::chrono::milliseconds::rep> dummy(
asio::any_io_executor exec,
std::chrono::milliseconds ms = std::chrono::milliseconds(50))
{
asio::steady_timer tim{exec, ms};
co_await tim.async_wait(cobalt::use_op);
co_return ms.count();
}
static cobalt::generator<int> gen(asio::any_io_executor exec)
{
asio::steady_timer tim{exec, std::chrono::milliseconds(50000)};
co_await tim.async_wait(cobalt::use_op);
co_return 123;
}
BOOST_AUTO_TEST_SUITE(left_race_);
#if !defined(BOOST_COBALT_NO_SELF_DELETE)
CO_TEST_CASE(variadic)
{
auto exec = co_await asio::this_coro::executor;
auto d1 = dummy(exec, std::chrono::milliseconds(100));
auto d2 = dummy(exec, std::chrono::milliseconds( 50));
auto g = gen(exec);
auto c = co_await left_race(d1, d2, dummy(exec, std::chrono::milliseconds(100000)), g);
BOOST_CHECK(c.index() == 1u);
BOOST_CHECK(boost::variant2::get<1>(c) == 50);
BOOST_CHECK(d1);
BOOST_CHECK(!d1.ready());
BOOST_CHECK( d2.ready());
BOOST_CHECK(100 == co_await d1);
BOOST_CHECK(!d1);
BOOST_CHECK( d1.ready());
co_await d2;
g.cancel();
BOOST_CHECK_THROW(co_await g, boost::system::system_error);
}
#endif
CO_TEST_CASE(list)
{
auto exec = co_await asio::this_coro::executor;
std::vector<cobalt::promise<std::chrono::milliseconds::rep>> vec;
vec.push_back(dummy(exec, std::chrono::milliseconds(100)));
vec.push_back(dummy(exec, std::chrono::milliseconds( 50)));
vec.push_back(dummy(exec, std::chrono::milliseconds(100000)));
auto c = co_await left_race(vec);
BOOST_CHECK(c.first == 1u);
BOOST_CHECK(c.second == 50);
BOOST_CHECK(!vec[0].ready());
BOOST_CHECK( vec[1].ready());
BOOST_CHECK(co_await vec[0]);
BOOST_CHECK( vec[0].ready());
BOOST_CHECK( vec[1].ready());
vec[2].cancel();
BOOST_CHECK( vec[2]);
BOOST_CHECK_THROW(co_await vec[2], boost::system::system_error);
BOOST_CHECK_THROW(co_await vec[2], boost::system::system_error);
BOOST_CHECK(!vec[2]);
}
CO_TEST_CASE(empty_list)
{
auto exec = co_await asio::this_coro::executor;
std::vector<cobalt::promise<std::size_t>> vec;
try {
BOOST_CHECK_THROW(co_await left_race(vec), boost::system::system_error);
}
catch(...) {}
}
CO_TEST_CASE(stop_)
{
auto d = dummy(co_await asio::this_coro::executor,
std::chrono::milliseconds(10));
BOOST_CHECK((co_await left_race(d, stop())).index() == 0);
}
CO_TEST_CASE(compliance)
{
auto exec = co_await asio::this_coro::executor;
auto d = dummy(exec, std::chrono::milliseconds(100000));
{
immediate i;
BOOST_CHECK((co_await left_race(d, i)).index() == 1);
}
{
immediate_bool i;
BOOST_CHECK((co_await left_race(d, i)).index() == 1);
}
{
immediate_handle i;
BOOST_CHECK((co_await left_race(d, i)).index() == 1);
}
{
posted p;
BOOST_CHECK((co_await left_race(d, p)).index() == 1);
}
{
posted_bool p;
BOOST_CHECK((co_await left_race(d, p)).index() == 1);
}
{
posted_handle p;
BOOST_CHECK((co_await left_race(d, p)).index() == 1);
}
d.cancel();
BOOST_CHECK_THROW(co_await d, boost::system::system_error);
}
CO_TEST_CASE(immediate_timer)
{
immediate i;
asio::steady_timer tim{co_await cobalt::this_coro::executor, std::chrono::steady_clock::time_point::max()};
BOOST_CHECK((co_await left_race(tim.async_wait(cobalt::use_op), i)) == 1);
}
CO_TEST_CASE(compliance_ranged)
{
BOOST_CHECK(co_await cobalt::left_race(std::vector<immediate>(3u)) == 0);
BOOST_CHECK(co_await cobalt::left_race(std::vector<immediate_bool>(1u)) == 0);
BOOST_CHECK(co_await cobalt::left_race(std::vector<immediate_handle>(1u)) == 0);
BOOST_CHECK(co_await cobalt::left_race(std::vector<posted>(3u)) == 0);
BOOST_CHECK(co_await cobalt::left_race(std::vector<posted_bool>(1u)) == 0);
BOOST_CHECK(co_await cobalt::left_race(std::vector<posted_handle>(1u)) == 0);
}
BOOST_AUTO_TEST_SUITE_END();