Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(643)

Side by Side Diff: base/run_loop_unittest.cc

Issue 2818533003: Make nesting/running states a RunLoop rather than a MessageLoop concept. (Closed)
Patch Set: still need to check MessageLoop::current() in Mojo's RunLoopNestingObserver::GetForThread() Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/run_loop.cc ('k') | chrome/browser/app_controller_mac.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/run_loop.h" 5 #include "base/run_loop.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/threading/thread_task_runner_handle.h" 13 #include "base/threading/thread_task_runner_handle.h"
14 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
15 16
16 namespace base { 17 namespace base {
17 18
18 namespace { 19 namespace {
19 20
20 void QuitWhenIdleTask(RunLoop* run_loop, int* counter) { 21 void QuitWhenIdleTask(RunLoop* run_loop, int* counter) {
21 run_loop->QuitWhenIdle(); 22 run_loop->QuitWhenIdle();
22 ++(*counter); 23 ++(*counter);
23 } 24 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 RunLoop run_loop_; 56 RunLoop run_loop_;
56 int counter_ = 0; 57 int counter_ = 0;
57 58
58 private: 59 private:
59 DISALLOW_COPY_AND_ASSIGN(RunLoopTest); 60 DISALLOW_COPY_AND_ASSIGN(RunLoopTest);
60 }; 61 };
61 62
62 } // namespace 63 } // namespace
63 64
64 TEST_F(RunLoopTest, QuitWhenIdle) { 65 TEST_F(RunLoopTest, QuitWhenIdle) {
65 message_loop_.task_runner()->PostTask( 66 ThreadTaskRunnerHandle::Get()->PostTask(
66 FROM_HERE, BindOnce(&QuitWhenIdleTask, Unretained(&run_loop_), 67 FROM_HERE, BindOnce(&QuitWhenIdleTask, Unretained(&run_loop_),
67 Unretained(&counter_))); 68 Unretained(&counter_)));
68 message_loop_.task_runner()->PostTask( 69 ThreadTaskRunnerHandle::Get()->PostTask(
69 FROM_HERE, BindOnce(&ShouldRunTask, Unretained(&counter_))); 70 FROM_HERE, BindOnce(&ShouldRunTask, Unretained(&counter_)));
70 message_loop_.task_runner()->PostDelayedTask( 71 ThreadTaskRunnerHandle::Get()->PostDelayedTask(
71 FROM_HERE, BindOnce(&ShouldNotRunTask), TimeDelta::FromDays(1)); 72 FROM_HERE, BindOnce(&ShouldNotRunTask), TimeDelta::FromDays(1));
72 73
73 run_loop_.Run(); 74 run_loop_.Run();
74 EXPECT_EQ(2, counter_); 75 EXPECT_EQ(2, counter_);
75 } 76 }
76 77
77 TEST_F(RunLoopTest, QuitWhenIdleNestedLoop) { 78 TEST_F(RunLoopTest, QuitWhenIdleNestedLoop) {
78 message_loop_.task_runner()->PostTask( 79 ThreadTaskRunnerHandle::Get()->PostTask(
79 FROM_HERE, BindOnce(&RunNestedLoopTask, Unretained(&counter_))); 80 FROM_HERE, BindOnce(&RunNestedLoopTask, Unretained(&counter_)));
80 message_loop_.task_runner()->PostTask( 81 ThreadTaskRunnerHandle::Get()->PostTask(
81 FROM_HERE, BindOnce(&QuitWhenIdleTask, Unretained(&run_loop_), 82 FROM_HERE, BindOnce(&QuitWhenIdleTask, Unretained(&run_loop_),
82 Unretained(&counter_))); 83 Unretained(&counter_)));
83 message_loop_.task_runner()->PostTask( 84 ThreadTaskRunnerHandle::Get()->PostTask(
84 FROM_HERE, BindOnce(&ShouldRunTask, Unretained(&counter_))); 85 FROM_HERE, BindOnce(&ShouldRunTask, Unretained(&counter_)));
85 message_loop_.task_runner()->PostDelayedTask( 86 ThreadTaskRunnerHandle::Get()->PostDelayedTask(
86 FROM_HERE, BindOnce(&ShouldNotRunTask), TimeDelta::FromDays(1)); 87 FROM_HERE, BindOnce(&ShouldNotRunTask), TimeDelta::FromDays(1));
87 88
88 run_loop_.Run(); 89 run_loop_.Run();
89 EXPECT_EQ(4, counter_); 90 EXPECT_EQ(4, counter_);
90 } 91 }
91 92
92 TEST_F(RunLoopTest, QuitWhenIdleClosure) { 93 TEST_F(RunLoopTest, QuitWhenIdleClosure) {
93 message_loop_.task_runner()->PostTask(FROM_HERE, 94 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
94 run_loop_.QuitWhenIdleClosure()); 95 run_loop_.QuitWhenIdleClosure());
95 message_loop_.task_runner()->PostTask( 96 ThreadTaskRunnerHandle::Get()->PostTask(
96 FROM_HERE, BindOnce(&ShouldRunTask, Unretained(&counter_))); 97 FROM_HERE, BindOnce(&ShouldRunTask, Unretained(&counter_)));
97 message_loop_.task_runner()->PostDelayedTask( 98 ThreadTaskRunnerHandle::Get()->PostDelayedTask(
98 FROM_HERE, BindOnce(&ShouldNotRunTask), TimeDelta::FromDays(1)); 99 FROM_HERE, BindOnce(&ShouldNotRunTask), TimeDelta::FromDays(1));
99 100
100 run_loop_.Run(); 101 run_loop_.Run();
101 EXPECT_EQ(1, counter_); 102 EXPECT_EQ(1, counter_);
102 } 103 }
103 104
104 // Verify that the QuitWhenIdleClosure() can run after the RunLoop has been 105 // Verify that the QuitWhenIdleClosure() can run after the RunLoop has been
105 // deleted. It should have no effect. 106 // deleted. It should have no effect.
106 TEST_F(RunLoopTest, QuitWhenIdleClosureAfterRunLoopScope) { 107 TEST_F(RunLoopTest, QuitWhenIdleClosureAfterRunLoopScope) {
107 Closure quit_when_idle_closure; 108 Closure quit_when_idle_closure;
108 { 109 {
109 RunLoop run_loop; 110 RunLoop run_loop;
110 quit_when_idle_closure = run_loop.QuitWhenIdleClosure(); 111 quit_when_idle_closure = run_loop.QuitWhenIdleClosure();
111 run_loop.RunUntilIdle(); 112 run_loop.RunUntilIdle();
112 } 113 }
113 quit_when_idle_closure.Run(); 114 quit_when_idle_closure.Run();
114 } 115 }
115 116
117 TEST_F(RunLoopTest, IsRunningOnCurrentThread) {
118 EXPECT_FALSE(RunLoop::IsRunningOnCurrentThread());
119 ThreadTaskRunnerHandle::Get()->PostTask(
120 FROM_HERE,
121 Bind([]() { EXPECT_TRUE(RunLoop::IsRunningOnCurrentThread()); }));
122 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_loop_.QuitClosure());
123 run_loop_.Run();
124 }
125
126 TEST_F(RunLoopTest, IsNestedOnCurrentThread) {
127 EXPECT_FALSE(RunLoop::IsNestedOnCurrentThread());
128
129 ThreadTaskRunnerHandle::Get()->PostTask(
130 FROM_HERE, Bind([]() {
131 EXPECT_FALSE(RunLoop::IsNestedOnCurrentThread());
132
133 RunLoop nested_run_loop;
134
135 ThreadTaskRunnerHandle::Get()->PostTask(
136 FROM_HERE,
137 Bind([]() { EXPECT_TRUE(RunLoop::IsNestedOnCurrentThread()); }));
138 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
139 nested_run_loop.QuitClosure());
140
141 EXPECT_FALSE(RunLoop::IsNestedOnCurrentThread());
142 MessageLoop::ScopedNestableTaskAllower allower(MessageLoop::current());
143 nested_run_loop.Run();
144 EXPECT_FALSE(RunLoop::IsNestedOnCurrentThread());
145 }));
146
147 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_loop_.QuitClosure());
148 run_loop_.Run();
149 }
150
151 class MockNestingObserver : public RunLoop::NestingObserver {
152 public:
153 MockNestingObserver() = default;
154
155 // RunLoop::NestingObserver:
156 MOCK_METHOD0(OnBeginNestedRunLoop, void());
157
158 private:
159 DISALLOW_COPY_AND_ASSIGN(MockNestingObserver);
160 };
161
162 TEST_F(RunLoopTest, NestingObservers) {
163 EXPECT_TRUE(RunLoop::IsNestingAllowedOnCurrentThread());
164
165 testing::StrictMock<MockNestingObserver> nesting_observer;
166
167 RunLoop::AddNestingObserverOnCurrentThread(&nesting_observer);
168
169 const RepeatingClosure run_nested_loop = Bind([]() {
170 RunLoop nested_run_loop;
171 ThreadTaskRunnerHandle::Get()->PostTask(
172 FROM_HERE, Bind([]() {
173 EXPECT_TRUE(RunLoop::IsNestingAllowedOnCurrentThread());
174 }));
175 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
176 nested_run_loop.QuitClosure());
177 MessageLoop::ScopedNestableTaskAllower allower(MessageLoop::current());
178 nested_run_loop.Run();
179 });
180
181 // Generate a stack of nested RunLoops, an OnBeginNestedRunLoop() is
182 // expected when beginning each nesting depth.
183 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_nested_loop);
184 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_nested_loop);
185 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_loop_.QuitClosure());
186
187 EXPECT_CALL(nesting_observer, OnBeginNestedRunLoop()).Times(2);
188 run_loop_.Run();
189
190 RunLoop::RemoveNestingObserverOnCurrentThread(&nesting_observer);
191 }
192
193 // Disabled on Android per http://crbug.com/643760.
194 #if defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
195 TEST_F(RunLoopTest, DisallowWaitingDeathTest) {
196 EXPECT_TRUE(RunLoop::IsNestingAllowedOnCurrentThread());
197 RunLoop::DisallowNestingOnCurrentThread();
198 EXPECT_FALSE(RunLoop::IsNestingAllowedOnCurrentThread());
199
200 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, Bind([]() {
201 RunLoop nested_run_loop;
202 nested_run_loop.RunUntilIdle();
203 }));
204 EXPECT_DEATH({ run_loop_.RunUntilIdle(); }, "Check failed");
205 }
206 #endif // defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
207
116 } // namespace base 208 } // namespace base
OLDNEW
« no previous file with comments | « base/run_loop.cc ('k') | chrome/browser/app_controller_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698