OLD | NEW |
(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 |
OLD | NEW |