| Index: chrome/browser/prerender/prerender_render_view_tracker_unittest.cc
|
| diff --git a/chrome/browser/prerender/prerender_render_view_tracker_unittest.cc b/chrome/browser/prerender/prerender_render_view_tracker_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c5017cd026a07da271fcc18ff5e9bd25e8093a9e
|
| --- /dev/null
|
| +++ b/chrome/browser/prerender/prerender_render_view_tracker_unittest.cc
|
| @@ -0,0 +1,330 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <set>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/message_loop.h"
|
| +#include "chrome/browser/prerender/prerender_manager.h"
|
| +#include "chrome/browser/prerender/prerender_render_view_tracker.h"
|
| +#include "chrome/test/base/testing_browser_process.h"
|
| +#include "content/test/test_browser_thread.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using content::BrowserThread;
|
| +
|
| +namespace prerender {
|
| +
|
| +namespace {
|
| +
|
| +class TestPrerenderManager : public PrerenderManager {
|
| + public:
|
| + explicit TestPrerenderManager(
|
| + PrerenderRenderViewTracker* prerender_render_view_tracker)
|
| + : PrerenderManager(NULL, prerender_render_view_tracker) {
|
| + mutable_config().rate_limit_enabled = false;
|
| + }
|
| +
|
| + virtual void DestroyPrerenderForRenderView(
|
| + int process_id, int view_id, FinalStatus final_status) OVERRIDE {
|
| + cancelled_id_pairs_.insert(std::make_pair(process_id, view_id));
|
| + }
|
| +
|
| + bool WasPrerenderCancelled(int child_id, int route_id) {
|
| + std::pair<int, int> child_route_id_pair(child_id, route_id);
|
| + return cancelled_id_pairs_.count(child_route_id_pair) != 0;
|
| + }
|
| +
|
| + // Set of all the RenderViews that have been cancelled.
|
| + std::set<std::pair<int, int> > cancelled_id_pairs_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class PrerenderRenderViewTrackerTest : public testing::Test {
|
| + public:
|
| + PrerenderRenderViewTrackerTest() :
|
| + ui_thread_(BrowserThread::UI, &message_loop_),
|
| + io_thread_(BrowserThread::IO, &message_loop_),
|
| + prerender_manager_(
|
| + new TestPrerenderManager(prerender_render_view_tracker())) {
|
| + }
|
| +
|
| + TestPrerenderManager* prerender_manager() {
|
| + return prerender_manager_.get();
|
| + }
|
| +
|
| + PrerenderRenderViewTracker* prerender_render_view_tracker() {
|
| + return g_browser_process->prerender_render_view_tracker();
|
| + }
|
| +
|
| + int GetCurrentStatus(int child_id, int route_id) {
|
| + FinalStatus final_status;
|
| + if (!prerender_render_view_tracker()->GetFinalStatus(child_id, route_id,
|
| + &final_status)) {
|
| + return -1;
|
| + }
|
| + return final_status;
|
| + }
|
| +
|
| + // Runs any tasks queued on either thread.
|
| + void RunEvents() {
|
| + message_loop_.RunAllPending();
|
| + }
|
| +
|
| + private:
|
| + MessageLoop message_loop_;
|
| + content::TestBrowserThread ui_thread_;
|
| + content::TestBrowserThread io_thread_;
|
| +
|
| + scoped_ptr<TestPrerenderManager> prerender_manager_;
|
| +};
|
| +
|
| +// Check that a non-existant RenderView is handled correctly.
|
| +TEST_F(PrerenderRenderViewTrackerTest, PrerenderRenderViewTrackerNull) {
|
| + FinalStatus final_status;
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryUse(0, 0));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->GetFinalStatus(
|
| + 0, 0, &final_status));
|
| + EXPECT_FALSE(prerender_manager()->WasPrerenderCancelled(0, 0));
|
| +}
|
| +
|
| +// Check that a page that is used is handled correctly.
|
| +TEST_F(PrerenderRenderViewTrackerTest, PrerenderRenderViewTrackerUsed) {
|
| + prerender_render_view_tracker()->OnPrerenderingStarted(
|
| + 0, 0, prerender_manager());
|
| + EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(0, 0));
|
| +
|
| + // This calls AddPrerenderOnIOThreadTask().
|
| + RunEvents();
|
| +
|
| + EXPECT_TRUE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| + EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(0, 0));
|
| +
|
| + // Display the prerendered RenderView.
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryUse(0, 0));
|
| +
|
| + // Make sure the page can't be destroyed or claim it was destroyed after
|
| + // it's been used.
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| + EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus(0, 0));
|
| +
|
| + // This would call DestroyPrerenderForChildRouteIdPair(), if the prerender
|
| + // were cancelled.
|
| + RunEvents();
|
| +
|
| + // These functions should all behave as before.
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| + EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus(0, 0));
|
| +
|
| + // This calls DestroyPrerenderForChildRouteIdPair().
|
| + prerender_render_view_tracker()->OnPrerenderingFinished(0, 0);
|
| + EXPECT_TRUE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| +
|
| + // This calls RemovePrerenderOnIOThreadTask().
|
| + RunEvents();
|
| +
|
| + FinalStatus final_status;
|
| + EXPECT_FALSE(prerender_render_view_tracker()->GetFinalStatus(
|
| + 0, 0, &final_status));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_FALSE(prerender_manager()->WasPrerenderCancelled(0, 0));
|
| +}
|
| +
|
| +// Check that a prerendered page cancelled by TryCancel() is handled correctly.
|
| +TEST_F(PrerenderRenderViewTrackerTest, PrerenderRenderViewTrackerCancelled) {
|
| + prerender_render_view_tracker()->OnPrerenderingStarted(
|
| + 0, 0, prerender_manager());
|
| + EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(0, 0));
|
| +
|
| + // This calls AddPrerenderOnIOThreadTask().
|
| + RunEvents();
|
| +
|
| + // Cancel the prerender.
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| +
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryUse(0, 0));
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| + EXPECT_EQ(FINAL_STATUS_HTTPS, GetCurrentStatus(0, 0));
|
| +
|
| + // This calls DestroyPrerenderForChildRouteIdPair().
|
| + RunEvents();
|
| + EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled(0, 0));
|
| +
|
| + // These should all work until the prerendering RenderViewHost is destroyed.
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| + EXPECT_EQ(FINAL_STATUS_HTTPS, GetCurrentStatus(0, 0));
|
| +
|
| + prerender_render_view_tracker()->OnPrerenderingFinished(0, 0);
|
| + EXPECT_TRUE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| +
|
| + // This calls RemovePrerenderOnIOThreadTask().
|
| + RunEvents();
|
| +
|
| + FinalStatus final_status;
|
| + EXPECT_FALSE(prerender_render_view_tracker()->GetFinalStatus(
|
| + 0, 0, &final_status));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| +}
|
| +
|
| +// Check that a prerendered page cancelled on the IO thread by
|
| +// TryCancelOnIOThread() is handled correctly.
|
| +TEST_F(PrerenderRenderViewTrackerTest,
|
| + PrerenderRenderViewTrackerCancelledOnIO) {
|
| + prerender_render_view_tracker()->OnPrerenderingStarted(
|
| + 0, 0, prerender_manager());
|
| + EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(0, 0));
|
| +
|
| + // This calls AddPrerenderOnIOThreadTask().
|
| + RunEvents();
|
| +
|
| + // Cancel the prerender.
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| +
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryUse(0, 0));
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_EQ(FINAL_STATUS_TIMED_OUT, GetCurrentStatus(0, 0));
|
| +
|
| + // This calls DestroyPrerenderForChildRouteIdPair().
|
| + RunEvents();
|
| + EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled(0, 0));
|
| +
|
| + // These should all work until the prerendering RenderViewHost is destroyed.
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_EQ(FINAL_STATUS_TIMED_OUT, GetCurrentStatus(0, 0));
|
| +
|
| + prerender_render_view_tracker()->OnPrerenderingFinished(0, 0);
|
| + EXPECT_TRUE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| +
|
| + // This calls RemovePrerenderOnIOThreadTask().
|
| + RunEvents();
|
| +
|
| + FinalStatus final_status;
|
| + EXPECT_FALSE(prerender_render_view_tracker()->GetFinalStatus(
|
| + 0, 0, &final_status));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| +}
|
| +
|
| +// Check that a prerendered page cancelled before it reaches the IO thread is
|
| +// handled correctly.
|
| +TEST_F(PrerenderRenderViewTrackerTest,
|
| + PrerenderRenderViewTrackerCancelledFast) {
|
| + prerender_render_view_tracker()->OnPrerenderingStarted(
|
| + 0, 0, prerender_manager());
|
| + // Cancel the prerender.
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| +
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryUse(0, 0));
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| +
|
| + // This calls AddPrerenderOnIOThreadTask() and
|
| + // DestroyPrerenderForChildRouteIdPair().
|
| + RunEvents();
|
| + EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled(0, 0));
|
| +
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_TIMED_OUT));
|
| + EXPECT_EQ(FINAL_STATUS_HTTPS, GetCurrentStatus(0, 0));
|
| +
|
| + prerender_render_view_tracker()->OnPrerenderingFinished(0, 0);
|
| +
|
| + // This calls RemovePrerenderOnIOThreadTask().
|
| + RunEvents();
|
| +
|
| + FinalStatus final_status;
|
| + EXPECT_FALSE(prerender_render_view_tracker()->GetFinalStatus(
|
| + 0, 0, &final_status));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| +}
|
| +
|
| +// Check that handling two pages at once works.
|
| +TEST_F(PrerenderRenderViewTrackerTest, PrerenderRenderViewTrackerMultiple) {
|
| + prerender_render_view_tracker()->OnPrerenderingStarted(
|
| + 0, 0, prerender_manager());
|
| +
|
| + // This calls AddPrerenderOnIOThreadTask().
|
| + RunEvents();
|
| + EXPECT_TRUE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(1, 2));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryUse(1, 2));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryCancel(
|
| + 1, 2, FINAL_STATUS_HTTPS));
|
| +
|
| + // Start second prerender.
|
| + prerender_render_view_tracker()->OnPrerenderingStarted(
|
| + 1, 2, prerender_manager());
|
| + // This calls AddPrerenderOnIOThreadTask().
|
| + RunEvents();
|
| +
|
| + // Use (0, 0).
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryUse(0, 0));
|
| + EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus(0, 0));
|
| + EXPECT_EQ(FINAL_STATUS_MAX, GetCurrentStatus(1, 2));
|
| +
|
| + // Cancel (1, 2).
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancelOnIOThread(
|
| + 1, 2, FINAL_STATUS_HTTPS));
|
| +
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryCancel(
|
| + 0, 0, FINAL_STATUS_HTTPS));
|
| + EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus(0, 0));
|
| +
|
| + EXPECT_FALSE(prerender_render_view_tracker()->TryUse(1, 2));
|
| + EXPECT_TRUE(prerender_render_view_tracker()->TryCancel(
|
| + 1, 2, FINAL_STATUS_HTTPS));
|
| + EXPECT_EQ(FINAL_STATUS_HTTPS, GetCurrentStatus(1, 2));
|
| +
|
| + // This calls DestroyPrerenderForChildRouteIdPair().
|
| + RunEvents();
|
| + EXPECT_FALSE(prerender_manager()->WasPrerenderCancelled(0, 0));
|
| + EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled(1, 2));
|
| +
|
| + prerender_render_view_tracker()->OnPrerenderingFinished(0, 0);
|
| + prerender_render_view_tracker()->OnPrerenderingFinished(1, 2);
|
| +
|
| + // This calls RemovePrerenderOnIOThreadTask().
|
| + RunEvents();
|
| +
|
| + FinalStatus final_status;
|
| + EXPECT_FALSE(prerender_render_view_tracker()->GetFinalStatus(
|
| + 0, 0, &final_status));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(0, 0));
|
| +
|
| + EXPECT_FALSE(prerender_render_view_tracker()->GetFinalStatus(
|
| + 1, 2, &final_status));
|
| + EXPECT_FALSE(prerender_render_view_tracker()->IsPrerenderingOnIOThread(1, 2));
|
| +}
|
| +
|
| +} // namespace prerender
|
|
|