11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/ref_counted.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_ptr.h"
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/message_loop/message_loop.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/predictors/resource_prefetcher.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/predictors/resource_prefetcher_manager.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/test/base/testing_profile.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/test/test_browser_thread.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/redirect_info.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/url_request.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/url_request_test_util.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gmock/include/gmock/gmock.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gtest/include/gtest/gtest.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::Eq;
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::Property;
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace predictors {
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Wrapper over the ResourcePrefetcher that stubs out the StartURLRequest call
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// since we do not want to do network fetches in this unittest.
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass TestResourcePrefetcher : public ResourcePrefetcher {
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestResourcePrefetcher(ResourcePrefetcher::Delegate* delegate,
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         const ResourcePrefetchPredictorConfig& config,
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         const NavigationID& navigation_id,
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         PrefetchKeyType key_type,
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         scoped_ptr<RequestVector> requests)
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : ResourcePrefetcher(delegate, config, navigation_id,
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           key_type, requests.Pass()) { }
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~TestResourcePrefetcher() { }
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD1(StartURLRequest, void(net::URLRequest* request));
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void ReadFullResponse(net::URLRequest* request) OVERRIDE {
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FinishRequest(request, Request::PREFETCH_STATUS_FROM_CACHE);
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(TestResourcePrefetcher);
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Delegate for ResourcePrefetcher.
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass TestResourcePrefetcherDelegate : public ResourcePrefetcher::Delegate {
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  explicit TestResourcePrefetcherDelegate(base::MessageLoop* loop)
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : request_context_getter_(new net::TestURLRequestContextGetter(
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          loop->message_loop_proxy())) { }
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ~TestResourcePrefetcherDelegate() { }
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return request_context_getter_->GetURLRequestContext();
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD2(ResourcePrefetcherFinished,
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               void(ResourcePrefetcher* prefetcher,
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    ResourcePrefetcher::RequestVector* requests));
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(TestResourcePrefetcherDelegate);
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The following unittest tests most of the ResourcePrefetcher except for:
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 1. Call to ReadFullResponse. There does not seem to be a good way to test the
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//    function in a unittest, and probably requires a browser_test.
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 2. Setting of the Prefetch status for cache vs non cache.
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ResourcePrefetcherTest : public testing::Test {
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ResourcePrefetcherTest();
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~ResourcePrefetcherTest();
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protected:
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef ResourcePrefetcher::Request Request;
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void AddStartUrlRequestExpectation(const std::string& url) {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*prefetcher_,
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                StartURLRequest(Property(&net::URLRequest::original_url,
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         Eq(GURL(url)))));
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void CheckPrefetcherState(size_t inflight, size_t queue, size_t host) {
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(prefetcher_->inflight_requests_.size(), inflight);
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(prefetcher_->request_queue_.size(), queue);
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(prefetcher_->host_inflight_counts_.size(), host);
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  net::URLRequest* GetInFlightRequest(const std::string& url_str) {
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GURL url(url_str);
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (std::list<Request*>::const_iterator it =
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         prefetcher_->request_queue_.begin();
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         it != prefetcher_->request_queue_.end(); ++it) {
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      EXPECT_NE((*it)->resource_url, url);
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (std::map<net::URLRequest*, Request*>::const_iterator it =
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         prefetcher_->inflight_requests_.begin();
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         it != prefetcher_->inflight_requests_.end(); ++it) {
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (it->first->original_url() == url)
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return it->first;
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(false) << "Infligh request not found: " << url_str;
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return NULL;
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnReceivedRedirect(const std::string& url) {
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    prefetcher_->OnReceivedRedirect(
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        GetInFlightRequest(url), net::RedirectInfo(), NULL);
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnAuthRequired(const std::string& url) {
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    prefetcher_->OnAuthRequired(GetInFlightRequest(url), NULL);
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnCertificateRequested(const std::string& url) {
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    prefetcher_->OnCertificateRequested(GetInFlightRequest(url), NULL);
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnSSLCertificateError(const std::string& url) {
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    prefetcher_->OnSSLCertificateError(GetInFlightRequest(url),
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       net::SSLInfo(), false);
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnResponse(const std::string& url) {
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    prefetcher_->OnResponseStarted(GetInFlightRequest(url));
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::MessageLoop loop_;
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::TestBrowserThread io_thread_;
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ResourcePrefetchPredictorConfig config_;
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestResourcePrefetcherDelegate prefetcher_delegate_;
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<TestResourcePrefetcher> prefetcher_;
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(ResourcePrefetcherTest);
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciResourcePrefetcherTest::ResourcePrefetcherTest()
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : loop_(base::MessageLoop::TYPE_IO),
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      io_thread_(content::BrowserThread::IO, &loop_),
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      prefetcher_delegate_(&loop_) {
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  config_.max_prefetches_inflight_per_navigation = 5;
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  config_.max_prefetches_inflight_per_host_per_navigation = 2;
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciResourcePrefetcherTest::~ResourcePrefetcherTest() {
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ResourcePrefetcherTest, TestPrefetcherFinishes) {
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourcePrefetcher::RequestVector> requests(
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new ResourcePrefetcher::RequestVector);
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://www.google.com/resource1.html")));
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://www.google.com/resource2.png")));
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://yahoo.com/resource1.png")));
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://yahoo.com/resource2.png")));
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://yahoo.com/resource3.png")));
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://m.google.com/resource1.jpg")));
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://www.google.com/resource3.html")));
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://m.google.com/resource2.html")));
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://m.google.com/resource3.css")));
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://m.google.com/resource4.png")));
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://yahoo.com/resource4.png")));
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://yahoo.com/resource5.png")));
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NavigationID navigation_id;
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_id.render_process_id = 1;
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_id.render_frame_id = 2;
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_id.main_frame_url = GURL("http://www.google.com");
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Needed later for comparison.
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ResourcePrefetcher::RequestVector* requests_ptr = requests.get();
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  prefetcher_.reset(new TestResourcePrefetcher(&prefetcher_delegate_,
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               config_,
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               navigation_id,
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               PREFETCH_KEY_TYPE_URL,
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               requests.Pass()));
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Starting the prefetcher maxes out the number of possible requests.
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://www.google.com/resource1.html");
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://www.google.com/resource2.png");
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://yahoo.com/resource1.png");
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://yahoo.com/resource2.png");
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://m.google.com/resource1.jpg");
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  prefetcher_->Start();
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(5, 7, 3);
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://m.google.com/resource2.html");
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://m.google.com/resource1.jpg");
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(5, 6, 3);
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://www.google.com/resource3.html");
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnSSLCertificateError("http://www.google.com/resource1.html");
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(5, 5, 3);
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://m.google.com/resource3.css");
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://m.google.com/resource2.html");
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(5, 4, 3);
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://m.google.com/resource4.png");
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnReceivedRedirect("http://www.google.com/resource3.html");
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(5, 3, 3);
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://www.google.com/resource2.png");
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(4, 3, 2);
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://yahoo.com/resource3.png");
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnReceivedRedirect("http://yahoo.com/resource2.png");
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(4, 2, 2);
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://yahoo.com/resource4.png");
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://yahoo.com/resource1.png");
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(4, 1, 2);
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://yahoo.com/resource5.png");
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://yahoo.com/resource4.png");
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(4, 0, 2);
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://yahoo.com/resource5.png");
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(3, 0, 2);
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnCertificateRequested("http://m.google.com/resource4.png");
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(2, 0, 2);
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnAuthRequired("http://m.google.com/resource3.css");
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(1, 0, 1);
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Expect the final call.
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(prefetcher_delegate_,
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              ResourcePrefetcherFinished(Eq(prefetcher_.get()),
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         Eq(requests_ptr)));
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://yahoo.com/resource3.png");
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(0, 0, 0);
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Check the prefetch status.
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_CERT_ERROR,
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[0]->prefetch_status);
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_FROM_CACHE,
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[1]->prefetch_status);
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_FROM_CACHE,
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[2]->prefetch_status);
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_REDIRECTED,
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[3]->prefetch_status);
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_FROM_CACHE,
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[4]->prefetch_status);
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_FROM_CACHE,
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[5]->prefetch_status);
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_REDIRECTED,
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[6]->prefetch_status);
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_FROM_CACHE,
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[7]->prefetch_status);
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_AUTH_REQUIRED,
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[8]->prefetch_status);
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_CERT_REQUIRED,
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[9]->prefetch_status);
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_FROM_CACHE,
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[10]->prefetch_status);
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Request::PREFETCH_STATUS_FROM_CACHE,
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            (*requests_ptr)[11]->prefetch_status);
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We need to delete requests_ptr here, though it looks to be managed by the
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // scoped_ptr requests. The scoped_ptr requests releases itself and the raw
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // pointer requests_ptr is passed to ResourcePrefetcherFinished(). In the
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // test, ResourcePrefetcherFinished() is a mock function and does not handle
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the raw pointer properly. In the real code, requests_ptr will eventually be
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // passed to and managed by ResourcePrefetchPredictor::Result::Result.
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  delete requests_ptr;
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ResourcePrefetcherTest, TestPrefetcherStopped) {
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ResourcePrefetcher::RequestVector> requests(
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new ResourcePrefetcher::RequestVector);
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://www.google.com/resource1.html")));
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://www.google.com/resource2.png")));
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://yahoo.com/resource1.png")));
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://yahoo.com/resource2.png")));
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://yahoo.com/resource3.png")));
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  requests->push_back(new ResourcePrefetcher::Request(GURL(
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "http://m.google.com/resource1.jpg")));
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NavigationID navigation_id;
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_id.render_process_id = 1;
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_id.render_frame_id = 2;
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_id.main_frame_url = GURL("http://www.google.com");
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Needed later for comparison.
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ResourcePrefetcher::RequestVector* requests_ptr = requests.get();
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  prefetcher_.reset(new TestResourcePrefetcher(&prefetcher_delegate_,
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               config_,
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               navigation_id,
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               PREFETCH_KEY_TYPE_HOST,
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                               requests.Pass()));
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Starting the prefetcher maxes out the number of possible requests.
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://www.google.com/resource1.html");
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://www.google.com/resource2.png");
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://yahoo.com/resource1.png");
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://yahoo.com/resource2.png");
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddStartUrlRequestExpectation("http://m.google.com/resource1.jpg");
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  prefetcher_->Start();
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(5, 1, 3);
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://www.google.com/resource1.html");
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(4, 1, 3);
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  prefetcher_->Stop();  // No more queueing.
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://www.google.com/resource2.png");
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(3, 1, 2);
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://yahoo.com/resource1.png");
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(2, 1, 2);
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://yahoo.com/resource2.png");
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(1, 1, 1);
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Expect the final call.
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(prefetcher_delegate_,
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              ResourcePrefetcherFinished(Eq(prefetcher_.get()),
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         Eq(requests_ptr)));
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnResponse("http://m.google.com/resource1.jpg");
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CheckPrefetcherState(0, 1, 0);
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We need to delete requests_ptr here, though it looks to be managed by the
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // scoped_ptr requests. The scoped_ptr requests releases itself and the raw
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // pointer requests_ptr is passed to ResourcePrefetcherFinished(). In the
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // test, ResourcePrefetcherFinished() is a mock function and does not handle
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the raw pointer properly. In the real code, requests_ptr will eventually be
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // passed to and managed by ResourcePrefetchPredictor::Result::Result.
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  delete requests_ptr;
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace predictors
360