OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 <set> | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/message_loop.h" | |
9 #include "chrome/browser/prerender/prerender_manager.h" | |
10 #include "chrome/browser/prerender/prerender_tracker.h" | |
11 #include "chrome/test/base/testing_browser_process.h" | |
12 #include "content/test/test_browser_thread.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 using content::BrowserThread; | |
16 | |
17 namespace prerender { | |
18 | |
19 namespace { | |
20 | |
21 class TestPrerenderManager : public PrerenderManager { | |
22 public: | |
23 explicit TestPrerenderManager(PrerenderTracker* prerender_tracker) : | |
24 PrerenderManager(NULL, prerender_tracker) { | |
25 mutable_config().rate_limit_enabled = false; | |
26 } | |
27 | |
28 virtual void DestroyPrerenderForRenderView( | |
29 int process_id, int view_id, FinalStatus final_status) OVERRIDE { | |
30 cancelled_id_pairs_.insert(std::make_pair(process_id, view_id)); | |
31 } | |
32 | |
33 bool WasPrerenderCancelled(int child_id, int route_id) { | |
34 std::pair<int, int> child_route_id_pair(child_id, route_id); | |
35 return cancelled_id_pairs_.count(child_route_id_pair) != 0; | |
36 } | |
37 | |
38 // Set of all the RenderViews that have been cancelled. | |
39 std::set<std::pair<int, int> > cancelled_id_pairs_; | |
40 }; | |
41 | |
42 } // namespace | |
43 | |
44 class PrerenderTrackerTest : public testing::Test { | |
45 public: | |
46 PrerenderTrackerTest() : | |
47 ui_thread_(BrowserThread::UI, &message_loop_), | |
48 io_thread_(BrowserThread::IO, &message_loop_), | |
49 prerender_manager_(new TestPrerenderManager(prerender_tracker())) { | |
50 } | |
51 | |
52 TestPrerenderManager* prerender_manager() { | |
53 return prerender_manager_.get(); | |
54 } | |
55 | |
56 PrerenderTracker* prerender_tracker() { | |
57 return g_browser_process->prerender_tracker(); | |
58 } | |
59 | |
60 int GetCurrentStatus(int child_id, int route_id) { | |
61 FinalStatus final_status; | |
62 if (!prerender_tracker()->GetFinalStatus(child_id, route_id, | |
63 &final_status)) { | |
64 return -1; | |
65 } | |
66 return final_status; | |
67 } | |
68 | |
69 // Runs any tasks queued on either thread. | |
70 void RunEvents() { | |
71 message_loop_.RunAllPending(); | |
72 } | |
73 | |
74 private: | |
75 MessageLoop message_loop_; | |
76 content::TestBrowserThread ui_thread_; | |
77 content::TestBrowserThread io_thread_; | |
78 | |
79 scoped_ptr<TestPrerenderManager> prerender_manager_; | |
80 }; | |
81 | |
82 // Check that a non-existant RenderView is handled correctly. | |
83 TEST_F(PrerenderTrackerTest, PrerenderTrackerNull) { | |
84 FinalStatus final_status; | |
85 EXPECT_FALSE(prerender_tracker()->TryUse(0, 0)); | |
86 EXPECT_FALSE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_HTTPS)); | |
87 EXPECT_FALSE(prerender_tracker()->TryCancelOnIOThread( | |
88 0, 0, FINAL_STATUS_HTTPS)); | |
89 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
90 EXPECT_FALSE(prerender_tracker()->GetFinalStatus(0, 0, &final_status)); | |
91 EXPECT_FALSE(prerender_manager()->WasPrerenderCancelled(0, 0)); | |
92 } | |
93 | |
94 // Check that a page that is used is handled correctly. | |
95 TEST_F(PrerenderTrackerTest, PrerenderTrackerUsed) { | |
96 prerender_tracker()->OnPrerenderingStarted(0, 0, prerender_manager()); | |
97 EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(0, 0)); | |
98 | |
99 // This calls AddPrerenderOnIOThreadTask(). | |
100 RunEvents(); | |
101 | |
102 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
103 EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(0, 0)); | |
104 | |
105 // Display the prerendered RenderView. | |
106 EXPECT_TRUE(prerender_tracker()->TryUse(0, 0)); | |
107 | |
108 // Make sure the page can't be destroyed or claim it was destroyed after | |
109 // it's been used. | |
110 EXPECT_FALSE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_HTTPS)); | |
111 EXPECT_FALSE(prerender_tracker()->TryCancelOnIOThread( | |
112 0, 0, FINAL_STATUS_TIMED_OUT)); | |
113 EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus(0, 0)); | |
114 | |
115 // This would call DestroyPrerenderForChildRouteIdPair(), if the prerender | |
116 // were cancelled. | |
117 RunEvents(); | |
118 | |
119 // These functions should all behave as before. | |
120 EXPECT_FALSE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_HTTPS)); | |
121 EXPECT_FALSE(prerender_tracker()->TryCancelOnIOThread( | |
122 0, 0, FINAL_STATUS_TIMED_OUT)); | |
123 EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus(0, 0)); | |
124 | |
125 // This calls DestroyPrerenderForChildRouteIdPair(). | |
126 prerender_tracker()->OnPrerenderingFinished(0, 0); | |
127 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
128 | |
129 // This calls RemovePrerenderOnIOThreadTask(). | |
130 RunEvents(); | |
131 | |
132 FinalStatus final_status; | |
133 EXPECT_FALSE(prerender_tracker()->GetFinalStatus(0, 0, &final_status)); | |
134 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
135 EXPECT_FALSE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_HTTPS)); | |
136 EXPECT_FALSE(prerender_manager()->WasPrerenderCancelled(0, 0)); | |
137 } | |
138 | |
139 // Check that a prerendered page cancelled by TryCancel() is handled correctly. | |
140 TEST_F(PrerenderTrackerTest, PrerenderTrackerCancelled) { | |
141 prerender_tracker()->OnPrerenderingStarted(0, 0, prerender_manager()); | |
142 EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(0, 0)); | |
143 | |
144 // This calls AddPrerenderOnIOThreadTask(). | |
145 RunEvents(); | |
146 | |
147 // Cancel the prerender. | |
148 EXPECT_TRUE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_HTTPS)); | |
149 | |
150 EXPECT_FALSE(prerender_tracker()->TryUse(0, 0)); | |
151 EXPECT_TRUE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_TIMED_OUT)); | |
152 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
153 0, 0, FINAL_STATUS_TIMED_OUT)); | |
154 EXPECT_EQ(FINAL_STATUS_HTTPS, GetCurrentStatus(0, 0)); | |
155 | |
156 // This calls DestroyPrerenderForChildRouteIdPair(). | |
157 RunEvents(); | |
158 EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled(0, 0)); | |
159 | |
160 // These should all work until the prerendering RenderViewHost is destroyed. | |
161 EXPECT_TRUE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_TIMED_OUT)); | |
162 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
163 0, 0, FINAL_STATUS_TIMED_OUT)); | |
164 EXPECT_EQ(FINAL_STATUS_HTTPS, GetCurrentStatus(0, 0)); | |
165 | |
166 prerender_tracker()->OnPrerenderingFinished(0, 0); | |
167 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
168 | |
169 // This calls RemovePrerenderOnIOThreadTask(). | |
170 RunEvents(); | |
171 | |
172 FinalStatus final_status; | |
173 EXPECT_FALSE(prerender_tracker()->GetFinalStatus(0, 0, &final_status)); | |
174 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
175 } | |
176 | |
177 // Check that a prerendered page cancelled on the IO thread by | |
178 // TryCancelOnIOThread() is handled correctly. | |
179 TEST_F(PrerenderTrackerTest, PrerenderTrackerCancelledOnIO) { | |
180 prerender_tracker()->OnPrerenderingStarted(0, 0, prerender_manager()); | |
181 EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(0, 0)); | |
182 | |
183 // This calls AddPrerenderOnIOThreadTask(). | |
184 RunEvents(); | |
185 | |
186 // Cancel the prerender. | |
187 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
188 0, 0, FINAL_STATUS_TIMED_OUT)); | |
189 | |
190 EXPECT_FALSE(prerender_tracker()->TryUse(0, 0)); | |
191 EXPECT_TRUE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_HTTPS)); | |
192 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
193 0, 0, FINAL_STATUS_HTTPS)); | |
194 EXPECT_EQ(FINAL_STATUS_TIMED_OUT, GetCurrentStatus(0, 0)); | |
195 | |
196 // This calls DestroyPrerenderForChildRouteIdPair(). | |
197 RunEvents(); | |
198 EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled(0, 0)); | |
199 | |
200 // These should all work until the prerendering RenderViewHost is destroyed. | |
201 EXPECT_TRUE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_HTTPS)); | |
202 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
203 0, 0, FINAL_STATUS_HTTPS)); | |
204 EXPECT_EQ(FINAL_STATUS_TIMED_OUT, GetCurrentStatus(0, 0)); | |
205 | |
206 prerender_tracker()->OnPrerenderingFinished(0, 0); | |
207 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
208 | |
209 // This calls RemovePrerenderOnIOThreadTask(). | |
210 RunEvents(); | |
211 | |
212 FinalStatus final_status; | |
213 EXPECT_FALSE(prerender_tracker()->GetFinalStatus(0, 0, &final_status)); | |
214 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
215 } | |
216 | |
217 // Check that a prerendered page cancelled before it reaches the IO thread is | |
218 // handled correctly. | |
219 TEST_F(PrerenderTrackerTest, PrerenderTrackerCancelledFast) { | |
220 prerender_tracker()->OnPrerenderingStarted(0, 0, prerender_manager()); | |
221 // Cancel the prerender. | |
222 EXPECT_TRUE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_HTTPS)); | |
223 | |
224 EXPECT_FALSE(prerender_tracker()->TryUse(0, 0)); | |
225 EXPECT_TRUE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_TIMED_OUT)); | |
226 | |
227 // This calls AddPrerenderOnIOThreadTask() and | |
228 // DestroyPrerenderForChildRouteIdPair(). | |
229 RunEvents(); | |
230 EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled(0, 0)); | |
231 | |
232 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
233 0, 0, FINAL_STATUS_TIMED_OUT)); | |
234 EXPECT_TRUE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_TIMED_OUT)); | |
235 EXPECT_EQ(FINAL_STATUS_HTTPS, GetCurrentStatus(0, 0)); | |
236 | |
237 prerender_tracker()->OnPrerenderingFinished(0, 0); | |
238 | |
239 // This calls RemovePrerenderOnIOThreadTask(). | |
240 RunEvents(); | |
241 | |
242 FinalStatus final_status; | |
243 EXPECT_FALSE(prerender_tracker()->GetFinalStatus(0, 0, &final_status)); | |
244 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
245 } | |
246 | |
247 // Check that handling two pages at once works. | |
248 TEST_F(PrerenderTrackerTest, PrerenderTrackerMultiple) { | |
249 prerender_tracker()->OnPrerenderingStarted(0, 0, prerender_manager()); | |
250 | |
251 // This calls AddPrerenderOnIOThreadTask(). | |
252 RunEvents(); | |
253 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
254 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread(1, 2)); | |
255 EXPECT_FALSE(prerender_tracker()->TryUse(1, 2)); | |
256 EXPECT_FALSE(prerender_tracker()->TryCancel(1, 2, FINAL_STATUS_HTTPS)); | |
257 | |
258 // Start second prerender. | |
259 prerender_tracker()->OnPrerenderingStarted(1, 2, prerender_manager()); | |
260 // This calls AddPrerenderOnIOThreadTask(). | |
261 RunEvents(); | |
262 | |
263 // Use (0, 0). | |
264 EXPECT_TRUE(prerender_tracker()->TryUse(0, 0)); | |
265 EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus(0, 0)); | |
266 EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(1, 2)); | |
267 | |
268 // Cancel (1, 2). | |
269 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
270 1, 2, FINAL_STATUS_HTTPS)); | |
271 | |
272 EXPECT_FALSE(prerender_tracker()->TryCancel(0, 0, FINAL_STATUS_HTTPS)); | |
273 EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus(0, 0)); | |
274 | |
275 EXPECT_FALSE(prerender_tracker()->TryUse(1, 2)); | |
276 EXPECT_TRUE(prerender_tracker()->TryCancel(1, 2, FINAL_STATUS_HTTPS)); | |
277 EXPECT_EQ(FINAL_STATUS_HTTPS, GetCurrentStatus(1, 2)); | |
278 | |
279 // This calls DestroyPrerenderForChildRouteIdPair(). | |
280 RunEvents(); | |
281 EXPECT_FALSE(prerender_manager()->WasPrerenderCancelled(0, 0)); | |
282 EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled(1, 2)); | |
283 | |
284 prerender_tracker()->OnPrerenderingFinished(0, 0); | |
285 prerender_tracker()->OnPrerenderingFinished(1, 2); | |
286 | |
287 // This calls RemovePrerenderOnIOThreadTask(). | |
288 RunEvents(); | |
289 | |
290 FinalStatus final_status; | |
291 EXPECT_FALSE(prerender_tracker()->GetFinalStatus(0, 0, &final_status)); | |
292 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread(0, 0)); | |
293 | |
294 EXPECT_FALSE(prerender_tracker()->GetFinalStatus(1, 2, &final_status)); | |
295 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread(1, 2)); | |
296 } | |
297 | |
298 } // namespace prerender | |
OLD | NEW |