utils: add timeout error injection with lambda
Even though calling then() on a ready future does not allocate a continuation, calling then on the result of it will allocate. This error injection only adds a continuation in the dependency chain if error injections are enabled at compile timeand this particular error injection is enabled. Signed-off-by: Alejo Sanchez <alejo.sanchez@scylladb.com>
This commit is contained in:
@@ -134,6 +134,22 @@ SEASTAR_TEST_CASE(test_inject_sleep_deadline_manual_clock) {
|
||||
});
|
||||
}
|
||||
|
||||
SEASTAR_TEST_CASE(test_inject_sleep_deadline_manual_clock_lambda) {
|
||||
return do_with_cql_env_thread([] (cql_test_env& e) {
|
||||
utils::error_injection<true> errinj;
|
||||
|
||||
// Inject sleep, deadline short-circuit
|
||||
auto deadline = seastar::manual_clock::now() + sleep_msec;
|
||||
errinj.enable("future_deadline");
|
||||
auto f = errinj.inject("future_deadline", deadline, [deadline] {
|
||||
BOOST_REQUIRE_GE(std::chrono::duration_cast<std::chrono::milliseconds>(seastar::manual_clock::now() - deadline).count(), 0);
|
||||
return make_ready_future<>();
|
||||
});
|
||||
manual_clock::advance(sleep_msec);
|
||||
f.get();
|
||||
});
|
||||
}
|
||||
|
||||
SEASTAR_TEST_CASE(test_inject_sleep_deadline_db_clock) {
|
||||
return do_with_cql_env_thread([] (cql_test_env& e) {
|
||||
utils::error_injection<true> errinj;
|
||||
|
||||
@@ -224,6 +224,25 @@ public:
|
||||
return seastar::sleep<Clock>(duration);
|
||||
}
|
||||
|
||||
// \brief Inject a sleep to deadline with lambda(timeout)
|
||||
// Avoid adding a sleep continuation in the chain for disabled error injection
|
||||
template <typename Clock, typename Duration, typename Func>
|
||||
[[gnu::always_inline]]
|
||||
std::result_of_t<Func()> inject(const std::string_view& name, std::chrono::time_point<Clock, Duration> deadline,
|
||||
Func&& func) {
|
||||
if (is_enabled(name)) {
|
||||
if (is_one_shot(name)) {
|
||||
disable(name);
|
||||
}
|
||||
std::chrono::milliseconds duration = std::chrono::duration_cast<std::chrono::milliseconds>(deadline - Clock::now());
|
||||
errinj_logger.debug("Triggering sleep injection \"{}\" ({}ms)", name, duration.count());
|
||||
return seastar::sleep<Clock>(duration).then([func = std::move(func)] {
|
||||
return func(); });
|
||||
} else {
|
||||
return func();
|
||||
}
|
||||
}
|
||||
|
||||
// \brief Inject exception
|
||||
// \param exception_factory function returning an exception pointer
|
||||
template <typename Func>
|
||||
@@ -316,6 +335,15 @@ public:
|
||||
return make_ready_future<>();
|
||||
}
|
||||
|
||||
// \brief Inject a sleep to deadline (timeout) with lambda
|
||||
// Avoid adding a continuation in the chain for disabled error injections
|
||||
template <typename Clock, typename Duration, typename Func>
|
||||
[[gnu::always_inline]]
|
||||
std::result_of_t<Func()> inject(const std::string_view& name, std::chrono::time_point<Clock, Duration> deadline,
|
||||
Func&& func) {
|
||||
return func();
|
||||
}
|
||||
|
||||
// Inject exception
|
||||
template <typename Func>
|
||||
[[gnu::always_inline]]
|
||||
|
||||
Reference in New Issue
Block a user