/* * Copyright (C) 2018-present ScyllaDB */ /* * SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0 */ #pragma once #include #include #include #include #include #include #include "seastarx.hh" using sleep_fn = std::function(std::chrono::milliseconds)>; extern sleep_fn seastar_sleep_fn; extern sleep_fn manual_clock_sleep_fn; inline void eventually(noncopyable_function f, size_t max_attempts = 17, sleep_fn sleep = seastar_sleep_fn) { size_t attempts = 0; while (true) { try { f(); break; } catch (...) { if (++attempts < max_attempts) { sleep(std::chrono::milliseconds(1 << attempts)).get(); } else { throw; } } } } inline bool eventually_true(noncopyable_function f, sleep_fn sleep = seastar_sleep_fn) { const unsigned max_attempts = 15; unsigned attempts = 0; while (true) { if (f()) { return true; } if (++attempts < max_attempts) { sleep(std::chrono::milliseconds(1 << attempts)).get(); } else { return false; } } return false; } // Must be called in a seastar thread template void REQUIRE_EVENTUALLY_EQUAL(std::function a, T b, sleep_fn sleep = seastar_sleep_fn) { eventually_true([&] { return a() == b; }, sleep); BOOST_REQUIRE_EQUAL(a(), b); } // Must be called in a seastar thread template void CHECK_EVENTUALLY_EQUAL(std::function a, T b, sleep_fn sleep = seastar_sleep_fn) { eventually_true([&] { return a() == b; }, sleep); BOOST_CHECK_EQUAL(a(), b); }