1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <time.h> 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <sstream> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/timer.h" 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/values.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/predictor_api.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/url_info.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/net/predictor_common.h" 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/address_list.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/mock_host_resolver.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/winsock_init.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time; 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta; 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chrome_browser_net { 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WaitForResolutionHelper; 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef base::RepeatingTimer<WaitForResolutionHelper> HelperTimer; 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WaitForResolutionHelper { 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WaitForResolutionHelper(Predictor* predictor, const UrlList& hosts, 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HelperTimer* timer) 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : predictor_(predictor), 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hosts_(hosts), 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timer_(timer) { 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Run() { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (UrlList::const_iterator i = hosts_.begin(); i != hosts_.end(); ++i) 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (predictor_->GetResolutionDuration(*i) == 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UrlInfo::kNullDuration) 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; // We don't have resolution for that host. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When all hostnames have been resolved, exit the loop. 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timer_->Stop(); 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->Quit(); 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete timer_; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete this; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Predictor* predictor_; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const UrlList hosts_; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HelperTimer* timer_; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass PredictorTest : public testing::Test { 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PredictorTest() 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : io_thread_(BrowserThread::IO, &loop_), 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host_resolver_(new net::MockCachingHostResolver()), 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default_max_queueing_delay_(TimeDelta::FromMilliseconds( 68513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PredictorInit::kMaxSpeculativeResolveQueueDelayMs)) { 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void SetUp() { 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::EnsureWinsockInit(); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Since we are using a caching HostResolver, the following latencies will 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // only be incurred by the first request, after which the result will be 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // cached internally by |host_resolver_|. 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::RuleBasedHostResolverProc* rules = host_resolver_->rules(); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rules->AddRuleWithLatency("www.google.com", "127.0.0.1", 50); 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rules->AddRuleWithLatency("gmail.google.com.com", "127.0.0.1", 70); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rules->AddRuleWithLatency("mail.google.com", "127.0.0.1", 44); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rules->AddRuleWithLatency("gmail.com", "127.0.0.1", 63); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void WaitForResolution(Predictor* predictor, const UrlList& hosts) { 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HelperTimer* timer = new HelperTimer(); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timer->Start(TimeDelta::FromMilliseconds(100), 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new WaitForResolutionHelper(predictor, hosts, timer), 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &WaitForResolutionHelper::Run); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->Run(); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // IMPORTANT: do not move this below |host_resolver_|; the host resolver 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // must not outlive the message loop, otherwise bad things can happen 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (like posting to a deleted message loop). 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop loop_; 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread io_thread_; 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<net::MockCachingHostResolver> host_resolver_; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shorthand to access TimeDelta of PredictorInit::kMaxQueueingDelayMs. 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (It would be a static constant... except style rules preclude that :-/ ). 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TimeDelta default_max_queueing_delay_; 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//------------------------------------------------------------------------------ 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, StartupShutdownTest) { 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<Predictor> testing_master( 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new Predictor(host_resolver_.get(), 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_max_queueing_delay_, 115513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PredictorInit::kMaxSpeculativeParallelResolves, 116513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false)); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->Shutdown(); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, ShutdownWhenResolutionIsPendingTest) { 122513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<net::WaitingHostResolverProc> resolver_proc( 123513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch new net::WaitingHostResolverProc(NULL)); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host_resolver_->Reset(resolver_proc); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<Predictor> testing_master( 127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new Predictor(host_resolver_.get(), 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_max_queueing_delay_, 129513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PredictorInit::kMaxSpeculativeParallelResolves, 130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false)); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL localhost("http://localhost:80"); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UrlList names; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch names.push_back(localhost); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->PostDelayedTask(FROM_HERE, 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new MessageLoop::QuitTask(), 500); 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->Run(); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(testing_master->WasFound(localhost)); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->Shutdown(); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Clean up after ourselves. 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch resolver_proc->Signal(); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, SingleLookupTest) { 152513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<Predictor> testing_master( 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new Predictor(host_resolver_.get(), 154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_max_queueing_delay_, 155513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PredictorInit::kMaxSpeculativeParallelResolves, 156513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false)); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL goog("http://www.google.com:80"); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UrlList names; 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch names.push_back(goog); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Try to flood the predictor with many concurrent requests. 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < 10; i++) 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WaitForResolution(testing_master, names); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(testing_master->WasFound(goog)); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_GT(testing_master->peak_pending_lookups(), names.size() / 2); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_LE(testing_master->peak_pending_lookups(), names.size()); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_LE(testing_master->peak_pending_lookups(), 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->max_concurrent_dns_lookups()); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->Shutdown(); 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, ConcurrentLookupTest) { 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host_resolver_->rules()->AddSimulatedFailure("*.notfound"); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<Predictor> testing_master( 185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new Predictor(host_resolver_.get(), 186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_max_queueing_delay_, 187513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PredictorInit::kMaxSpeculativeParallelResolves, 188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false)); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL goog("http://www.google.com:80"), 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch goog2("http://gmail.google.com.com:80"), 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch goog3("http://mail.google.com:80"), 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch goog4("http://gmail.com:80"); 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL bad1("http://bad1.notfound:80"), 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bad2("http://bad2.notfound:80"); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UrlList names; 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch names.push_back(goog); 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch names.push_back(goog3); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch names.push_back(bad1); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch names.push_back(goog2); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch names.push_back(bad2); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch names.push_back(goog4); 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch names.push_back(goog); 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Try to flood the predictor with many concurrent requests. 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < 10; i++) 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WaitForResolution(testing_master, names); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(testing_master->WasFound(goog)); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(testing_master->WasFound(goog3)); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(testing_master->WasFound(goog2)); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(testing_master->WasFound(goog4)); 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(testing_master->WasFound(bad1)); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(testing_master->WasFound(bad2)); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(testing_master->WasFound(bad1)); 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(testing_master->WasFound(bad2)); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_LE(testing_master->peak_pending_lookups(), names.size()); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_LE(testing_master->peak_pending_lookups(), 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->max_concurrent_dns_lookups()); 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->Shutdown(); 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, MassiveConcurrentLookupTest) { 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host_resolver_->rules()->AddSimulatedFailure("*.notfound"); 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<Predictor> testing_master( 235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new Predictor(host_resolver_.get(), 236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_max_queueing_delay_, 237513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PredictorInit::kMaxSpeculativeParallelResolves, 238513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false)); 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UrlList names; 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < 100; i++) 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick names.push_back(GURL( 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "http://host" + base::IntToString(i) + ".notfound:80")); 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Try to flood the predictor with many concurrent requests. 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < 10; i++) 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->ResolveList(names, UrlInfo::PAGE_SCAN_MOTIVATED); 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WaitForResolution(testing_master, names); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->RunAllPending(); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_LE(testing_master->peak_pending_lookups(), names.size()); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_LE(testing_master->peak_pending_lookups(), 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->max_concurrent_dns_lookups()); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testing_master->Shutdown(); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//------------------------------------------------------------------------------ 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Functions to help synthesize and test serializations of subresource referrer 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// lists. 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Return a motivation_list if we can find one for the given motivating_host (or 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NULL if a match is not found). 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic ListValue* FindSerializationMotivation( 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& motivation, const ListValue& referral_list) { 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK_LT(0u, referral_list.GetSize()); // Room for version. 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int format_version = -1; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(referral_list.GetInteger(0, &format_version)); 2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CHECK_EQ(Predictor::PREDICTOR_REFERRER_VERSION, format_version); 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* motivation_list(NULL); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 1; i < referral_list.GetSize(); ++i) { 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch referral_list.GetList(i, &motivation_list); 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string existing_spec; 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(motivation_list->GetString(0, &existing_spec)); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (motivation == GURL(existing_spec)) 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return motivation_list; 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Create a new empty serialization list. 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic ListValue* NewEmptySerializationList() { 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* list = new ListValue; 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick list->Append(new FundamentalValue(Predictor::PREDICTOR_REFERRER_VERSION)); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return list; 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Add a motivating_url and a subresource_url to a serialized list, using 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// this given latency. This is a helper function for quickly building these 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// lists. 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void AddToSerializedList(const GURL& motivation, 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& subresource, 2953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick double use_rate, 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* referral_list ) { 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Find the motivation if it is already used. 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* motivation_list = FindSerializationMotivation(motivation, 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *referral_list); 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!motivation_list) { 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is the first mention of this motivation, so build a list. 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch motivation_list = new ListValue; 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch motivation_list->Append(new StringValue(motivation.spec())); 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Provide empty subresource list. 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch motivation_list->Append(new ListValue()); 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ...and make it part of the serialized referral_list. 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch referral_list->Append(motivation_list); 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* subresource_list(NULL); 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 0 == url; 1 == subresource_list. 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(motivation_list->GetList(1, &subresource_list)); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We won't bother to check for the subresource being there already. Worst 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // case, during deserialization, the latency value we supply plus the 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // existing value(s) will be added to the referrer. 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch subresource_list->Append(new StringValue(subresource.spec())); 3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick subresource_list->Append(new FundamentalValue(use_rate)); 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kLatencyNotFound = -1; 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For a given motivation, and subresource, find what latency is currently 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// listed. This assume a well formed serialization, which has at most one such 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// entry for any pair of names. If no such pair is found, then return false. 3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Data is written into use_rate arguments. 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic bool GetDataFromSerialization(const GURL& motivation, 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& subresource, 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ListValue& referral_list, 3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick double* use_rate) { 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* motivation_list = FindSerializationMotivation(motivation, 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch referral_list); 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!motivation_list) 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* subresource_list; 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(motivation_list->GetList(1, &subresource_list)); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < subresource_list->GetSize();) { 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url_spec; 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(subresource_list->GetString(i++, &url_spec)); 34272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(subresource_list->GetDouble(i++, use_rate)); 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (subresource == GURL(url_spec)) { 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//------------------------------------------------------------------------------ 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure nil referral lists really have no entries, and no latency listed. 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, ReferrerSerializationNilTest) { 354513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<Predictor> predictor( 355731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new Predictor(host_resolver_.get(), 356731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_max_queueing_delay_, 357513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PredictorInit::kMaxSpeculativeParallelResolves, 358513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false)); 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ListValue> referral_list(NewEmptySerializationList()); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->SerializeReferrers(referral_list.get()); 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(1U, referral_list->GetSize()); 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(GetDataFromSerialization( 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL("http://a.com:79"), GURL("http://b.com:78"), 3643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *referral_list.get(), NULL)); 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->Shutdown(); 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure that when a serialization list includes a value, that it can be 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// deserialized into the database, and can be extracted back out via 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// serialization without being changed. 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, ReferrerSerializationSingleReferrerTest) { 373513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<Predictor> predictor( 374731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new Predictor(host_resolver_.get(), 375731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_max_queueing_delay_, 376513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PredictorInit::kMaxSpeculativeParallelResolves, 377513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false)); 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL motivation_url("http://www.google.com:91"); 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL subresource_url("http://icons.google.com:90"); 3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const double kUseRate = 23.4; 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ListValue> referral_list(NewEmptySerializationList()); 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddToSerializedList(motivation_url, subresource_url, 3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kUseRate, referral_list.get()); 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->DeserializeReferrers(*referral_list.get()); 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue recovered_referral_list; 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->SerializeReferrers(&recovered_referral_list); 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2U, recovered_referral_list.GetSize()); 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double rate; 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(GetDataFromSerialization( 3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, subresource_url, recovered_referral_list, &rate)); 3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(rate, kUseRate); 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->Shutdown(); 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Verify that two floats are within 1% of each other in value. 400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define EXPECT_SIMILAR(a, b) do { \ 401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen double espilon_ratio = 1.01; \ 402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if ((a) < 0.) \ 403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen espilon_ratio = 1 / espilon_ratio; \ 404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_LT(a, espilon_ratio * (b)); \ 405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_GT((a) * espilon_ratio, b); \ 406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } while (0) 407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure the Trim() functionality works as expected. 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, ReferrerSerializationTrimTest) { 411513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<Predictor> predictor( 412731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick new Predictor(host_resolver_.get(), 413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default_max_queueing_delay_, 414513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PredictorInit::kMaxSpeculativeParallelResolves, 415513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch false)); 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL motivation_url("http://www.google.com:110"); 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL icon_subresource_url("http://icons.google.com:111"); 419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const double kRateIcon = 16.0 * Predictor::kDiscardableExpectedValue; 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL img_subresource_url("http://img.google.com:118"); 421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const double kRateImg = 8.0 * Predictor::kDiscardableExpectedValue; 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ListValue> referral_list(NewEmptySerializationList()); 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddToSerializedList( 4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, icon_subresource_url, kRateIcon, referral_list.get()); 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddToSerializedList( 4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, img_subresource_url, kRateImg, referral_list.get()); 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->DeserializeReferrers(*referral_list.get()); 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue recovered_referral_list; 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->SerializeReferrers(&recovered_referral_list); 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2U, recovered_referral_list.GetSize()); 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double rate; 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(GetDataFromSerialization( 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch motivation_url, icon_subresource_url, recovered_referral_list, 4373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick &rate)); 438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_SIMILAR(rate, kRateIcon); 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(GetDataFromSerialization( 4413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, img_subresource_url, recovered_referral_list, &rate)); 442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_SIMILAR(rate, kRateImg); 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Each time we Trim 24 times, the user_rate figures should reduce by a factor 445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // of two, until they are small, and then a trim will delete the whole entry. 446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; i < 24; ++i) 447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->TrimReferrersNow(); 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->SerializeReferrers(&recovered_referral_list); 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2U, recovered_referral_list.GetSize()); 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(GetDataFromSerialization( 4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, icon_subresource_url, recovered_referral_list, &rate)); 452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_SIMILAR(rate, kRateIcon / 2); 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(GetDataFromSerialization( 4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, img_subresource_url, recovered_referral_list, &rate)); 456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_SIMILAR(rate, kRateImg / 2); 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; i < 24; ++i) 459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->TrimReferrersNow(); 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->SerializeReferrers(&recovered_referral_list); 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2U, recovered_referral_list.GetSize()); 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(GetDataFromSerialization( 4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, icon_subresource_url, recovered_referral_list, &rate)); 464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_SIMILAR(rate, kRateIcon / 4); 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(GetDataFromSerialization( 4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, img_subresource_url, recovered_referral_list, &rate)); 467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_SIMILAR(rate, kRateImg / 4); 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; i < 24; ++i) 470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->TrimReferrersNow(); 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->SerializeReferrers(&recovered_referral_list); 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2U, recovered_referral_list.GetSize()); 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(GetDataFromSerialization( 4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, icon_subresource_url, recovered_referral_list, &rate)); 475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_SIMILAR(rate, kRateIcon / 8); 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Img is below threshold, and so it gets deleted. 4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(GetDataFromSerialization( 4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, img_subresource_url, recovered_referral_list, &rate)); 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; i < 24; ++i) 482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->TrimReferrersNow(); 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->SerializeReferrers(&recovered_referral_list); 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Icon is also trimmed away, so entire set gets discarded. 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(1U, recovered_referral_list.GetSize()); 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(GetDataFromSerialization( 4873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, icon_subresource_url, recovered_referral_list, &rate)); 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(GetDataFromSerialization( 4893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick motivation_url, img_subresource_url, recovered_referral_list, &rate)); 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predictor->Shutdown(); 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, PriorityQueuePushPopTest) { 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Predictor::HostNameQueue queue; 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL first("http://first:80"), second("http://second:90"); 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First check high priority queue FIFO functionality. 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(queue.IsEmpty()); 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(first, UrlInfo::LEARNED_REFERAL_MOTIVATED); 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(queue.IsEmpty()); 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(second, UrlInfo::MOUSE_OVER_MOTIVATED); 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(queue.IsEmpty()); 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), first); 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(queue.IsEmpty()); 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), second); 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(queue.IsEmpty()); 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Then check low priority queue FIFO functionality. 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(first, UrlInfo::PAGE_SCAN_MOTIVATED); 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(queue.IsEmpty()); 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(second, UrlInfo::OMNIBOX_MOTIVATED); 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(queue.IsEmpty()); 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), first); 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(queue.IsEmpty()); 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), second); 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(queue.IsEmpty()); 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PredictorTest, PriorityQueueReorderTest) { 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Predictor::HostNameQueue queue; 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Push all the low priority items. 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL low1("http://low1:80"), 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch low2("http://low2:80"), 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch low3("http://low3:443"), 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch low4("http://low4:80"), 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch low5("http://low5:80"), 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hi1("http://hi1:80"), 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hi2("http://hi2:80"), 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hi3("http://hi3:80"); 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(queue.IsEmpty()); 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(low1, UrlInfo::PAGE_SCAN_MOTIVATED); 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(low2, UrlInfo::UNIT_TEST_MOTIVATED); 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(low3, UrlInfo::LINKED_MAX_MOTIVATED); 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(low4, UrlInfo::OMNIBOX_MOTIVATED); 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(low5, UrlInfo::STARTUP_LIST_MOTIVATED); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(low4, UrlInfo::OMNIBOX_MOTIVATED); 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Push all the high prority items 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(hi1, UrlInfo::LEARNED_REFERAL_MOTIVATED); 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(hi2, UrlInfo::STATIC_REFERAL_MOTIVATED); 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue.Push(hi3, UrlInfo::MOUSE_OVER_MOTIVATED); 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check that high priority stuff comes out first, and in FIFO order. 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), hi1); 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), hi2); 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), hi3); 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ...and then low priority strings. 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), low1); 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), low2); 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), low3); 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), low4); 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), low5); 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(queue.Pop(), low4); 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(queue.IsEmpty()); 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(PredictorTest, CanonicalizeUrl) { 5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Base case, only handles HTTP and HTTPS. 5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(GURL(), Predictor::CanonicalizeUrl(GURL("ftp://anything"))); 5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Remove path testing. 5693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL long_url("http://host:999/path?query=value"); 5703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(Predictor::CanonicalizeUrl(long_url), long_url.GetWithEmptyPath()); 5713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Default port cannoncalization. 5733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL implied_port("http://test"); 5743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL explicit_port("http://test:80"); 5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(Predictor::CanonicalizeUrl(implied_port), 5763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Predictor::CanonicalizeUrl(explicit_port)); 5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Port is still maintained. 5793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL port_80("http://test:80"); 5803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL port_90("http://test:90"); 5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_NE(Predictor::CanonicalizeUrl(port_80), 5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Predictor::CanonicalizeUrl(port_90)); 5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Host is still maintained. 5853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL host_1("http://test_1"); 5863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL host_2("http://test_2"); 5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_NE(Predictor::CanonicalizeUrl(host_1), 5883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Predictor::CanonicalizeUrl(host_2)); 5893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Scheme is maintained (mismatch identified). 5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL http("http://test"); 5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL https("https://test"); 5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_NE(Predictor::CanonicalizeUrl(http), 5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Predictor::CanonicalizeUrl(https)); 5953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Https works fine. 5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL long_https("https://host:999/path?query=value"); 5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(Predictor::CanonicalizeUrl(long_https), 5993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick long_https.GetWithEmptyPath()); 6003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PredictorTest, DiscardPredictorResults) { 603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<Predictor> predictor( 604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new Predictor(host_resolver_.get(), 605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen default_max_queueing_delay_, 606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PredictorInit::kMaxSpeculativeParallelResolves, 607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen false)); 608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue referral_list; 609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->SerializeReferrers(&referral_list); 610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(1U, referral_list.GetSize()); 611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL host_1("http://test_1"); 613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL host_2("http://test_2"); 614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->LearnFromNavigation(host_1, host_2); 615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->SerializeReferrers(&referral_list); 617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(2U, referral_list.GetSize()); 618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->DiscardAllResults(); 620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->SerializeReferrers(&referral_list); 621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(1U, referral_list.GetSize()); 622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen predictor->Shutdown(); 624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace chrome_browser_net 627