Upstream commit: https://webrtc.googlesource.com/src/+/17ad2f4af656e4acd73bf89f68852506aac79e00 Add more clocks for WaitUntil support There are many different clocks used for testing. One day there will only be one but for now this function needs to support them all. Bug: webrtc:381524905 Change-Id: I8e240167af2ada2494420c751722f8e0dc97f0d2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/371303 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Evan Shrubsole <eshr@webrtc.org> Auto-Submit: Evan Shrubsole <eshr@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43580}
101 lines
3.5 KiB
C++
101 lines
3.5 KiB
C++
/*
|
|
* Copyright 2024 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#ifndef TEST_WAIT_UNTIL_H_
|
|
#define TEST_WAIT_UNTIL_H_
|
|
|
|
#include <string>
|
|
|
|
#include "absl/types/variant.h"
|
|
#include "api/rtc_error.h"
|
|
#include "api/test/time_controller.h"
|
|
#include "api/units/time_delta.h"
|
|
#include "api/units/timestamp.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/fake_clock.h"
|
|
#include "rtc_base/thread.h"
|
|
#include "system_wrappers/include/clock.h"
|
|
#include "test/gmock.h"
|
|
#include "test/wait_until_internal.h" // IWYU pragma: private
|
|
|
|
namespace webrtc {
|
|
|
|
using ClockVariant = absl::variant<absl::monostate,
|
|
SimulatedClock*,
|
|
rtc::FakeClock*,
|
|
rtc::ThreadProcessingFakeClock*,
|
|
TimeController*>;
|
|
|
|
namespace wait_until_internal {
|
|
Timestamp GetTimeFromClockVariant(const ClockVariant& clock);
|
|
void AdvanceTimeOnClockVariant(ClockVariant& clock, TimeDelta delta);
|
|
} // namespace wait_until_internal
|
|
|
|
struct WaitUntilSettings {
|
|
// The maximum time to wait for the condition to be met.
|
|
TimeDelta timeout = TimeDelta::Seconds(5);
|
|
// The interval between polling the condition.
|
|
TimeDelta polling_interval = TimeDelta::Millis(1);
|
|
// The clock to use for timing.
|
|
ClockVariant clock = absl::monostate();
|
|
// Name of the result to be used in the error message.
|
|
std::string result_name = "result";
|
|
};
|
|
|
|
// Runs a function `fn`, which returns a result, until `matcher` matches the
|
|
// result.
|
|
//
|
|
// The function is called repeatedly until the result matches the matcher or the
|
|
// timeout is reached. If the matcher matches the result, the result is
|
|
// returned. Otherwise, an error is returned.
|
|
//
|
|
// Example:
|
|
//
|
|
// int counter = 0;
|
|
// RTCErrorOr<int> result = Waituntil([&] { return ++counter; }, Eq(3))
|
|
// EXPECT_THAT(result, IsOkAndHolds(3));
|
|
template <typename Fn, typename Matcher>
|
|
[[nodiscard]] auto WaitUntil(const Fn& fn,
|
|
Matcher matcher,
|
|
WaitUntilSettings settings = {})
|
|
-> RTCErrorOr<decltype(fn())> {
|
|
if (absl::holds_alternative<absl::monostate>(settings.clock)) {
|
|
RTC_CHECK(rtc::Thread::Current()) << "A current thread is required. An "
|
|
"rtc::AutoThread can work for tests.";
|
|
}
|
|
|
|
Timestamp start =
|
|
wait_until_internal::GetTimeFromClockVariant(settings.clock);
|
|
do {
|
|
auto result = fn();
|
|
if (::testing::Value(result, matcher)) {
|
|
return result;
|
|
}
|
|
wait_until_internal::AdvanceTimeOnClockVariant(settings.clock,
|
|
settings.polling_interval);
|
|
} while (wait_until_internal::GetTimeFromClockVariant(settings.clock) <
|
|
start + settings.timeout);
|
|
|
|
// One more try after the last sleep. This failure will contain the error
|
|
// message.
|
|
auto result = fn();
|
|
::testing::StringMatchResultListener listener;
|
|
if (wait_until_internal::ExplainMatchResult(matcher, result, &listener,
|
|
settings.result_name)) {
|
|
return result;
|
|
}
|
|
|
|
return RTCError(RTCErrorType::INTERNAL_ERROR, listener.str());
|
|
}
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // TEST_WAIT_UNTIL_H_
|