浏览代码

* Implemented 'timeout' for futures and streams

master
bergmann 4 年前
父节点
当前提交
e8d33bdc52
共有 31 个文件被更改,包括 589 次插入71 次删除
  1. +2
    -0
      include/asyncpp/core.h
  2. +10
    -0
      include/asyncpp/core/future.h
  3. +37
    -1
      include/asyncpp/core/future.inl
  4. +16
    -1
      include/asyncpp/core/future.pre.h
  5. +3
    -3
      include/asyncpp/core/misc.inl
  6. +3
    -0
      include/asyncpp/core/result.h
  7. +2
    -0
      include/asyncpp/core/result.inl
  8. +10
    -0
      include/asyncpp/core/stream.h
  9. +37
    -1
      include/asyncpp/core/stream.inl
  10. +14
    -1
      include/asyncpp/core/stream.pre.h
  11. +0
    -9
      include/asyncpp/timer.h
  12. +13
    -0
      include/asyncpp/timing.h
  13. +5
    -4
      include/asyncpp/timing/delay.h
  14. +8
    -7
      include/asyncpp/timing/delay.inl
  15. +1
    -1
      include/asyncpp/timing/delay.pre.h
  16. +1
    -1
      include/asyncpp/timing/impl/registration.h
  17. +1
    -1
      include/asyncpp/timing/impl/registration.inl
  18. +1
    -1
      include/asyncpp/timing/impl/timer_base.h
  19. +1
    -1
      include/asyncpp/timing/impl/timer_base.inl
  20. +1
    -1
      include/asyncpp/timing/impl/timer_base.pre.h
  21. +4
    -4
      include/asyncpp/timing/interval.h
  22. +5
    -5
      include/asyncpp/timing/interval.inl
  23. +94
    -0
      include/asyncpp/timing/timeout.h
  24. +85
    -0
      include/asyncpp/timing/timeout.inl
  25. +1
    -1
      include/asyncpp/timing/timer.h
  26. +2
    -2
      include/asyncpp/timing/timer.inl
  27. +3
    -3
      test/asyncpp/timing/delay_tests.cpp
  28. +3
    -3
      test/asyncpp/timing/interval_tests.cpp
  29. +202
    -0
      test/asyncpp/timing/timeout_tests.cpp
  30. +21
    -17
      test/asyncpp/timing/timer_tests.cpp
  31. +3
    -3
      test/helper/now_mock.h

+ 2
- 0
include/asyncpp/core.h 查看文件

@@ -1,10 +1,12 @@
#pragma once

#include "core/future.h"
#include "core/misc.h"
#include "core/result.h"
#include "core/stream.h"
#include "core/task.h"

#include "core/future.inl"
#include "core/misc.inl"
#include "core/result.inl"
#include "core/stream.inl"

+ 10
- 0
include/asyncpp/core/future.h 查看文件

@@ -52,6 +52,16 @@ namespace asyncpp
template<typename X_lambda>
inline auto and_then(X_lambda&& p_lambda);

#ifdef asyncpp_timing
/**
* @brief Throw an execption if the timeout has passed.
*
* This method is only enabled if timer.h is included before.
*/
template<typename X_base, typename X_ratio>
inline auto timeout(const duration<X_base, X_ratio>& p_timeout);
#endif

public:
inline pointer operator->();
inline reference operator*();


+ 37
- 1
include/asyncpp/core/future.inl 查看文件

@@ -5,6 +5,10 @@
#include "future/map.inl"
#include "future/and_then.inl"

#ifdef asyncpp_timing
#include <asyncpp/timing/timeout.inl>
#endif

namespace asyncpp
{

@@ -38,6 +42,21 @@ namespace asyncpp
std::forward<X_lambda>(p_lambda)));
}

#ifdef asyncpp_timing
template<typename T_impl>
template<typename X_future, typename X_base, typename X_ratio>
auto future_base<T_impl>
::timeout(X_future&& self, const duration<X_base, X_ratio>& p_timeout)
{
using future_type = X_future;
using timeout_type = timing::timeout<future_type>;

return as_future(timeout_type(
std::forward<X_future>(self),
p_timeout));
}
#endif

