blob: 6bc1419729409d5463841d5980493a8d98a9a70f [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef RTC_BASE_GUNIT_H_
12#define RTC_BASE_GUNIT_H_
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013
Ali Tofigh7fa90572022-03-17 15:47:49 +010014#include "absl/strings/string_view.h"
Steve Anton10542f22019-01-11 09:11:00 -080015#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "rtc_base/logging.h"
17#include "rtc_base/thread.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "test/gtest.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000019
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020020// Wait until "ex" is true, or "timeout" expires.
21#define WAIT(ex, timeout) \
22 for (int64_t start = rtc::SystemTimeMillis(); \
23 !(ex) && rtc::SystemTimeMillis() < start + (timeout);) { \
24 rtc::Thread::Current()->ProcessMessages(0); \
25 rtc::Thread::Current()->SleepMs(1); \
26 }
27
28// This returns the result of the test in res, so that we don't re-evaluate
29// the expression in the XXXX_WAIT macros below, since that causes problems
30// when the expression is only true the first time you check it.
31#define WAIT_(ex, timeout, res) \
32 do { \
33 int64_t start = rtc::SystemTimeMillis(); \
Niels Möller94327682022-04-28 13:20:29 +020034 res = (ex) && true; \
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020035 while (!res && rtc::SystemTimeMillis() < start + (timeout)) { \
36 rtc::Thread::Current()->ProcessMessages(0); \
37 rtc::Thread::Current()->SleepMs(1); \
Niels Möller94327682022-04-28 13:20:29 +020038 res = (ex) && true; \
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020039 } \
40 } while (0)
41
42// The typical EXPECT_XXXX and ASSERT_XXXXs, but done until true or a timeout.
minyue-webrtc0b249c22017-07-10 11:52:21 +020043// One can add failure message by appending "<< msg".
44#define EXPECT_TRUE_WAIT(ex, timeout) \
45 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
46 if (bool res = true) { \
47 WAIT_(ex, timeout, res); \
48 if (!res) \
49 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
50 } else \
51 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_TRUE(ex)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020052
minyue-webrtc0b249c22017-07-10 11:52:21 +020053#define EXPECT_EQ_WAIT(v1, v2, timeout) \
54 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
55 if (bool res = true) { \
56 WAIT_(v1 == v2, timeout, res); \
57 if (!res) \
58 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
59 } else \
60 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_EQ(v1, v2)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020061
minyue-webrtc0b249c22017-07-10 11:52:21 +020062#define ASSERT_TRUE_WAIT(ex, timeout) \
63 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
64 if (bool res = true) { \
65 WAIT_(ex, timeout, res); \
66 if (!res) \
67 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
68 } else \
69 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_TRUE(ex)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020070
minyue-webrtc0b249c22017-07-10 11:52:21 +020071#define ASSERT_EQ_WAIT(v1, v2, timeout) \
72 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
73 if (bool res = true) { \
74 WAIT_(v1 == v2, timeout, res); \
75 if (!res) \
76 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
77 } else \
78 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_EQ(v1, v2)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020079
80// Version with a "soft" timeout and a margin. This logs if the timeout is
81// exceeded, but it only fails if the expression still isn't true after the
82// margin time passes.
Mirko Bonadei675513b2017-11-09 11:09:25 +010083#define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \
84 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
85 if (bool res = true) { \
86 WAIT_(ex, timeout, res); \
87 if (res) \
88 break; \
89 RTC_LOG(LS_WARNING) << "Expression " << #ex << " still not true after " \
90 << (timeout) << "ms; waiting an additional " << margin \
91 << "ms"; \
92 WAIT_(ex, margin, res); \
93 if (!res) \
94 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
95 } else \
minyue-webrtc0b249c22017-07-10 11:52:21 +020096 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_TRUE(ex)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020097
98// Wait until "ex" is true, or "timeout" expires, using fake clock where
99// messages are processed every millisecond.
100// TODO(pthatcher): Allow tests to control how many milliseconds to advance.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +0200101#define SIMULATED_WAIT(ex, timeout, clock) \
102 for (int64_t start = rtc::TimeMillis(); \
103 !(ex) && rtc::TimeMillis() < start + (timeout);) { \
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100104 (clock).AdvanceTime(webrtc::TimeDelta::Millis(1)); \
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200105 }
106
107// This returns the result of the test in res, so that we don't re-evaluate
108// the expression in the XXXX_WAIT macros below, since that causes problems
109// when the expression is only true the first time you check it.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +0200110#define SIMULATED_WAIT_(ex, timeout, res, clock) \
111 do { \
112 int64_t start = rtc::TimeMillis(); \
113 res = (ex); \
114 while (!res && rtc::TimeMillis() < start + (timeout)) { \
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100115 (clock).AdvanceTime(webrtc::TimeDelta::Millis(1)); \
Sebastian Jansson5f83cf02018-05-08 14:52:22 +0200116 res = (ex); \
117 } \
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200118 } while (0)
119
120// The typical EXPECT_XXXX, but done until true or a timeout with a fake clock.
121#define EXPECT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \
122 do { \
123 bool res; \
124 SIMULATED_WAIT_(ex, timeout, res, clock); \
125 if (!res) { \
126 EXPECT_TRUE(ex); \
127 } \
128 } while (0)
129
130#define EXPECT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \
minyue-webrtc0b249c22017-07-10 11:52:21 +0200131 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
132 if (bool res = true) { \
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200133 SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \
134 if (!res) \
minyue-webrtc0b249c22017-07-10 11:52:21 +0200135 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
136 } else \
137 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_EQ(v1, v2)
138
139#define ASSERT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \
140 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
141 if (bool res = true) { \
142 SIMULATED_WAIT_(ex, timeout, res, clock); \
143 if (!res) \
144 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
145 } else \
146 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_TRUE(ex)
147
148#define ASSERT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \
149 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
150 if (bool res = true) { \
151 SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \
152 if (!res) \
153 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
154 } else \
155 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_EQ(v1, v2)
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700156
Steve Anton68586e82018-12-13 17:41:25 -0800157// Usage: EXPECT_PRED_FORMAT2(AssertStartsWith, text, "prefix");
158testing::AssertionResult AssertStartsWith(const char* text_expr,
Steve Antonad7bffc2018-01-22 10:21:56 -0800159 const char* prefix_expr,
Steve Anton68586e82018-12-13 17:41:25 -0800160 absl::string_view text,
161 absl::string_view prefix);
Steve Antonad7bffc2018-01-22 10:21:56 -0800162
Steve Anton80dd7b52018-02-16 17:08:42 -0800163// Usage: EXPECT_PRED_FORMAT2(AssertStringContains, str, "substring");
164testing::AssertionResult AssertStringContains(const char* str_expr,
165 const char* substr_expr,
Ali Tofigh7fa90572022-03-17 15:47:49 +0100166 absl::string_view str,
167 absl::string_view substr);
Steve Anton80dd7b52018-02-16 17:08:42 -0800168
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200169#endif // RTC_BASE_GUNIT_H_