1#include <xrpl/beast/asio/io_latency_probe.h> 
    2#include <xrpl/beast/test/yield_to.h> 
    3#include <xrpl/beast/unit_test.h> 
    5#include <boost/asio/basic_waitable_timer.hpp> 
    6#include <boost/asio/deadline_timer.hpp> 
    7#include <boost/asio/executor_work_guard.hpp> 
    8#include <boost/asio/io_context.hpp> 
   16using namespace std::chrono_literals;
 
   22        boost::asio::basic_waitable_timer<std::chrono::steady_clock>;
 
   24#ifdef XRPL_RUNNING_IN_CI 
   35    struct measure_asio_timers
 
   37        using duration = 
typename Clock::duration;
 
   38        using rep = 
typename MeasureClock::duration::rep;
 
   42        measure_asio_timers(duration interval = 100ms, 
size_t num_samples = 50)
 
   45            boost::asio::io_context 
ios;
 
   47                boost::asio::io_context::executor_type>>
 
   48                work{boost::asio::make_work_guard(
ios)};
 
   50            boost::asio::basic_waitable_timer<Clock> timer{
ios};
 
   51            elapsed_times_.
reserve(num_samples);
 
   56            boost::system::error_code wait_err;
 
   60                auto const start{MeasureClock::now()};
 
   62                timer.expires_after(interval);
 
   63                timer.async_wait([&](boost::system::error_code 
const& ec) {
 
   66                    auto const end{MeasureClock::now()};
 
   72                cv.
wait(mainlock, [&done] { 
return done; });
 
   77                boost::asio::detail::throw_error(wait_err, 
"wait");
 
   85            for (
auto const& v : elapsed_times_)
 
   87                sum += 
static_cast<double>(
 
   88                    std::chrono::duration_cast<D>(v).count());
 
   90            return sum / elapsed_times_.
size();
 
   97            return std::chrono::duration_cast<D>(
 
   99                           elapsed_times_.
begin(), elapsed_times_.
end()))
 
  107            return std::chrono::duration_cast<D>(
 
  109                           elapsed_times_.
begin(), elapsed_times_.
end()))
 
  122            boost::asio::io_context& 
ios)
 
 
  140        operator()(std::chrono::steady_clock::duration 
const& elapsed)
 
 
 
  150        boost::system::error_code ec;
 
  154        timer.async_wait(yield[ec]);
 
  155        if (!BEAST_EXPECTS(!ec, ec.message()))
 
  157        BEAST_EXPECT(io_probe.durations_.size() == 1);
 
  158        io_probe.probe_.cancel_async();
 
 
  165        boost::system::error_code ec;
 
  167        auto interval = 99ms;
 
  168        auto probe_duration = 1s;
 
  170        size_t expected_probe_count_max = (probe_duration / interval);
 
  171        size_t expected_probe_count_min = expected_probe_count_max;
 
  172#ifdef XRPL_RUNNING_IN_CI 
  175        measure_asio_timers<steady_clock> tt{interval};
 
  180        expected_probe_count_min =
 
  182                duration_cast<milliseconds>(probe_duration).count()) /
 
  188        timer.async_wait(yield[ec]);
 
  189        if (!BEAST_EXPECTS(!ec, ec.message()))
 
  191        auto probes_seen = io_probe.durations_.size();
 
  193            probes_seen >= (expected_probe_count_min - 1) &&
 
  194                probes_seen <= (expected_probe_count_max + 1),
 
  196        io_probe.probe_.cancel_async();
 
  199        timer.expires_after(1s);
 
  200        timer.async_wait(yield[ec]);
 
 
  209        except<std::logic_error>([&io_probe]() { io_probe.start_one(); });
 
  210        except<std::logic_error>([&io_probe]() { io_probe.start(); });
 
 
  217        yield_to([&](boost::asio::yield_context& yield) {
 
 
 
  225BEAST_DEFINE_TESTSUITE(io_latency_probe, 
beast, 
beast);
 
Measures handler latency on an io_context queue.
 
void sample(Handler &&handler)
Initiate continuous i/o latency sampling.
 
void sample_one(Handler &&handler)
Measure one sample of i/o latency.
 
Mix-in to support tests using asio coroutines.
 
boost::asio::io_context & get_io_context()
Return the io_context associated with the object.
 
void yield_to(F0 &&f0, FN &&... fn)
Run one or more functions, each in a coroutine.
 
log_os< char > log
Logging output stream.
 
testcase_t testcase
Memberspace for declaring test cases.
 
boost::asio::basic_waitable_timer< std::chrono::steady_clock > MyTimer
 
void testCanceled(boost::asio::yield_context &yield)
 
void testSampleOngoing(boost::asio::yield_context &yield)
 
void run() override
Runs the suite.
 
void testSampleOne(boost::asio::yield_context &yield)
 
T emplace_back(T... args)
 
void operator()(std::chrono::steady_clock::duration const &elapsed)
 
beast::io_latency_probe< std::chrono::steady_clock > probe_
 
std::vector< std::chrono::steady_clock::duration > durations_
 
test_sampler(std::chrono::milliseconds interval, boost::asio::io_context &ios)