/* future */

template<
@@ -76,6 +95,18 @@ namespace asyncpp
::and_then(X_lambda&& p_lambda)
{ return trait_type::and_then(std::move(*this), std::forward<X_lambda>(p_lambda)); }

#ifdef asyncpp_timing
template<
typename T_value,
typename T_impl>
template<
typename X_base,
typename X_ratio>
auto future<T_value, T_impl>
::timeout(const duration<X_base, X_ratio>& p_timeout)
{ return trait_type::timeout(std::move(*this), p_timeout); }
#endif

template<
typename T_value,
typename T_impl>
@@ -107,7 +138,7 @@ namespace asyncpp
/* misc */

template<typename X_value>
constexpr decltype(auto) as_future(X_value&& value)
constexpr future<X_value> as_future(X_value&& value)
{
using value_type = X_value;
using future_type = future<value_type>;
@@ -115,4 +146,9 @@ namespace asyncpp
return future_type(std::forward<X_value>(value));
}

template<typename T>
struct is_future<future<T>, void>
: public std::true_type
{ };

}

+ 16
- 1
include/asyncpp/core/future.pre.h 查看文件

@@ -1,5 +1,7 @@
#pragma once

#include "misc.h"

namespace asyncpp
{

@@ -18,6 +20,11 @@ namespace asyncpp

template<typename X_future, typename X_lambda>
static inline auto and_then(X_future&& self, X_lambda&& p_lambda);

#ifdef asyncpp_timing
template<typename X_future, typename X_base, typename X_ratio>
static inline auto timeout(X_future&& self, const duration<X_base, X_ratio>& p_timeout);
#endif
};

template<typename T, typename = void>
@@ -28,10 +35,18 @@ namespace asyncpp
typename T_impl = future_trait<std::decay_t<T_object>>>
struct future;

template<typename T, typename = void>
struct is_future
: public std::false_type
{ };

template<typename T>
constexpr decltype(auto) is_future_v = is_future<T>::value;

/**
* @brief Construct a future from the given value.
*/
template<typename X_value>
constexpr decltype(auto) as_future(X_value&& value);
constexpr future<X_value> as_future(X_value&& value);

}

+ 3
- 3
include/asyncpp/core/misc.inl 查看文件

@@ -2,8 +2,8 @@

#include "misc.h"

namespace asyncpp {
namespace timer {
namespace asyncpp
{

#ifndef __asyncpp_has_impl_timer_now
time_point now()
@@ -34,4 +34,4 @@ namespace timer {
}
}

} }
}

+ 3
- 0
include/asyncpp/core/result.h 查看文件

@@ -119,6 +119,9 @@ namespace asyncpp
inline const_reference_type operator* () const;
};

template<bool for_stream>
struct result<for_stream, void>;

}

}

+ 2
- 0
include/asyncpp/core/result.inl 查看文件

@@ -120,6 +120,8 @@ namespace asyncpp
::operator* () const
{ return value(); }

/* result<void> */

template<bool for_stream>
struct result<for_stream, void>
{


+ 10
- 0
include/asyncpp/core/stream.h 查看文件

@@ -46,6 +46,16 @@ namespace asyncpp
template<typename X_lambda>
inline auto for_each(X_lambda&& p_lambda);

#ifdef asyncpp_timing
/**
* @brief Throw an execption if the timeout has passed.
*
* This method is only enabled if timer.h is included before.
*/
template<typename X_base, typename X_ratio>
inline auto timeout(const duration<X_base, X_ratio>& p_timeout);
#endif

public:
inline pointer operator->();
inline reference operator*();


+ 37
- 1
include/asyncpp/core/stream.inl 查看文件

@@ -4,6 +4,10 @@

#include "stream/for_each.inl"

#ifdef asyncpp_timing
#include <asyncpp/timing/timeout.inl>
#endif

namespace asyncpp
{

@@ -23,6 +27,21 @@ namespace asyncpp
std::forward<X_lambda>(p_lambda)));
}

