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