OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/task_scheduler/shutdown_manager.h" | |
6 | |
7 #include "base/macros.h" | |
8 #include "base/threading/platform_thread.h" | |
9 #include "base/threading/simple_thread.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 | |
12 namespace base { | |
13 namespace internal { | |
14 | |
15 namespace { | |
16 | |
17 class ThreadCallingShutdown : public SimpleThread { | |
18 public: | |
19 explicit ThreadCallingShutdown(ShutdownManager* manager) | |
20 : SimpleThread("ThreadCallingShutdown"), | |
21 manager_(manager), | |
22 has_exited_(false) {} | |
23 | |
24 // Waits until manager_->Shutdown() has been called. | |
25 void WaitUntilShutdownCalled() { | |
26 while (!manager_->is_shutting_down_for_testing()) | |
27 PlatformThread::Sleep(TimeDelta::FromMilliseconds(5)); | |
gab
2016/02/23 22:28:23
5 seems arbitrary. How about PlatformThread::Yield
fdoray
2016/02/26 15:53:28
Done.
| |
28 } | |
29 | |
30 // Returns true once the thread has exited. | |
31 bool has_exited() const { return has_exited_; } | |
32 | |
33 private: | |
34 void Run() override { | |
35 manager_->Shutdown(); | |
36 has_exited_ = true; | |
37 } | |
38 | |
39 ShutdownManager* manager_; | |
40 bool has_exited_; | |
41 | |
42 DISALLOW_COPY_AND_ASSIGN(ThreadCallingShutdown); | |
43 }; | |
44 | |
45 } // namespace | |
46 | |
47 TEST(TaskSchedulerShutdownManagerTest, ShouldPostTaskBeforeShutdown) { | |
48 ShutdownManager manager; | |
49 EXPECT_TRUE( | |
50 manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
51 EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
52 EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
53 } | |
54 | |
55 TEST(TaskSchedulerShutdownManagerTest, ShouldPostTaskAfterShutdownCompleted) { | |
56 ShutdownManager manager; | |
57 manager.Shutdown(); | |
58 EXPECT_FALSE( | |
59 manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
60 EXPECT_FALSE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
61 EXPECT_FALSE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
62 } | |
63 | |
64 TEST(TaskSchedulerShutdownManagerTest, ShouldScheduleTaskBeforeShutdown) { | |
65 ShutdownManager manager; | |
66 EXPECT_TRUE( | |
67 manager.ShouldScheduleTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
68 EXPECT_TRUE( | |
69 manager.ShouldScheduleTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
70 EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
71 } | |
72 | |
73 TEST(TaskSchedulerShutdownManagerTest, | |
74 ShouldScheduleTaskAfterShutdownCompleted) { | |
75 ShutdownManager manager; | |
76 manager.Shutdown(); | |
77 EXPECT_FALSE( | |
78 manager.ShouldScheduleTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
79 EXPECT_FALSE( | |
80 manager.ShouldScheduleTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
81 EXPECT_FALSE( | |
82 manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
83 } | |
84 | |
85 TEST(TaskSchedulerShutdownManagerTest, | |
86 ShouldPostAndScheduleTaskDuringShutdown) { | |
87 ShutdownManager manager; | |
88 | |
89 // Inform the manager that a BLOCK_SHUTDOWN task has been posted, to block | |
90 // shutdown. | |
91 EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
92 | |
93 // Call manager.Shutdown() on another thread. | |
94 ThreadCallingShutdown thread(&manager); | |
95 thread.Start(); | |
96 thread.WaitUntilShutdownCalled(); | |
97 EXPECT_FALSE(thread.has_exited()); | |
98 | |
99 // Check that only a BLOCK_SHUTDOWN task can be posted. | |
100 EXPECT_FALSE( | |
101 manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
102 EXPECT_FALSE(thread.has_exited()); | |
103 EXPECT_FALSE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
104 EXPECT_FALSE(thread.has_exited()); | |
105 EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
106 EXPECT_FALSE(thread.has_exited()); | |
107 | |
108 // Check that only a BLOCK_SHUTDOWN task can be scheduled. | |
109 EXPECT_FALSE( | |
110 manager.ShouldScheduleTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
111 EXPECT_FALSE(thread.has_exited()); | |
112 EXPECT_FALSE( | |
113 manager.ShouldScheduleTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
114 EXPECT_FALSE(thread.has_exited()); | |
115 EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
116 EXPECT_FALSE(thread.has_exited()); | |
117 | |
118 // Unblock Shutdown(). | |
119 manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); | |
120 EXPECT_FALSE(thread.has_exited()); | |
121 EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
122 EXPECT_FALSE(thread.has_exited()); | |
123 manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); | |
124 | |
125 // Wait until the thread calling manager.Shutdown() exits. | |
126 thread.Join(); | |
127 EXPECT_TRUE(thread.has_exited()); | |
128 } | |
129 | |
130 TEST(TaskSchedulerShutdownManagerTest, | |
131 ShutdownWithQueuedSkipAndContinueOnShutdownTasks) { | |
132 ShutdownManager manager; | |
133 | |
134 // Inform |manager| that a CONTINUE_ON_SHUTDOWN task and a SKIP_ON_SHUTDOWN | |
135 // task have been posted. | |
136 EXPECT_TRUE( | |
137 manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
138 EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
139 | |
140 // Call manager.Shutdown(). This call shouldn't block. | |
141 manager.Shutdown(); | |
142 } | |
143 | |
144 TEST(TaskSchedulerShutdownManagerTest, | |
145 ShutdownScheduledContinueOnShutdownTasks) { | |
146 ShutdownManager manager; | |
147 | |
148 // Inform |manager| that a SKIP_ON_SHUTDOWN task has been posted and | |
149 // scheduled. | |
150 EXPECT_TRUE( | |
151 manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
152 EXPECT_TRUE( | |
153 manager.ShouldScheduleTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
154 | |
155 // Call manager.Shutdown() on another thread. This call shouldn't block. | |
156 manager.Shutdown(); | |
157 } | |
158 | |
159 TEST(TaskSchedulerShutdownManagerTest, ShutdownScheduledSkipOnShutdownTasks) { | |
160 ShutdownManager manager; | |
161 | |
162 // Inform |manager| that a SKIP_ON_SHUTDOWN task has been posted and | |
163 // scheduled. | |
164 EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
165 EXPECT_TRUE( | |
166 manager.ShouldScheduleTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
167 | |
168 // Call manager.Shutdown() on another thread. This call should block until the | |
169 // SKIP_ON_SHUTDOWN task has been executed. | |
170 ThreadCallingShutdown thread(&manager); | |
171 thread.Start(); | |
172 thread.WaitUntilShutdownCalled(); | |
173 EXPECT_FALSE(thread.has_exited()); | |
174 | |
175 // Inform |manager| that a SKIP_ON_SHUTDOWN task has been executed. | |
176 manager.DidExecuteTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN); | |
177 | |
178 // Wait until the thread calling manager.Shutdown() exits. | |
179 thread.Join(); | |
180 EXPECT_TRUE(thread.has_exited()); | |
181 } | |
182 | |
183 TEST(TaskSchedulerShutdownManagerTest, ShutdownWithQueuedBlockShutdownTasks) { | |
gab
2016/02/23 22:28:23
I think ShouldPostAndScheduleTaskDuringShutdown al
fdoray
2016/02/26 15:53:28
I completely refactored the unit tests :)
| |
184 ShutdownManager manager; | |
185 | |
186 // Inform |manager| that 2 BLOCK_SHUTDOWN task have been posted. | |
187 EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
188 EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
189 | |
190 // Call manager.Shutdown() on another thread. This call should block until | |
191 // both BLOCK_SHUTDOWN tasks have been executed. | |
192 ThreadCallingShutdown thread(&manager); | |
193 thread.Start(); | |
194 thread.WaitUntilShutdownCalled(); | |
195 EXPECT_FALSE(thread.has_exited()); | |
196 | |
197 // Inform |manager| that the first BLOCK_SHUTDOWN task has been scheduled and | |
198 // executed. | |
199 EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
200 EXPECT_FALSE(thread.has_exited()); | |
201 manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); | |
202 EXPECT_FALSE(thread.has_exited()); | |
203 | |
204 // Inform |manager| that the second BLOCK_SHUTDOWN task has been scheduled and | |
205 // executed.. | |
206 EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
207 EXPECT_FALSE(thread.has_exited()); | |
208 manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); | |
209 | |
210 // Wait until the thread calling manager.Shutdown() exits. | |
211 thread.Join(); | |
212 EXPECT_TRUE(thread.has_exited()); | |
213 } | |
214 | |
215 TEST(TaskSchedulerShutdownManagerTest, | |
216 ShutdownWithScheduledBlockShutdownTasks) { | |
217 ShutdownManager manager; | |
218 | |
219 // Inform |manager| that a BLOCK_SHUTDOWN task have been posted and scheduled. | |
220 EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
221 EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
222 | |
223 // Call manager.Shutdown() on another thread. This call should block until the | |
224 // BLOCK_SHUTDOWN task has been executed. | |
225 ThreadCallingShutdown thread(&manager); | |
226 thread.Start(); | |
227 thread.WaitUntilShutdownCalled(); | |
228 EXPECT_FALSE(thread.has_exited()); | |
229 | |
230 // Inform |manager| that a BLOCK_SHUTDOWN task has been executed. | |
231 manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); | |
232 | |
233 // Wait until the thread calling manager.Shutdown() exits. | |
234 thread.Join(); | |
235 EXPECT_TRUE(thread.has_exited()); | |
236 } | |
237 | |
238 } // namespace internal | |
239 } // namespace base | |
OLD | NEW |