#ifdef asyncpp_timing
template<typename T_impl>
template<typename X_stream, typename X_base, typename X_ratio>
auto stream_base<T_impl>
::timeout(X_stream&& self, const duration<X_base, X_ratio>& p_timeout)
{
using stream_type = X_stream;
using timeout_type = timing::timeout<stream_type>;

return as_stream(timeout_type(
std::forward<X_stream>(self),
p_timeout));
}
#endif

/* stream */

template<
@@ -52,6 +71,18 @@ namespace asyncpp
::for_each(X_lambda&& p_lambda)
{ return trait_type::for_each(std::move(*this), std::forward<X_lambda>(p_lambda)); }

#ifdef asyncpp_timing
template<
typename T_value,
typename T_impl>
template<
typename X_base,
typename X_ratio>
auto stream<T_value, T_impl>
::timeout(const duration<X_base, X_ratio>& p_timeout)
{ return trait_type::timeout(std::move(*this), p_timeout); }
#endif

template<
typename T_value,
typename T_impl>
@@ -83,7 +114,7 @@ namespace asyncpp
/* misc */

template<typename X_value>
constexpr decltype(auto) as_stream(X_value&& value)
constexpr stream<X_value> as_stream(X_value&& value)
{
using value_type = X_value;
using stream_type = stream<value_type>;
@@ -91,4 +122,9 @@ namespace asyncpp
return stream_type(std::forward<X_value>(value));
}

template<typename T>
struct is_stream<stream<T>, void>
: public std::true_type
{ };

}

+ 14
- 1
include/asyncpp/core/stream.pre.h 查看文件

@@ -15,6 +15,11 @@ namespace asyncpp

template<typename X_stream, typename X_lambda>
static inline auto for_each(X_stream&& self, X_lambda&& p_lambda);

#ifdef asyncpp_timing
template<typename X_stream, typename X_base, typename X_ratio>
static inline auto timeout(X_stream&& self, const duration<X_base, X_ratio>& p_timeout);
#endif
};

template<typename T, typename = void>
@@ -25,10 +30,18 @@ namespace asyncpp
typename T_impl = stream_trait<std::decay_t<T_object>>>
struct stream;

template<typename T, typename = void>
struct is_stream
: public std::false_type
{ };

template<typename T>
constexpr decltype(auto) is_stream_v = is_stream<T>::value;

/**
* @brief Construct a stream from the given value.
*/
template<typename X_value>
constexpr decltype(auto) as_stream(X_value&& value);
constexpr stream<X_value> as_stream(X_value&& value);

}

+ 0
- 9
include/asyncpp/timer.h 查看文件

@@ -1,9 +0,0 @@
#pragma once

#include "timer/delay.h"
#include "timer/interval.h"
#include "timer/timer.h"

#include "timer/delay.inl"
#include "timer/interval.inl"
#include "timer/timer.inl"

+ 13
- 0
include/asyncpp/timing.h 查看文件

@@ -0,0 +1,13 @@
#pragma once

#define asyncpp_timing

#include "timing/delay.h"
#include "timing/interval.h"
#include "timing/timeout.h"
#include "timing/timer.h"

#include "timing/delay.inl"
#include "timing/interval.inl"
#include "timing/timeout.inl"
#include "timing/timer.inl"

include/asyncpp/timer/delay.h → include/asyncpp/timing/delay.h 查看文件

@@ -1,12 +1,13 @@
#pragma once

#include <asyncpp/core/misc.h>
#include <asyncpp/core/future.h>

#include "timer.h"
#include "delay.pre.h"

