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