scoped_run_loop_timeout.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/test/scoped_run_loop_timeout.h"
  5. #include "base/bind.h"
  6. #include "base/callback_helpers.h"
  7. #include "base/location.h"
  8. #include "base/logging.h"
  9. #include "base/strings/strcat.h"
  10. #include "base/time/time.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. namespace base {
  13. namespace test {
  14. namespace {
  15. bool g_add_gtest_failure_on_timeout = false;
  16. std::string TimeoutMessage(const RepeatingCallback<std::string()>& get_log,
  17. const Location& timeout_enabled_from_here) {
  18. std::string message = "RunLoop::Run() timed out. Timeout set at ";
  19. message += timeout_enabled_from_here.ToString() + ".";
  20. if (get_log)
  21. StrAppend(&message, {"\n", get_log.Run()});
  22. return message;
  23. }
  24. } // namespace
  25. ScopedRunLoopTimeout::ScopedRunLoopTimeout(const Location& from_here,
  26. TimeDelta timeout)
  27. : ScopedRunLoopTimeout(from_here, timeout, NullCallback()) {}
  28. ScopedRunLoopTimeout::~ScopedRunLoopTimeout() {
  29. RunLoop::SetTimeoutForCurrentThread(nested_timeout_);
  30. }
  31. ScopedRunLoopTimeout::ScopedRunLoopTimeout(
  32. const Location& timeout_enabled_from_here,
  33. TimeDelta timeout,
  34. RepeatingCallback<std::string()> on_timeout_log)
  35. : nested_timeout_(RunLoop::GetTimeoutForCurrentThread()) {
  36. DCHECK_GT(timeout, TimeDelta());
  37. run_timeout_.timeout = timeout;
  38. if (g_add_gtest_failure_on_timeout) {
  39. run_timeout_.on_timeout = BindRepeating(
  40. [](const Location& timeout_enabled_from_here,
  41. RepeatingCallback<std::string()> on_timeout_log,
  42. const Location& run_from_here) {
  43. GTEST_FAIL_AT(run_from_here.file_name(), run_from_here.line_number())
  44. << TimeoutMessage(on_timeout_log, timeout_enabled_from_here);
  45. },
  46. timeout_enabled_from_here, std::move(on_timeout_log));
  47. } else {
  48. run_timeout_.on_timeout = BindRepeating(
  49. [](const Location& timeout_enabled_from_here,
  50. RepeatingCallback<std::string()> on_timeout_log,
  51. const Location& run_from_here) {
  52. std::string message =
  53. TimeoutMessage(on_timeout_log, timeout_enabled_from_here);
  54. logging::LogMessage(run_from_here.file_name(),
  55. run_from_here.line_number(), message.data());
  56. },
  57. timeout_enabled_from_here, std::move(on_timeout_log));
  58. }
  59. RunLoop::SetTimeoutForCurrentThread(&run_timeout_);
  60. }
  61. // static
  62. bool ScopedRunLoopTimeout::ExistsForCurrentThread() {
  63. return RunLoop::GetTimeoutForCurrentThread() != nullptr;
  64. }
  65. // static
  66. void ScopedRunLoopTimeout::SetAddGTestFailureOnTimeout() {
  67. g_add_gtest_failure_on_timeout = true;
  68. }
  69. // static
  70. const RunLoop::RunLoopTimeout*
  71. ScopedRunLoopTimeout::GetTimeoutForCurrentThread() {
  72. return RunLoop::GetTimeoutForCurrentThread();
  73. }
  74. ScopedDisableRunLoopTimeout::ScopedDisableRunLoopTimeout()
  75. : nested_timeout_(RunLoop::GetTimeoutForCurrentThread()) {
  76. RunLoop::SetTimeoutForCurrentThread(nullptr);
  77. }
  78. ScopedDisableRunLoopTimeout::~ScopedDisableRunLoopTimeout() {
  79. RunLoop::SetTimeoutForCurrentThread(nested_timeout_);
  80. }
  81. } // namespace test
  82. } // namespace base