namespace asyncpp {
namespace timer {
namespace timing {

struct delay
{
@@ -56,11 +57,11 @@ namespace timer {
namespace asyncpp
{

/* future_impl for timer::delay */
/* future_impl for timing::delay */

template<>
struct future_trait<timer::delay, void>
: public future_base<future<timer::delay, void>>
struct future_trait<timing::delay, void>
: public future_base<future<timing::delay, void>>
{
using value_type = void;
using result_type = future_result<value_type>;

include/asyncpp/timer/delay.inl → include/asyncpp/timing/delay.inl 查看文件

@@ -2,13 +2,14 @@

#include <asyncpp/core/future.pre.h>
#include <asyncpp/core/result.pre.h>
#include <asyncpp/core/result.inl>

#include "delay.h"

#include "timer.inl"

namespace asyncpp {
namespace timer {
namespace timing {

/* delay */

@@ -19,7 +20,7 @@ namespace timer {

template<typename T_base, typename T_ratio>
delay::delay(const duration<T_base, T_ratio>& p_duration)
: _deadline (clock::now() + p_duration)
: _deadline (asyncpp::now() + p_duration)
, _registration ()
{ }

@@ -39,7 +40,7 @@ namespace timer {
void delay::reset(const duration<T_base, T_ratio>& p_duration)
{
__impl::timer_base::unregister_resource(_registration);
_deadline = now() + p_duration;
_deadline = asyncpp::now() + p_duration;
}

} }
@@ -47,19 +48,19 @@ namespace timer {
namespace asyncpp
{

/* future_impl for timer::delay */
/* future_impl for timing::delay */

template<typename X_future>
auto future_trait<timer::delay, void>
auto future_trait<timing::delay, void>
::poll(X_future& self)
{
auto now = timer::now();
auto now = asyncpp::now();

if (self->_deadline <= now)
return result_type::ready();

if (self->_registration.expired())
self->_registration = timer::__impl::timer_base::register_resource(self->_deadline);
self->_registration = timing::__impl::timer_base::register_resource(self->_deadline);

return result_type::not_ready();
}

include/asyncpp/timer/delay.pre.h → include/asyncpp/timing/delay.pre.h 查看文件

@@ -1,7 +1,7 @@
#pragma once

namespace asyncpp {
namespace timer {
namespace timing {

struct delay;


include/asyncpp/timer/impl/registration.h → include/asyncpp/timing/impl/registration.h 查看文件

@@ -8,7 +8,7 @@
#include "timer_base.pre.h"

namespace asyncpp {
namespace timer {
namespace timing {
namespace __impl {

struct registration

include/asyncpp/timer/impl/registration.inl → include/asyncpp/timing/impl/registration.inl 查看文件

@@ -3,7 +3,7 @@
#include "registration.h"

namespace asyncpp {
namespace timer {
namespace timing {
namespace __impl {

/* registration */

include/asyncpp/timer/impl/timer_base.h → include/asyncpp/timing/impl/timer_base.h 查看文件

@@ -11,7 +11,7 @@
#include "registration.h"

namespace asyncpp {
namespace timer {
namespace timing {
namespace __impl {

struct timer_base

include/asyncpp/timer/impl/timer_base.inl → include/asyncpp/timing/impl/timer_base.inl 查看文件

@@ -3,7 +3,7 @@
#include "timer_base.h"

namespace asyncpp {
namespace timer {
namespace timing {
namespace __impl {

/* timer_base::inner_less_compare */

include/asyncpp/timer/impl/timer_base.pre.h → include/asyncpp/timing/impl/timer_base.pre.h 查看文件

@@ -1,7 +1,7 @@
#pragma once

namespace asyncpp {
namespace timer {
namespace timing {
namespace __impl {

struct timer_base;

include/asyncpp/timer/interval.h → include/asyncpp/timing/interval.h 查看文件

@@ -7,7 +7,7 @@
#include "delay.h"

namespace asyncpp {
namespace timer {
namespace timing {

struct interval
{
@@ -51,11 +51,11 @@ namespace timer {
namespace asyncpp
{

/* stream_trait for timer::interval */
/* stream_trait for timing::interval */

template<>
struct stream_trait<timer::interval, void>
: public stream_base<stream<timer::interval, void>>
struct stream_trait<timing::interval, void>
: public stream_base<stream<timing::interval, void>>
{
using value_type = void;
using result_type = stream_result<value_type>;

include/asyncpp/timer/interval.inl → include/asyncpp/timing/interval.inl 查看文件

@@ -6,7 +6,7 @@
#include "interval.h"

namespace asyncpp {
namespace timer {
namespace timing {

/* interval */

@@ -14,7 +14,7 @@ namespace timer {
interval::interval(
const asyncpp::duration<T_base, T_ratio>& p_duration,
time_point p_deadline)
: interval(clock::now() + p_duration, p_duration, p_deadline)
: interval(asyncpp::now() + p_duration, p_duration, p_deadline)
{ }

template<typename T_base, typename T_ratio>
@@ -35,11 +35,11 @@ namespace timer {
namespace asyncpp
{

/* stream_trait for timer::interval */
/* stream_trait for timing::interval */

template<typename X_stream>
typename stream_trait<timer::interval, void>::result_type
stream_trait<timer::interval, void>
typename stream_trait<timing::interval, void>::result_type
stream_trait<timing::interval, void>
::poll(X_stream& self)
{
auto ret = self->_delay.poll();

+ 94
- 0
include/asyncpp/timing/timeout.h 查看文件

@@ -0,0 +1,94 @@
#pragma once

#include <cppcore/misc/exception.h>

#include <asyncpp/core/misc.h>
#include <asyncpp/core/future.h>
#include <asyncpp/core/stream.h>

#include "delay.h"

namespace asyncpp {
namespace timing {

struct timeout_exception
: public cppcore::exception
{
using cppcore::exception::exception;
};

template<typename T_inner>
struct timeout
{
public:
using inner_type = T_inner;
using delay_future_type = future<delay>;

public:
friend struct stream_trait<timeout, void>;
friend struct future_trait<timeout, void>;

private:
inner_type _inner; //!< Inner future / stream.
clock::duration _timeout; //!< Timeout.
delay_future_type _delay; //!< Delay future.

public:
/**
* @brief Constructor.
*/
template<typename X_inner, typename X_base, typename X_ratio>
inline timeout(
X_inner&& p_inner,
const duration<X_base, X_ratio>& p_timeout);

/**
* @brief Reset the deadline.
*/
template<typename X_base, typename X_ratio>
inline void reset(
const duration<X_base, X_ratio>& p_timeout);
};

} }

namespace asyncpp
{

/* future_trait for timing::timeout */

template<typename T_inner>
struct future_trait<
timing::timeout<T_inner>,
std::enable_if_t<is_future_v<T_inner>>
>
: public future_base<future<timing::timeout<T_inner>, void>>
{
using inner_type = T_inner;
using timeout_type = timing::timeout<inner_type>;
using value_type = typename inner_type::value_type;
using result_type = typename inner_type::result_type;

template<typename X_future>
static inline result_type poll(X_future& self);
};

/* stream_trait for timing::timeout */

template<typename T_inner>
struct stream_trait<
timing::timeout<T_inner>,
std::enable_if_t<is_stream_v<T_inner>>
>
: public stream_base<stream<timing::timeout<T_inner>, void>>
{
using inner_type = T_inner;
using timeout_type = timing::timeout<inner_type>;
using value_type = typename inner_type::value_type;
using result_type = typename inner_type::result_type;

template<typename X_stream>
static inline result_type poll(X_stream& self);
};

}

+ 85
- 0
include/asyncpp/timing/timeout.inl 查看文件

@@ -0,0 +1,85 @@
#pragma once

#include <asyncpp/core/misc.inl>

#include "timeout.h"

namespace asyncpp {
namespace timing {

/* timer */

template<typename T_inner>
template<typename X_inner, typename X_base, typename X_ratio>
timeout<T_inner>
::timeout(
X_inner&& p_inner,
const duration<X_base, X_ratio>& p_duration)
: _inner (std::forward<X_inner>(p_inner))
, _timeout (p_duration)
, _delay (as_future(delay(asyncpp::now() + p_duration)))
{ }

template<typename T_inner>
template<typename X_base, typename X_ratio>
void timeout<T_inner>
::reset(const duration<X_base, X_ratio>& p_duration)
{
_timeout = p_duration;
_delay->reset(asyncpp::now() + p_duration);
}

} }

namespace asyncpp
{

/* future_trait for timing::timeout */

template<typename T_inner>
template<typename X_future>
typename T_inner::result_type
future_trait<
timing::timeout<T_inner>,
std::enable_if_t<is_future_v<T_inner>>
>
::poll(X_future& self)
{
auto r = self->_inner.poll();

if ( r.is_not_ready()
&& self->_delay.poll())
{
auto new_deadline = self->_delay->deadline() + self->_timeout;
self->_delay->reset(new_deadline);
throw timing::timeout_exception();
}

return r;
}

/* stream_trait for timing::timeout */

template<typename T_inner>
template<typename X_stream>
typename T_inner::result_type
stream_trait<
timing::timeout<T_inner>,
std::enable_if_t<is_stream_v<T_inner>>
>
::poll(X_stream& self)
{
auto r = self->_inner.poll();

if ( r.is_not_ready()
&& self->_delay.poll())
{
auto new_deadline = self->_delay->deadline() + self->_timeout;
self->_delay->reset(new_deadline);
throw timing::timeout_exception();
}

return r;
}

}

include/asyncpp/timer/timer.h → include/asyncpp/timing/timer.h 查看文件

@@ -9,7 +9,7 @@
#include "impl/registration.h"

namespace asyncpp {
namespace timer {
namespace timing {

namespace __impl
{

include/asyncpp/timer/timer.inl → include/asyncpp/timing/timer.inl 查看文件

@@ -9,7 +9,7 @@
#include "impl/registration.inl"

namespace asyncpp {
namespace timer {
namespace timing {

namespace __impl
{
@@ -41,7 +41,7 @@ namespace timer {
template<typename T_inner>
void timer<T_inner>::idle(const asyncpp::time_point * p_deadline)
{
auto now = clock::now();
auto now = asyncpp::now();

{
auto r = _registrations.lock();

test/asyncpp/timer/delay_tests.cpp → test/asyncpp/timing/delay_tests.cpp 查看文件

@@ -3,11 +3,11 @@
#include "../../helper/now_mock.h"

#include <asyncpp.h>
#include <asyncpp/timer.h>
#include <asyncpp/timing.h>

using namespace ::testing;
using namespace ::asyncpp;
using namespace ::asyncpp::timer;
using namespace ::asyncpp::timing;

TEST(delay_tests, poll)
{
@@ -18,7 +18,7 @@ TEST(delay_tests, poll)
.WillOnce(Return(time_point(std::chrono::seconds( 999))))
.WillOnce(Return(time_point(std::chrono::seconds(1000))));

asyncpp::timer::timer t;
asyncpp::timing::timer t;
t.make_current();

{

test/asyncpp/timer/interval_tests.cpp → test/asyncpp/timing/interval_tests.cpp 查看文件

@@ -3,17 +3,17 @@
#include "../../helper/now_mock.h"

#include <asyncpp.h>
#include <asyncpp/timer.h>
#include <asyncpp/timing.h>

using namespace ::testing;
using namespace ::asyncpp;
using namespace ::asyncpp::timer;
using namespace ::asyncpp::timing;

TEST(interval_tests, poll)
{
InSequence seq;
StrictMock<now_mock> m;
asyncpp::timer::timer t;
asyncpp::timing::timer t;
interval i(
time_point(std::chrono::seconds(10)),
std::chrono::seconds(5),

+ 202
- 0
test/asyncpp/timing/timeout_tests.cpp 查看文件

@@ -0,0 +1,202 @@
#include <gtest/gtest.h>

#include "../../helper/now_mock.h"

#include <asyncpp/timing.h>
#include <asyncpp.h>

using namespace ::testing;
using namespace ::asyncpp;
using namespace ::asyncpp::timing;

struct test
{
int i;
};

namespace asyncpp
{

template<>
struct future_trait<test, void>
: public future_base<future<test, void>>
{
using value_type = int;
using result_type = future_result<value_type>;

template<typename X_future>
static inline result_type poll(X_future& self)
{
return self->i
? result_type::ready(self->i)
: result_type::not_ready();
}
};

template<>
struct stream_trait<test, void>
: public stream_base<stream<test, void>>
{
using value_type = int;
using result_type = stream_result<value_type>;

template<typename X_future>
static inline result_type poll(X_future& self)
{
return self->i == 0 ? result_type::not_ready() :
self->i < 0 ? result_type::done() :
result_type::ready(self->i);
}
};

}

TEST(timeout_tests, poll_future_no_timeout)
{
InSequence seq;
StrictMock<now_mock> m;

asyncpp::timing::timer tmr;
tmr.make_current();

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto t = test { 0 };
auto f = as_future(t)
.timeout(std::chrono::seconds(5));

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto r0 = f.poll();
ASSERT_FALSE(r0);

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto r1 = f.poll();
ASSERT_FALSE(r1);

++t.i;

auto r2 = f.poll();
ASSERT_TRUE(r2);
}

TEST(timeout_tests, poll_future_timeout)
{
InSequence seq;
StrictMock<now_mock> m;

asyncpp::timing::timer tmr;
tmr.make_current();

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto t = test { 0 };
auto f = as_future(t)
.timeout(std::chrono::seconds(5));

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto r0 = f.poll();
ASSERT_FALSE(r0);

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(4))));

auto r1 = f.poll();
ASSERT_FALSE(r1);

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(5))));

EXPECT_THROW(f.poll(), timing::timeout_exception);
}

TEST(timeout_tests, poll_stream_no_timeout)
{
InSequence seq;
StrictMock<now_mock> m;

asyncpp::timing::timer tmr;
tmr.make_current();

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto t = test { 0 };
auto f = as_stream(t)
.timeout(std::chrono::seconds(5));

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto r0 = f.poll();
ASSERT_FALSE(r0);

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto r1 = f.poll();
ASSERT_FALSE(r1);

++t.i;

auto r2 = f.poll();
ASSERT_TRUE(r2);
}

TEST(timeout_tests, poll_stream_timeout)
{
InSequence seq;
StrictMock<now_mock> m;

asyncpp::timing::timer tmr;
tmr.make_current();

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto t = test { 0 };
auto f = as_stream(t)
.timeout(std::chrono::seconds(5));

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(0))));

auto r0 = f.poll();
ASSERT_FALSE(r0);

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(4))));

auto r1 = f.poll();
ASSERT_FALSE(r1);

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(5))));

EXPECT_THROW(f.poll(), timing::timeout_exception);

++t.i;

auto r2 = f.poll();
ASSERT_TRUE(r2);

t.i = 0;

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(9))));

auto r3 = f.poll();
ASSERT_FALSE(r3);

EXPECT_CALL(m, now())
.WillOnce(Return(time_point(std::chrono::seconds(10))));

EXPECT_THROW(f.poll(), timing::timeout_exception);
}

test/asyncpp/timer/timer_tests.cpp → test/asyncpp/timing/timer_tests.cpp 查看文件

@@ -4,7 +4,7 @@
#include "../../helper/runtime_mock.h"

#include <asyncpp.h>
#include <asyncpp/timer.h>
#include <asyncpp/timing.h>

using namespace ::testing;
using namespace ::asyncpp;
@@ -12,24 +12,24 @@ using namespace ::asyncpp;
TEST(timer_tests, current)
{
{
timer::timer t;
timing::timer t;

EXPECT_EQ(nullptr, timer::__impl::timer_base::current());
EXPECT_EQ(nullptr, timing::__impl::timer_base::current());

t.make_current();

EXPECT_EQ(&t, timer::__impl::timer_base::current());
EXPECT_EQ(&t, timing::__impl::timer_base::current());

t.clear_current();

EXPECT_EQ(nullptr, timer::__impl::timer_base::current());
EXPECT_EQ(nullptr, timing::__impl::timer_base::current());

t.make_current();

EXPECT_EQ(&t, timer::__impl::timer_base::current());
EXPECT_EQ(&t, timing::__impl::timer_base::current());
}

EXPECT_EQ(nullptr, timer::__impl::timer_base::current());
EXPECT_EQ(nullptr, timing::__impl::timer_base::current());
}

TEST(timer_tests, resource_registration)
@@ -38,14 +38,14 @@ TEST(timer_tests, resource_registration)
EXPECT_CALL(m, now)
.WillRepeatedly(Return(time_point(std::chrono::seconds(0))));

using delay_future_type = decltype(as_future(timer::delay(std::chrono::seconds(10))));
using delay_future_type = decltype(as_future(timing::delay(std::chrono::seconds(10))));

timer::timer t;
timing::timer t;
t.make_current();

auto f1 = std::make_unique<delay_future_type>(timer::delay(std::chrono::seconds(10)));
auto f2 = std::make_unique<delay_future_type>(timer::delay(std::chrono::seconds(20)));
auto f3 = std::make_unique<delay_future_type>(timer::delay(std::chrono::seconds(30)));
auto f1 = std::make_unique<delay_future_type>(timing::delay(std::chrono::seconds(10)));
auto f2 = std::make_unique<delay_future_type>(timing::delay(std::chrono::seconds(20)));
auto f3 = std::make_unique<delay_future_type>(timing::delay(std::chrono::seconds(30)));

EXPECT_EQ(0, t.resource_count());

@@ -80,39 +80,43 @@ TEST(timer_tests, resource_registration)

TEST(timer_tests, idle)
{
using delay_future_type = decltype(as_future(std::declval<timer::delay>()));
using delay_future_type = decltype(as_future(std::declval<timing::delay>()));

time_point x;
InSequence seq;
StrictMock<now_mock> nm;
StrictMock<runtime_mock> rm;
timer::timer<StrictMock<runtime_mock>&> t(rm);
timing::timer<StrictMock<runtime_mock>&> t(rm);
t.make_current();

EXPECT_CALL(nm, now);
EXPECT_CALL(rm, idle(nullptr));

t.idle(nullptr);

EXPECT_CALL(nm, now);
EXPECT_CALL(rm, idle(Pointee(time_point(std::chrono::seconds(5)))));

x = time_point(std::chrono::seconds(5));
t.idle(&x);

EXPECT_CALL(nm, now)
.WillOnce(Return(time_point(std::chrono::seconds(0))));
EXPECT_CALL(nm, now);

auto f = std::make_unique<delay_future_type>(timer::delay(time_point(std::chrono::seconds(10))));
auto f = std::make_unique<delay_future_type>(timing::delay(time_point(std::chrono::seconds(10))));
f->poll();

EXPECT_CALL(nm, now);
EXPECT_CALL(rm, idle(Pointee(time_point(std::chrono::seconds(10)))));

t.idle(nullptr);

EXPECT_CALL(nm, now);
EXPECT_CALL(rm, idle(Pointee(time_point(std::chrono::seconds(5)))));

x = time_point(std::chrono::seconds(5));
t.idle(&x);

EXPECT_CALL(nm, now);
EXPECT_CALL(rm, idle(Pointee(time_point(std::chrono::seconds(10)))));

x = time_point(std::chrono::seconds(15));

+ 3
- 3
test/helper/now_mock.h 查看文件

@@ -27,8 +27,8 @@ public:
MOCK_METHOD0(now, asyncpp::time_point());
};

namespace asyncpp {
namespace timer {
namespace asyncpp
{

time_point now()
{
@@ -37,4 +37,4 @@ namespace timer {
: std::chrono::steady_clock::now();
}

} }
}

正在加载...
取消
保存