blob: d49912524cd7530f0c29b9b1f43c61203937d4f1 [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
Steve Anton10542f22019-01-11 09:11:00 -080014#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "rtc_base/logging.h"
16#include "rtc_base/thread.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "test/gtest.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000018
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020019// Wait until "ex" is true, or "timeout" expires.
20#define WAIT(ex, timeout) \
21 for (int64_t start = rtc::SystemTimeMillis(); \
22 !(ex) && rtc::SystemTimeMillis() < start + (timeout);) { \
23 rtc::Thread::Current()->ProcessMessages(0); \
24 rtc::Thread::Current()->SleepMs(1); \
25 }
26
27// This returns the result of the test in res, so that we don't re-evaluate
28// the expression in the XXXX_WAIT macros below, since that causes problems
29// when the expression is only true the first time you check it.
30#define WAIT_(ex, timeout, res) \
31 do { \
32 int64_t start = rtc::SystemTimeMillis(); \
33 res = (ex); \
34 while (!res && rtc::SystemTimeMillis() < start + (timeout)) { \
35 rtc::Thread::Current()->ProcessMessages(0); \
36 rtc::Thread::Current()->SleepMs(1); \
37 res = (ex); \
38 } \
39 } while (0)
40
41// The typical EXPECT_XXXX and ASSERT_XXXXs, but done until true or a timeout.
minyue-webrtc0b249c22017-07-10 11:52:21 +020042// One can add failure message by appending "<< msg".
43#define EXPECT_TRUE_WAIT(ex, timeout) \
44 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
45 if (bool res = true) { \
46 WAIT_(ex, timeout, res); \
47 if (!res) \
48 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
49 } else \
50 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_TRUE(ex)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020051
minyue-webrtc0b249c22017-07-10 11:52:21 +020052#define EXPECT_EQ_WAIT(v1, v2, timeout) \
53 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
54 if (bool res = true) { \
55 WAIT_(v1 == v2, timeout, res); \
56 if (!res) \
57 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
58 } else \
59 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_EQ(v1, v2)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020060
minyue-webrtc0b249c22017-07-10 11:52:21 +020061#define ASSERT_TRUE_WAIT(ex, timeout) \
62 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
63 if (bool res = true) { \
64 WAIT_(ex, timeout, res); \
65 if (!res) \
66 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
67 } else \
68 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_TRUE(ex)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020069
minyue-webrtc0b249c22017-07-10 11:52:21 +020070#define ASSERT_EQ_WAIT(v1, v2, timeout) \
71 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
72 if (bool res = true) { \
73 WAIT_(v1 == v2, timeout, res); \
74 if (!res) \
75 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
76 } else \
77 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_EQ(v1, v2)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020078
79// Version with a "soft" timeout and a margin. This logs if the timeout is
80// exceeded, but it only fails if the expression still isn't true after the
81// margin time passes.
Mirko Bonadei675513b2017-11-09 11:09:25 +010082#define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \
83 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
84 if (bool res = true) { \
85 WAIT_(ex, timeout, res); \
86 if (res) \
87 break; \
88 RTC_LOG(LS_WARNING) << "Expression " << #ex << " still not true after " \
89 << (timeout) << "ms; waiting an additional " << margin \
90 << "ms"; \
91 WAIT_(ex, margin, res); \
92 if (!res) \
93 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
94 } else \
minyue-webrtc0b249c22017-07-10 11:52:21 +020095 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_TRUE(ex)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020096
97// Wait until "ex" is true, or "timeout" expires, using fake clock where
98// messages are processed every millisecond.
99// TODO(pthatcher): Allow tests to control how many milliseconds to advance.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +0200100#define SIMULATED_WAIT(ex, timeout, clock) \
101 for (int64_t start = rtc::TimeMillis(); \
102 !(ex) && rtc::TimeMillis() < start + (timeout);) { \
103 (clock).AdvanceTime(webrtc::TimeDelta::ms(1)); \
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200104 }
105
106// This returns the result of the test in res, so that we don't re-evaluate
107// the expression in the XXXX_WAIT macros below, since that causes problems
108// when the expression is only true the first time you check it.
Sebastian Jansson5f83cf02018-05-08 14:52:22 +0200109#define SIMULATED_WAIT_(ex, timeout, res, clock) \
110 do { \
111 int64_t start = rtc::TimeMillis(); \
112 res = (ex); \
113 while (!res && rtc::TimeMillis() < start + (timeout)) { \
114 (clock).AdvanceTime(webrtc::TimeDelta::ms(1)); \
115 res = (ex); \
116 } \
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200117 } while (0)
118
119// The typical EXPECT_XXXX, but done until true or a timeout with a fake clock.
120#define EXPECT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \
121 do { \
122 bool res; \
123 SIMULATED_WAIT_(ex, timeout, res, clock); \
124 if (!res) { \
125 EXPECT_TRUE(ex); \
126 } \
127 } while (0)
128
129#define EXPECT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \
minyue-webrtc0b249c22017-07-10 11:52:21 +0200130 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
131 if (bool res = true) { \
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200132 SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \
133 if (!res) \
minyue-webrtc0b249c22017-07-10 11:52:21 +0200134 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
135 } else \
136 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : EXPECT_EQ(v1, v2)
137
138#define ASSERT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \
139 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
140 if (bool res = true) { \
141 SIMULATED_WAIT_(ex, timeout, res, clock); \
142 if (!res) \
143 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
144 } else \
145 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_TRUE(ex)
146
147#define ASSERT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \
148 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
149 if (bool res = true) { \
150 SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \
151 if (!res) \
152 goto GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__); \
153 } else \
154 GTEST_CONCAT_TOKEN_(gunit_label_, __LINE__) : ASSERT_EQ(v1, v2)
Taylor Brandstetter716d07a2016-06-27 14:07:41 -0700155
Steve Anton68586e82018-12-13 17:41:25 -0800156// Usage: EXPECT_PRED_FORMAT2(AssertStartsWith, text, "prefix");
157testing::AssertionResult AssertStartsWith(const char* text_expr,
Steve Antonad7bffc2018-01-22 10:21:56 -0800158 const char* prefix_expr,
Steve Anton68586e82018-12-13 17:41:25 -0800159 absl::string_view text,
160 absl::string_view prefix);
Steve Antonad7bffc2018-01-22 10:21:56 -0800161
Steve Anton80dd7b52018-02-16 17:08:42 -0800162// Usage: EXPECT_PRED_FORMAT2(AssertStringContains, str, "substring");
163testing::AssertionResult AssertStringContains(const char* str_expr,
164 const char* substr_expr,
165 const std::string& str,
166 const std::string& substr);
167
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200168#endif // RTC_BASE_GUNIT_H_