Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: chrome/browser/predictors/resource_prefetcher_unittest.cc

Issue 10817004: Adds speculative prefetching of resources. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Addressing Dominich's comment. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/memory/ref_counted.h"
6 #include "base/message_loop.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "chrome/browser/predictors/resource_prefetcher.h"
9 #include "chrome/browser/predictors/resource_prefetcher_manager.h"
10 #include "chrome/test/base/testing_profile.h"
11 #include "content/public/test/test_browser_thread.h"
12 #include "net/url_request/url_request.h"
13 #include "net/url_request/url_request_test_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16
17 using testing::Eq;
18 using testing::Property;
19
20 namespace predictors {
21
22 // Wrapper over the ResourcePrefetcher that stubs out the StartURLRequest call
23 // since we do not want to do network fetches in this unittest.
24 class TestResourcePrefetcher : public ResourcePrefetcher {
25 public:
26 TestResourcePrefetcher(ResourcePrefetcher::Delegate* delegate,
27 const ResourcePrefetchPredictorConfig& config,
28 const NavigationID& navigation_id,
29 scoped_ptr<RequestVector> requests)
30 : ResourcePrefetcher(delegate, config, navigation_id, requests.Pass()) { }
31
32 virtual ~TestResourcePrefetcher() { }
33
34 MOCK_METHOD1(StartURLRequest, void(net::URLRequest* request));
35
36 void ReadFullResponse(net::URLRequest* request) OVERRIDE {
37 FinishRequest(request, Request::PREFETCH_STATUS_FROM_CACHE);
38 }
39
40 private:
41 DISALLOW_COPY_AND_ASSIGN(TestResourcePrefetcher);
42 };
43
44
45 // Delegate for ResourcePrefetcher.
46 class TestResourcePrefetcherDelegate : public ResourcePrefetcher::Delegate {
47 public:
48 explicit TestResourcePrefetcherDelegate(MessageLoop* loop)
49 : request_context_getter_(new TestURLRequestContextGetter(
50 loop->message_loop_proxy())) { }
51 ~TestResourcePrefetcherDelegate() { }
52
53 virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
54 return request_context_getter_->GetURLRequestContext();
55 }
56
57 MOCK_METHOD2(ResourcePrefetcherFinished,
58 void(ResourcePrefetcher* prefetcher,
59 ResourcePrefetcher::RequestVector* requests));
60
61 private:
62 TestURLRequestContextGetter* request_context_getter_;
Lei Zhang 2012/09/15 01:45:11 This probably should have been a scoped_ptr.
63
64 DISALLOW_COPY_AND_ASSIGN(TestResourcePrefetcherDelegate);
65 };
66
67
68 // The following unittest tests most of the ResourcePrefetcher except for:
69 // 1. Call to ReadFullResponse. There does not seem to be a good way to test the
70 // function in a unittest, and probably requires a browser_test.
71 // 2. Setting of the Prefetch status for cache vs non cache.
72 class ResourcePrefetcherTest : public testing::Test {
73 public:
74 ResourcePrefetcherTest();
75 ~ResourcePrefetcherTest();
76
77 protected:
78 typedef ResourcePrefetcher::Request Request;
79
80 void AddStartUrlRequestExpectation(const std::string& url) {
81 EXPECT_CALL(*prefetcher_,
82 StartURLRequest(Property(&net::URLRequest::original_url,
83 Eq(GURL(url)))));
84 }
85
86 void CheckPrefetcherState(size_t inflight, size_t queue, size_t host) {
87 EXPECT_EQ(prefetcher_->inflight_requests_.size(), inflight);
88 EXPECT_EQ(prefetcher_->request_queue_.size(), queue);
89 EXPECT_EQ(prefetcher_->host_inflight_counts_.size(), host);
90 }
91
92 net::URLRequest* GetInFlightRequest(const std::string& url_str) {
93 GURL url(url_str);
94
95 for (std::list<Request*>::const_iterator it =
96 prefetcher_->request_queue_.begin();
97 it != prefetcher_->request_queue_.end(); ++it) {
98 EXPECT_NE((*it)->resource_url, url);
99 }
100 for (std::map<net::URLRequest*, Request*>::const_iterator it =
101 prefetcher_->inflight_requests_.begin();
102 it != prefetcher_->inflight_requests_.end(); ++it) {
103 if (it->first->original_url() == url)
104 return it->first;
105 }
106 EXPECT_TRUE(false) << "Infligh request not found: " << url_str;
107 return NULL;
108 }
109
110
111 void OnReceivedRedirect(const std::string& url) {
112 prefetcher_->OnReceivedRedirect(GetInFlightRequest(url), GURL(""), NULL);
113 }
114 void OnAuthRequired(const std::string& url) {
115 prefetcher_->OnAuthRequired(GetInFlightRequest(url), NULL);
116 }
117 void OnCertificateRequested(const std::string& url) {
118 prefetcher_->OnCertificateRequested(GetInFlightRequest(url), NULL);
119 }
120 void OnSSLCertificateError(const std::string& url) {
121 prefetcher_->OnSSLCertificateError(GetInFlightRequest(url),
122 net::SSLInfo(), false);
123 }
124 void OnResponse(const std::string& url) {
125 prefetcher_->OnResponseStarted(GetInFlightRequest(url));
126 }
127
128 MessageLoop loop_;
129 content::TestBrowserThread io_thread_;
130 ResourcePrefetchPredictorConfig config_;
131 TestResourcePrefetcherDelegate prefetcher_delegate_;
132 scoped_ptr<TestResourcePrefetcher> prefetcher_;
133
134 private:
135 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetcherTest);
136 };
137
138 ResourcePrefetcherTest::ResourcePrefetcherTest()
139 : loop_(MessageLoop::TYPE_IO),
140 io_thread_(content::BrowserThread::IO, &loop_),
141 prefetcher_delegate_(&loop_) {
142 config_.max_prefetches_inflight_per_navigation = 5;
143 config_.max_prefetches_inflight_per_host_per_navigation = 2;
144 }
145
146 ResourcePrefetcherTest::~ResourcePrefetcherTest() {
147 }
148
149 TEST_F(ResourcePrefetcherTest, TestPrefetcherFinishes) {
150 scoped_ptr<ResourcePrefetcher::RequestVector> requests(
151 new ResourcePrefetcher::RequestVector);
152 requests->push_back(new ResourcePrefetcher::Request(GURL(
153 "http://www.google.com/resource1.html")));
154 requests->push_back(new ResourcePrefetcher::Request(GURL(
155 "http://www.google.com/resource2.png")));
156 requests->push_back(new ResourcePrefetcher::Request(GURL(
157 "http://yahoo.com/resource1.png")));
158 requests->push_back(new ResourcePrefetcher::Request(GURL(
159 "http://yahoo.com/resource2.png")));
160 requests->push_back(new ResourcePrefetcher::Request(GURL(
161 "http://yahoo.com/resource3.png")));
162 requests->push_back(new ResourcePrefetcher::Request(GURL(
163 "http://m.google.com/resource1.jpg")));
164 requests->push_back(new ResourcePrefetcher::Request(GURL(
165 "http://www.google.com/resource3.html")));
166 requests->push_back(new ResourcePrefetcher::Request(GURL(
167 "http://m.google.com/resource2.html")));
168 requests->push_back(new ResourcePrefetcher::Request(GURL(
169 "http://m.google.com/resource3.css")));
170 requests->push_back(new ResourcePrefetcher::Request(GURL(
171 "http://m.google.com/resource4.png")));
172 requests->push_back(new ResourcePrefetcher::Request(GURL(
173 "http://yahoo.com/resource4.png")));
174 requests->push_back(new ResourcePrefetcher::Request(GURL(
175 "http://yahoo.com/resource5.png")));
176
177 NavigationID navigation_id;
178 navigation_id.render_process_id = 1;
179 navigation_id.render_view_id = 2;
180 navigation_id.main_frame_url = GURL("http://www.google.com");
181
182 // Needed later for comparison.
183 ResourcePrefetcher::RequestVector* requests_ptr = requests.get();
184
185 prefetcher_.reset(new TestResourcePrefetcher(&prefetcher_delegate_,
186 config_,
187 navigation_id,
188 requests.Pass()));
189
190 // Starting the prefetcher maxes out the number of possible requests.
191 AddStartUrlRequestExpectation("http://www.google.com/resource1.html");
192 AddStartUrlRequestExpectation("http://www.google.com/resource2.png");
193 AddStartUrlRequestExpectation("http://yahoo.com/resource1.png");
194 AddStartUrlRequestExpectation("http://yahoo.com/resource2.png");
195 AddStartUrlRequestExpectation("http://m.google.com/resource1.jpg");
196
197 prefetcher_->Start();
198 CheckPrefetcherState(5, 7, 3);
199
200 AddStartUrlRequestExpectation("http://m.google.com/resource2.html");
201 OnResponse("http://m.google.com/resource1.jpg");
202 CheckPrefetcherState(5, 6, 3);
203
204 AddStartUrlRequestExpectation("http://www.google.com/resource3.html");
205 OnSSLCertificateError("http://www.google.com/resource1.html");
206 CheckPrefetcherState(5, 5, 3);
207
208 AddStartUrlRequestExpectation("http://m.google.com/resource3.css");
209 OnResponse("http://m.google.com/resource2.html");
210 CheckPrefetcherState(5, 4, 3);
211
212 AddStartUrlRequestExpectation("http://m.google.com/resource4.png");
213 OnReceivedRedirect("http://www.google.com/resource3.html");
214 CheckPrefetcherState(5, 3, 3);
215
216 OnResponse("http://www.google.com/resource2.png");
217 CheckPrefetcherState(4, 3, 2);
218
219 AddStartUrlRequestExpectation("http://yahoo.com/resource3.png");
220 OnReceivedRedirect("http://yahoo.com/resource2.png");
221 CheckPrefetcherState(4, 2, 2);
222
223 AddStartUrlRequestExpectation("http://yahoo.com/resource4.png");
224 OnResponse("http://yahoo.com/resource1.png");
225 CheckPrefetcherState(4, 1, 2);
226
227 AddStartUrlRequestExpectation("http://yahoo.com/resource5.png");
228 OnResponse("http://yahoo.com/resource4.png");
229 CheckPrefetcherState(4, 0, 2);
230
231 OnResponse("http://yahoo.com/resource5.png");
232 CheckPrefetcherState(3, 0, 2);
233
234 OnCertificateRequested("http://m.google.com/resource4.png");
235 CheckPrefetcherState(2, 0, 2);
236
237 OnAuthRequired("http://m.google.com/resource3.css");
238 CheckPrefetcherState(1, 0, 1);
239
240 // Expect the final call.
241 EXPECT_CALL(prefetcher_delegate_,
242 ResourcePrefetcherFinished(Eq(prefetcher_.get()),
243 Eq(requests_ptr)));
244
245 OnResponse("http://yahoo.com/resource3.png");
246 CheckPrefetcherState(0, 0, 0);
247
248 // Check the prefetch status.
249 EXPECT_EQ((*requests_ptr)[0]->prefetch_status,
250 Request::PREFETCH_STATUS_CERT_ERROR);
251 EXPECT_EQ((*requests_ptr)[1]->prefetch_status,
252 Request::PREFETCH_STATUS_FROM_CACHE);
253 EXPECT_EQ((*requests_ptr)[2]->prefetch_status,
254 Request::PREFETCH_STATUS_FROM_CACHE);
255 EXPECT_EQ((*requests_ptr)[3]->prefetch_status,
256 Request::PREFETCH_STATUS_REDIRECTED);
257 EXPECT_EQ((*requests_ptr)[4]->prefetch_status,
258 Request::PREFETCH_STATUS_FROM_CACHE);
259 EXPECT_EQ((*requests_ptr)[5]->prefetch_status,
260 Request::PREFETCH_STATUS_FROM_CACHE);
261 EXPECT_EQ((*requests_ptr)[6]->prefetch_status,
262 Request::PREFETCH_STATUS_REDIRECTED);
263 EXPECT_EQ((*requests_ptr)[7]->prefetch_status,
264 Request::PREFETCH_STATUS_FROM_CACHE);
265 EXPECT_EQ((*requests_ptr)[8]->prefetch_status,
266 Request::PREFETCH_STATUS_AUTH_REQUIRED);
267 EXPECT_EQ((*requests_ptr)[9]->prefetch_status,
268 Request::PREFETCH_STATUS_CERT_REQUIRED);
269 EXPECT_EQ((*requests_ptr)[10]->prefetch_status,
270 Request::PREFETCH_STATUS_FROM_CACHE);
271 EXPECT_EQ((*requests_ptr)[11]->prefetch_status,
272 Request::PREFETCH_STATUS_FROM_CACHE);
273 }
274
275 TEST_F(ResourcePrefetcherTest, TestPrefetcherStopped) {
276 scoped_ptr<ResourcePrefetcher::RequestVector> requests(
277 new ResourcePrefetcher::RequestVector);
278 requests->push_back(new ResourcePrefetcher::Request(GURL(
279 "http://www.google.com/resource1.html")));
280 requests->push_back(new ResourcePrefetcher::Request(GURL(
281 "http://www.google.com/resource2.png")));
282 requests->push_back(new ResourcePrefetcher::Request(GURL(
283 "http://yahoo.com/resource1.png")));
284 requests->push_back(new ResourcePrefetcher::Request(GURL(
285 "http://yahoo.com/resource2.png")));
286 requests->push_back(new ResourcePrefetcher::Request(GURL(
287 "http://yahoo.com/resource3.png")));
288 requests->push_back(new ResourcePrefetcher::Request(GURL(
289 "http://m.google.com/resource1.jpg")));
290
291 NavigationID navigation_id;
292 navigation_id.render_process_id = 1;
293 navigation_id.render_view_id = 2;
294 navigation_id.main_frame_url = GURL("http://www.google.com");
295
296 // Needed later for comparison.
297 ResourcePrefetcher::RequestVector* requests_ptr = requests.get();
298
299 prefetcher_.reset(new TestResourcePrefetcher(&prefetcher_delegate_,
300 config_,
301 navigation_id,
302 requests.Pass()));
303
304 // Starting the prefetcher maxes out the number of possible requests.
305 AddStartUrlRequestExpectation("http://www.google.com/resource1.html");
306 AddStartUrlRequestExpectation("http://www.google.com/resource2.png");
307 AddStartUrlRequestExpectation("http://yahoo.com/resource1.png");
308 AddStartUrlRequestExpectation("http://yahoo.com/resource2.png");
309 AddStartUrlRequestExpectation("http://m.google.com/resource1.jpg");
310
311 prefetcher_->Start();
312 CheckPrefetcherState(5, 1, 3);
313
314 OnResponse("http://www.google.com/resource1.html");
315 CheckPrefetcherState(4, 1, 3);
316
317 prefetcher_->Stop(); // No more queueing.
318
319 OnResponse("http://www.google.com/resource2.png");
320 CheckPrefetcherState(3, 1, 2);
321
322 OnResponse("http://yahoo.com/resource1.png");
323 CheckPrefetcherState(2, 1, 2);
324
325 OnResponse("http://yahoo.com/resource2.png");
326 CheckPrefetcherState(1, 1, 1);
327
328 // Expect the final call.
329 EXPECT_CALL(prefetcher_delegate_,
330 ResourcePrefetcherFinished(Eq(prefetcher_.get()),
331 Eq(requests_ptr)));
332
333 OnResponse("http://m.google.com/resource1.jpg");
334 CheckPrefetcherState(0, 1, 0);
335 }
336
337 } // namespace predictors
OLDNEW
« no previous file with comments | « chrome/browser/predictors/resource_prefetcher_manager.cc ('k') | chrome/browser/prerender/prerender_field_trial.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698