Merge 'tests: utils: error injection: print time duration instead of count' from Kefu Chai

before this change, we always cast the wait duration to millisecond,
even if it could be using a higher resolution. actually
`std::chrono::steady_clock` is using `nanosecond` for its duration,
so if we inject a deadline using `steady_clock`, we could be awaken
earlier due to the narrowing of the duration type caused by the
duration_cast.

in this change, we just use the duration as it is. this should allow
the caller to use the resolution provided by Seastar without losing
the precision. the tests are updated to print the time duration
instead of count to provide information with a higher resolution.

Fixes #15902

Closes scylladb/scylladb#16264

* github.com:scylladb/scylladb:
  tests: utils: error injection: print time duration instead of count
  error_injection: do not cast to milliseconds when injecting timeout
This commit is contained in:
Pavel Emelyanov
2024-01-25 16:13:27 +03:00
2 changed files with 21 additions and 9 deletions

View File

@@ -29,6 +29,14 @@ using steady_clock = std::chrono::steady_clock;
constexpr milliseconds sleep_msec(10); // Injection time sleep 10 msec
namespace std::chrono {
template<class Clock, class Duration>
std::ostream& boost_test_print_type(std::ostream& os, const std::chrono::time_point<Clock, Duration>& time_point) {
fmt::print(os, "{}", time_point);
return os;
}
}
SEASTAR_TEST_CASE(test_inject_noop) {
utils::error_injection<false> errinj;
@@ -93,7 +101,7 @@ SEASTAR_TEST_CASE(test_inject_sleep_duration) {
errinj.enable("future_sleep");
return errinj.inject("future_sleep", sleep_msec).then([start_time] {
auto wait_time = std::chrono::duration_cast<milliseconds>(steady_clock::now() - start_time);
BOOST_REQUIRE_GE(wait_time.count(), sleep_msec.count());
BOOST_REQUIRE_GE(wait_time, sleep_msec);
return make_ready_future<>();
});
}
@@ -106,7 +114,8 @@ SEASTAR_TEST_CASE(test_inject_sleep_deadline_steady_clock) {
auto deadline = steady_clock::now() + sleep_msec;
errinj.enable("future_deadline");
errinj.inject("future_deadline", deadline).then([deadline] {
BOOST_REQUIRE_GE(std::chrono::duration_cast<std::chrono::milliseconds>(steady_clock::now() - deadline).count(), 0);
BOOST_REQUIRE_GE(steady_clock::now() - deadline,
steady_clock::duration::zero());
return make_ready_future<>();
}).get();
});
@@ -120,7 +129,8 @@ SEASTAR_TEST_CASE(test_inject_sleep_deadline_manual_clock) {
auto deadline = seastar::manual_clock::now() + sleep_msec;
errinj.enable("future_deadline");
auto f = errinj.inject("future_deadline", deadline).then([deadline] {
BOOST_REQUIRE_GE(std::chrono::duration_cast<std::chrono::milliseconds>(seastar::manual_clock::now() - deadline).count(), 0);
BOOST_REQUIRE_GE(seastar::manual_clock::now() - deadline,
seastar::manual_clock::duration::zero());
return make_ready_future<>();
});
manual_clock::advance(sleep_msec);
@@ -136,7 +146,8 @@ SEASTAR_TEST_CASE(test_inject_sleep_deadline_manual_clock_lambda) {
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);
BOOST_REQUIRE_GE(seastar::manual_clock::now() - deadline,
seastar::manual_clock::duration::zero());
return make_ready_future<>();
});
manual_clock::advance(sleep_msec);
@@ -152,7 +163,8 @@ SEASTAR_TEST_CASE(test_inject_sleep_deadline_db_clock) {
auto deadline = db::timeout_clock::now() + sleep_msec;
errinj.enable("future_deadline");
errinj.inject("future_deadline", deadline).then([deadline] {
BOOST_REQUIRE_GE(std::chrono::duration_cast<std::chrono::milliseconds>(db::timeout_clock::now() - deadline).count(), 0);
BOOST_REQUIRE_GE(db::timeout_clock::now() - deadline,
db::timeout_clock::duration::zero());
return make_ready_future<>();
}).get();
});
@@ -163,8 +175,8 @@ SEASTAR_TEST_CASE(test_inject_future_disabled) {
auto start_time = steady_clock::now();
return errinj.inject("futid", sleep_msec).then([start_time] {
auto wait_time = std::chrono::duration_cast<milliseconds>(steady_clock::now() - start_time);
BOOST_REQUIRE_LT(wait_time.count(), sleep_msec.count());
auto wait_time = steady_clock::now() - start_time;
BOOST_REQUIRE_LT(wait_time, sleep_msec);
return make_ready_future<>();
});
}

View File

@@ -346,8 +346,8 @@ public:
}
// Time left until deadline
std::chrono::milliseconds duration = std::chrono::duration_cast<std::chrono::milliseconds>(deadline - Clock::now());
errinj_logger.debug("Triggering sleep injection \"{}\" ({}ms)", name, duration.count());
auto duration = deadline - Clock::now();
errinj_logger.debug("Triggering sleep injection \"{}\" ({})", name, duration);
return seastar::sleep<Clock>(duration);
}