1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/test/scoped_run_loop_timeout.h"
6
7 #include "base/functional/bind.h"
8 #include "base/functional/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/task/sequenced_task_runner.h"
11 #include "base/test/bind.h"
12 #include "base/test/gtest_util.h"
13 #include "base/test/task_environment.h"
14 #include "base/time/time.h"
15 #include "testing/gtest/include/gtest/gtest-spi.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace base {
19 namespace test {
20
TEST(ScopedRunLoopTimeoutTest,TimesOut)21 TEST(ScopedRunLoopTimeoutTest, TimesOut) {
22 TaskEnvironment task_environment;
23 RunLoop run_loop;
24
25 static constexpr auto kArbitraryTimeout = Milliseconds(10);
26 ScopedRunLoopTimeout run_timeout(FROM_HERE, kArbitraryTimeout);
27
28 // Since the delayed task will be posted only after the message pump starts
29 // running, the ScopedRunLoopTimeout will already have started to elapse,
30 // so if Run() exits at the correct time then our delayed task will not run.
31 SequencedTaskRunner::GetCurrentDefault()->PostTask(
32 FROM_HERE,
33 BindOnce(IgnoreResult(&SequencedTaskRunner::PostDelayedTask),
34 SequencedTaskRunner::GetCurrentDefault(), FROM_HERE,
35 MakeExpectedNotRunClosure(FROM_HERE), kArbitraryTimeout));
36
37 // This task should get to run before Run() times-out.
38 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
39 FROM_HERE, MakeExpectedRunClosure(FROM_HERE), kArbitraryTimeout);
40
41 // EXPECT_FATAL_FAILURE() can only reference globals and statics.
42 static RunLoop& static_loop = run_loop;
43 EXPECT_FATAL_FAILURE(static_loop.Run(), "Run() timed out.");
44 }
45
TEST(ScopedRunLoopTimeoutTest,RunTasksUntilTimeout)46 TEST(ScopedRunLoopTimeoutTest, RunTasksUntilTimeout) {
47 TaskEnvironment task_environment;
48 RunLoop run_loop;
49
50 static constexpr auto kArbitraryTimeout = Milliseconds(10);
51 ScopedRunLoopTimeout run_timeout(FROM_HERE, kArbitraryTimeout);
52
53 // Posting a task with the same delay as our timeout, immediately before
54 // calling Run(), means it should get to run. Since this uses QuitWhenIdle(),
55 // the Run() timeout callback should also get to run.
56 SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
57 FROM_HERE, MakeExpectedRunClosure(FROM_HERE), kArbitraryTimeout);
58
59 // EXPECT_FATAL_FAILURE() can only reference globals and statics.
60 static RunLoop& static_loop = run_loop;
61 EXPECT_FATAL_FAILURE(static_loop.Run(), "Run() timed out.");
62 }
63
TEST(ScopedRunLoopTimeoutTest,OnTimeoutLog)64 TEST(ScopedRunLoopTimeoutTest, OnTimeoutLog) {
65 TaskEnvironment task_environment;
66 RunLoop run_loop;
67
68 static constexpr auto kArbitraryTimeout = Milliseconds(10);
69 ScopedRunLoopTimeout run_timeout(
70 FROM_HERE, kArbitraryTimeout,
71 BindRepeating([]() -> std::string { return "I like kittens!"; }));
72
73 // EXPECT_FATAL_FAILURE() can only reference globals and statics.
74 static RunLoop& static_loop = run_loop;
75 #if defined(__clang__) && defined(_MSC_VER)
76 EXPECT_FATAL_FAILURE(
77 static_loop.Run(),
78 "Run() timed out. Timeout set at "
79 "TestBody@base\\test\\scoped_run_loop_timeout_unittest.cc:70.\n"
80 "I like kittens!");
81 }
82 #else
83 EXPECT_FATAL_FAILURE(
84 static_loop.Run(),
85 "Run() timed out. Timeout set at "
86 "TestBody@base/test/scoped_run_loop_timeout_unittest.cc:70.\n"
87 "I like kittens!");
88 }
89 #endif
90
91 } // namespace test
92 } // namespace base
93