xref: /aosp_15_r20/external/cronet/base/test/run_until_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2023 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/test/run_until.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_forward.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/timer/timer.h"
13*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest-spi.h"
14*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker namespace base::test {
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker namespace {
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker template <typename Lambda>
RunLater(Lambda lambda)21*6777b538SAndroid Build Coastguard Worker void RunLater(Lambda lambda) {
22*6777b538SAndroid Build Coastguard Worker   SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
23*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindLambdaForTesting(lambda));
24*6777b538SAndroid Build Coastguard Worker }
25*6777b538SAndroid Build Coastguard Worker 
PostDelayedTask(base::OnceClosure closure,base::TimeDelta delay)26*6777b538SAndroid Build Coastguard Worker void PostDelayedTask(base::OnceClosure closure, base::TimeDelta delay) {
27*6777b538SAndroid Build Coastguard Worker   base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
28*6777b538SAndroid Build Coastguard Worker       FROM_HERE, std::move(closure), delay);
29*6777b538SAndroid Build Coastguard Worker }
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker }  // namespace
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker class RunUntilTest : public ::testing::Test {
34*6777b538SAndroid Build Coastguard Worker  public:
35*6777b538SAndroid Build Coastguard Worker   RunUntilTest() = default;
36*6777b538SAndroid Build Coastguard Worker   RunUntilTest(const RunUntilTest&) = delete;
37*6777b538SAndroid Build Coastguard Worker   RunUntilTest& operator=(const RunUntilTest&) = delete;
38*6777b538SAndroid Build Coastguard Worker   ~RunUntilTest() override = default;
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker  private:
41*6777b538SAndroid Build Coastguard Worker   test::SingleThreadTaskEnvironment environment_;
42*6777b538SAndroid Build Coastguard Worker };
43*6777b538SAndroid Build Coastguard Worker 
TEST_F(RunUntilTest,ShouldReturnTrueIfPredicateIsAlreadyFulfilled)44*6777b538SAndroid Build Coastguard Worker TEST_F(RunUntilTest, ShouldReturnTrueIfPredicateIsAlreadyFulfilled) {
45*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(RunUntil([]() { return true; }));
46*6777b538SAndroid Build Coastguard Worker }
47*6777b538SAndroid Build Coastguard Worker 
TEST_F(RunUntilTest,ShouldReturnTrueOncePredicateIsFulfilled)48*6777b538SAndroid Build Coastguard Worker TEST_F(RunUntilTest, ShouldReturnTrueOncePredicateIsFulfilled) {
49*6777b538SAndroid Build Coastguard Worker   bool done = false;
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker   RunLater([&done]() { done = true; });
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(RunUntil([&done]() { return done; }));
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker 
TEST_F(RunUntilTest,ShouldNotSimplyActivelyInvokePredicateInALoop)56*6777b538SAndroid Build Coastguard Worker TEST_F(RunUntilTest, ShouldNotSimplyActivelyInvokePredicateInALoop) {
57*6777b538SAndroid Build Coastguard Worker   bool done = false;
58*6777b538SAndroid Build Coastguard Worker   int call_count = 0;
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker   PostDelayedTask(base::BindLambdaForTesting([&done]() { done = true; }),
61*6777b538SAndroid Build Coastguard Worker                   base::Milliseconds(50));
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(RunUntil([&]() {
64*6777b538SAndroid Build Coastguard Worker     call_count++;
65*6777b538SAndroid Build Coastguard Worker     return done;
66*6777b538SAndroid Build Coastguard Worker   }));
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker   // Ensure the predicate is not called a ton of times.
69*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(call_count, 10);
70*6777b538SAndroid Build Coastguard Worker }
71*6777b538SAndroid Build Coastguard Worker 
TEST_F(RunUntilTest,ShouldNotSimplyReturnOnFirstIdle)72*6777b538SAndroid Build Coastguard Worker TEST_F(RunUntilTest, ShouldNotSimplyReturnOnFirstIdle) {
73*6777b538SAndroid Build Coastguard Worker   bool done = false;
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker   PostDelayedTask(base::DoNothing(), base::Milliseconds(1));
76*6777b538SAndroid Build Coastguard Worker   PostDelayedTask(base::DoNothing(), base::Milliseconds(5));
77*6777b538SAndroid Build Coastguard Worker   PostDelayedTask(base::BindLambdaForTesting([&done]() { done = true; }),
78*6777b538SAndroid Build Coastguard Worker                   base::Milliseconds(10));
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(RunUntil([&]() { return done; }));
81*6777b538SAndroid Build Coastguard Worker }
82*6777b538SAndroid Build Coastguard Worker 
TEST_F(RunUntilTest,ShouldAlwaysLetOtherTasksRunFirstEvenIfPredicateIsAlreadyFulfilled)83*6777b538SAndroid Build Coastguard Worker TEST_F(RunUntilTest,
84*6777b538SAndroid Build Coastguard Worker        ShouldAlwaysLetOtherTasksRunFirstEvenIfPredicateIsAlreadyFulfilled) {
85*6777b538SAndroid Build Coastguard Worker   // This ensures that no tests can (accidentally) rely on `RunUntil`
86*6777b538SAndroid Build Coastguard Worker   // immediately returning.
87*6777b538SAndroid Build Coastguard Worker   bool other_job_done = false;
88*6777b538SAndroid Build Coastguard Worker   RunLater([&other_job_done] { other_job_done = true; });
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(RunUntil([]() { return true; }));
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(other_job_done);
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker 
TEST_F(RunUntilTest,ShouldWorkEvenWhenTimerIsRunning)95*6777b538SAndroid Build Coastguard Worker TEST_F(RunUntilTest, ShouldWorkEvenWhenTimerIsRunning) {
96*6777b538SAndroid Build Coastguard Worker   bool done = false;
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker   base::RepeatingTimer timer;
99*6777b538SAndroid Build Coastguard Worker   timer.Start(FROM_HERE, base::Seconds(1), base::DoNothing());
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker   PostDelayedTask(base::BindLambdaForTesting([&done]() { done = true; }),
102*6777b538SAndroid Build Coastguard Worker                   base::Milliseconds(10));
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(RunUntil([&]() { return done; }));
105*6777b538SAndroid Build Coastguard Worker }
106*6777b538SAndroid Build Coastguard Worker 
TEST_F(RunUntilTest,ShouldReturnFalseIfTimeoutHappens)107*6777b538SAndroid Build Coastguard Worker TEST_F(RunUntilTest, ShouldReturnFalseIfTimeoutHappens) {
108*6777b538SAndroid Build Coastguard Worker   test::ScopedRunLoopTimeout timeout(FROM_HERE, Milliseconds(1));
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker   // `ScopedRunLoopTimeout` will automatically fail the test when a timeout
111*6777b538SAndroid Build Coastguard Worker   // happens, so we use EXPECT_FATAL_FAILURE to handle this failure.
112*6777b538SAndroid Build Coastguard Worker   // EXPECT_FATAL_FAILURE only works on static objects.
113*6777b538SAndroid Build Coastguard Worker   static bool success;
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE({ success = RunUntil([]() { return false; }); },
116*6777b538SAndroid Build Coastguard Worker                           "timed out");
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(success);
119*6777b538SAndroid Build Coastguard Worker }
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker }  // namespace base::test
122