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

Side by Side Diff: chrome/browser/prerender/prerender_tracker_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698