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