gunit.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright 2004 The WebRTC Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef RTC_BASE_GUNIT_H_
  11. #define RTC_BASE_GUNIT_H_
  12. #include "rtc_base/fake_clock.h"
  13. #include "rtc_base/logging.h"
  14. #include "rtc_base/thread.h"
  15. #include "test/gtest.h"
  16. // Wait until "ex" is true, or "timeout" expires.
  17. #define WAIT(ex, timeout) \
  18. for (int64_t start = rtc::SystemTimeMillis(); \
  19. !(ex) && rtc::SystemTimeMillis() < start + (timeout);) { \
  20. rtc::Thread::Current()->ProcessMessages(0); \
  21. rtc::Thread::Current()->SleepMs(1); \
  22. }
  23. // This returns the result of the test in res, so that we don't re-evaluate
  24. // the expression in the XXXX_WAIT macros below, since that causes problems
  25. // when the expression is only true the first time you check it.
  26. #define WAIT_(ex, timeout, res) \
  27. do { \
  28. int64_t start = rtc::SystemTimeMillis(); \
  29. res = (ex); \
  30. while (!res && rtc::SystemTimeMillis() < start + (timeout)) { \
  31. rtc::Thread::Current()->ProcessMessages(0); \
  32. rtc::Thread::Current()->SleepMs(1); \
  33. res = (ex); \
  34. } \
  35. } while (0)
  36. // The typical EXPECT_XXXX and ASSERT_XXXXs, but done until true or a timeout.
  37. // One can add failure message by appending "<< msg".
  38. #define EXPECT_TRUE_WAIT(ex, timeout) \
  39. GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  40. if (bool res = true) { \
  41. WAIT_(ex, timeout, res); \
  42. if (!res) \
  43. goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
  44. } else \
  45. GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_TRUE(ex)
  46. #define EXPECT_EQ_WAIT(v1, v2, timeout) \
  47. GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  48. if (bool res = true) { \
  49. WAIT_(v1 == v2, timeout, res); \
  50. if (!res) \
  51. goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
  52. } else \
  53. GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_EQ(v1, v2)
  54. #define ASSERT_TRUE_WAIT(ex, timeout) \
  55. GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  56. if (bool res = true) { \
  57. WAIT_(ex, timeout, res); \
  58. if (!res) \
  59. goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
  60. } else \
  61. GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_TRUE(ex)
  62. #define ASSERT_EQ_WAIT(v1, v2, timeout) \
  63. GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  64. if (bool res = true) { \
  65. WAIT_(v1 == v2, timeout, res); \
  66. if (!res) \
  67. goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
  68. } else \
  69. GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_EQ(v1, v2)
  70. // Version with a "soft" timeout and a margin. This logs if the timeout is
  71. // exceeded, but it only fails if the expression still isn't true after the
  72. // margin time passes.
  73. #define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \
  74. GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  75. if (bool res = true) { \
  76. WAIT_(ex, timeout, res); \
  77. if (res) \
  78. break; \
  79. RTC_LOG(LS_WARNING) << "Expression " << #ex << " still not true after " \
  80. << (timeout) << "ms; waiting an additional " << margin \
  81. << "ms"; \
  82. WAIT_(ex, margin, res); \
  83. if (!res) \
  84. goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
  85. } else \
  86. GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_TRUE(ex)
  87. // Wait until "ex" is true, or "timeout" expires, using fake clock where
  88. // messages are processed every millisecond.
  89. // TODO(pthatcher): Allow tests to control how many milliseconds to advance.
  90. #define SIMULATED_WAIT(ex, timeout, clock) \
  91. for (int64_t start = rtc::TimeMillis(); \
  92. !(ex) && rtc::TimeMillis() < start + (timeout);) { \
  93. (clock).AdvanceTime(webrtc::TimeDelta::Millis(1)); \
  94. }
  95. // This returns the result of the test in res, so that we don't re-evaluate
  96. // the expression in the XXXX_WAIT macros below, since that causes problems
  97. // when the expression is only true the first time you check it.
  98. #define SIMULATED_WAIT_(ex, timeout, res, clock) \
  99. do { \
  100. int64_t start = rtc::TimeMillis(); \
  101. res = (ex); \
  102. while (!res && rtc::TimeMillis() < start + (timeout)) { \
  103. (clock).AdvanceTime(webrtc::TimeDelta::Millis(1)); \
  104. res = (ex); \
  105. } \
  106. } while (0)
  107. // The typical EXPECT_XXXX, but done until true or a timeout with a fake clock.
  108. #define EXPECT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \
  109. do { \
  110. bool res; \
  111. SIMULATED_WAIT_(ex, timeout, res, clock); \
  112. if (!res) { \
  113. EXPECT_TRUE(ex); \
  114. } \
  115. } while (0)
  116. #define EXPECT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \
  117. GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  118. if (bool res = true) { \
  119. SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \
  120. if (!res) \
  121. goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
  122. } else \
  123. GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_EQ(v1, v2)
  124. #define ASSERT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \
  125. GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  126. if (bool res = true) { \
  127. SIMULATED_WAIT_(ex, timeout, res, clock); \
  128. if (!res) \
  129. goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
  130. } else \
  131. GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_TRUE(ex)
  132. #define ASSERT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \
  133. GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  134. if (bool res = true) { \
  135. SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \
  136. if (!res) \
  137. goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
  138. } else \
  139. GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_EQ(v1, v2)
  140. // Usage: EXPECT_PRED_FORMAT2(AssertStartsWith, text, "prefix");
  141. testing::AssertionResult AssertStartsWith(const char* text_expr,
  142. const char* prefix_expr,
  143. absl::string_view text,
  144. absl::string_view prefix);
  145. // Usage: EXPECT_PRED_FORMAT2(AssertStringContains, str, "substring");
  146. testing::AssertionResult AssertStringContains(const char* str_expr,
  147. const char* substr_expr,
  148. const std::string& str,
  149. const std::string& substr);
  150. #endif // RTC_BASE_GUNIT_H_