OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/prerender/prerender_resource_handler.h" | 5 #include "chrome/browser/prerender/prerender_resource_handler.h" |
6 #include "chrome/common/resource_response.h" | 6 #include "chrome/common/resource_response.h" |
7 #include "net/http/http_response_headers.h" | 7 #include "net/http/http_response_headers.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
9 | 9 |
10 namespace { | 10 namespace { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 const std::string& security_info) { | 52 const std::string& security_info) { |
53 return true; | 53 return true; |
54 } | 54 } |
55 | 55 |
56 virtual void OnRequestClosed() { | 56 virtual void OnRequestClosed() { |
57 } | 57 } |
58 | 58 |
59 virtual void OnDataDownloaded(int request_id, int bytes_downloaded) {} | 59 virtual void OnDataDownloaded(int request_id, int bytes_downloaded) {} |
60 }; | 60 }; |
61 | 61 |
62 base::Time FixedGetCurrentTime() { | |
63 return base::Time(); | |
64 } | |
65 | |
66 // HttpResponseHeaders expects the raw input for it's constructor | 62 // HttpResponseHeaders expects the raw input for it's constructor |
67 // to be a NUL ('\0') separated string for each line. This is a little | 63 // to be a NUL ('\0') separated string for each line. This is a little |
68 // difficult to do for string literals, so this helper function accepts | 64 // difficult to do for string literals, so this helper function accepts |
69 // newline-separated string literals and does the substitution. The | 65 // newline-separated string literals and does the substitution. The |
70 // returned object is expected to be deleted by the caller. | 66 // returned object is expected to be deleted by the caller. |
71 net::HttpResponseHeaders* CreateResponseHeaders( | 67 net::HttpResponseHeaders* CreateResponseHeaders( |
72 const char* newline_separated_headers) { | 68 const char* newline_separated_headers) { |
73 std::string headers(newline_separated_headers); | 69 std::string headers(newline_separated_headers); |
74 std::string::iterator i = headers.begin(); | 70 std::string::iterator i = headers.begin(); |
75 std::string::iterator end = headers.end(); | 71 std::string::iterator end = headers.end(); |
76 while (i != end) { | 72 while (i != end) { |
77 if (*i == '\n') | 73 if (*i == '\n') |
78 *i = '\0'; | 74 *i = '\0'; |
79 ++i; | 75 ++i; |
80 } | 76 } |
81 return new net::HttpResponseHeaders(headers); | 77 return new net::HttpResponseHeaders(headers); |
82 } | 78 } |
83 | 79 |
84 } // namespace | 80 } // namespace |
85 | 81 |
86 class PrerenderResourceHandlerTest : public testing::Test { | 82 class PrerenderResourceHandlerTest : public testing::Test { |
87 protected: | 83 protected: |
88 PrerenderResourceHandlerTest() | 84 PrerenderResourceHandlerTest() |
89 : prerender_duration_(base::TimeDelta::FromSeconds(10)), | 85 : ALLOW_THIS_IN_INITIALIZER_LIST( |
90 ALLOW_THIS_IN_INITIALIZER_LIST( | |
91 pre_handler_(new PrerenderResourceHandler( | 86 pre_handler_(new PrerenderResourceHandler( |
92 new MockResourceHandler(), | 87 new MockResourceHandler(), |
93 NewCallback( | 88 NewCallback( |
94 this, | 89 this, |
95 &PrerenderResourceHandlerTest::SetLastHandledURL)))), | 90 &PrerenderResourceHandlerTest::SetLastHandledURL)))), |
96 ui_thread_(BrowserThread::UI, &loop_), | 91 ui_thread_(BrowserThread::UI, &loop_), |
97 io_thread_(BrowserThread::IO, &loop_), | 92 io_thread_(BrowserThread::IO, &loop_), |
98 default_url_("http://www.prerender.com") { | 93 default_url_("http://www.prerender.com") { |
99 pre_handler_->set_prerender_duration(prerender_duration_); | |
100 pre_handler_->set_get_current_time_function(&FixedGetCurrentTime); | |
101 } | 94 } |
102 | 95 |
103 virtual ~PrerenderResourceHandlerTest() { | 96 virtual ~PrerenderResourceHandlerTest() { |
104 // When a ResourceHandler's reference count drops to 0, it is not | 97 // When a ResourceHandler's reference count drops to 0, it is not |
105 // deleted immediately. Instead, a task is posted to the IO thread's | 98 // deleted immediately. Instead, a task is posted to the IO thread's |
106 // message loop to delete it. | 99 // message loop to delete it. |
107 // So, drop the reference count to 0 and run the message loop once | 100 // So, drop the reference count to 0 and run the message loop once |
108 // to ensure that all resources are cleaned up before the test exits. | 101 // to ensure that all resources are cleaned up before the test exits. |
109 pre_handler_ = NULL; | 102 pre_handler_ = NULL; |
110 loop_.RunAllPending(); | 103 loop_.RunAllPending(); |
111 } | 104 } |
112 | 105 |
113 void SetLastHandledURL(const GURL& url, const std::vector<GURL>& alias_urls) { | 106 void SetLastHandledURL(const GURL& url, const std::vector<GURL>& alias_urls) { |
114 last_handled_url_ = url; | 107 last_handled_url_ = url; |
115 alias_urls_ = alias_urls; | 108 alias_urls_ = alias_urls; |
116 } | 109 } |
117 | 110 |
118 // Common logic shared by many of the tests | 111 // Common logic shared by many of the tests |
119 void StartPrerendering(const std::string& mime_type, | 112 void StartPrerendering(const std::string& mime_type, |
120 const char* headers) { | 113 const char* headers) { |
121 int request_id = 1; | 114 int request_id = 1; |
122 bool defer = false; | 115 bool defer = false; |
123 EXPECT_TRUE(pre_handler_->OnWillStart(request_id, default_url_, &defer)); | 116 EXPECT_TRUE(pre_handler_->OnWillStart(request_id, default_url_, &defer)); |
124 EXPECT_FALSE(defer); | 117 EXPECT_FALSE(defer); |
125 scoped_refptr<ResourceResponse> response(new ResourceResponse); | 118 scoped_refptr<ResourceResponse> response(new ResourceResponse); |
126 response->response_head.request_time = FixedGetCurrentTime(); | |
127 response->response_head.response_time = FixedGetCurrentTime(); | |
128 response->response_head.mime_type = mime_type; | 119 response->response_head.mime_type = mime_type; |
129 response->response_head.headers = CreateResponseHeaders(headers); | 120 response->response_head.headers = CreateResponseHeaders(headers); |
130 EXPECT_TRUE(last_handled_url_.is_empty()); | 121 EXPECT_TRUE(last_handled_url_.is_empty()); |
131 | 122 |
132 // Start the response. If it is able to prerender, a task will | 123 // Start the response. If it is able to prerender, a task will |
133 // be posted to the UI thread and |SetLastHandledURL| will be called. | 124 // be posted to the UI thread and |SetLastHandledURL| will be called. |
134 EXPECT_TRUE(pre_handler_->OnResponseStarted(request_id, response)); | 125 EXPECT_TRUE(pre_handler_->OnResponseStarted(request_id, response)); |
135 loop_.RunAllPending(); | 126 loop_.RunAllPending(); |
136 } | 127 } |
137 | 128 |
138 // Test whether a given URL is part of alias_urls_. | 129 // Test whether a given URL is part of alias_urls_. |
139 bool ContainsAliasURL(const GURL& url) { | 130 bool ContainsAliasURL(const GURL& url) { |
140 return std::find(alias_urls_.begin(), alias_urls_.end(), url) | 131 return std::find(alias_urls_.begin(), alias_urls_.end(), url) |
141 != alias_urls_.end(); | 132 != alias_urls_.end(); |
142 } | 133 } |
143 | 134 |
144 base::TimeDelta prerender_duration_; | |
145 scoped_refptr<PrerenderResourceHandler> pre_handler_; | 135 scoped_refptr<PrerenderResourceHandler> pre_handler_; |
146 MessageLoop loop_; | 136 MessageLoop loop_; |
147 BrowserThread ui_thread_; | 137 BrowserThread ui_thread_; |
148 BrowserThread io_thread_; | 138 BrowserThread io_thread_; |
149 GURL last_handled_url_; | 139 GURL last_handled_url_; |
150 GURL default_url_; | 140 GURL default_url_; |
151 std::vector<GURL> alias_urls_; | 141 std::vector<GURL> alias_urls_; |
152 }; | 142 }; |
153 | 143 |
154 namespace { | 144 namespace { |
155 | 145 |
156 TEST_F(PrerenderResourceHandlerTest, NoOp) { | 146 TEST_F(PrerenderResourceHandlerTest, NoOp) { |
157 } | 147 } |
158 | 148 |
159 // Tests that a valid HTML resource will correctly get diverted | 149 // Tests that a valid HTML resource will correctly get diverted |
160 // to the PrerenderManager. | 150 // to the PrerenderManager. |
161 TEST_F(PrerenderResourceHandlerTest, Prerender) { | 151 TEST_F(PrerenderResourceHandlerTest, Prerender) { |
162 StartPrerendering("text/html", | 152 StartPrerendering("text/html", |
163 "HTTP/1.1 200 OK\n" | 153 "HTTP/1.1 200 OK\n"); |
164 "cache-control: max-age=86400\n"); | |
165 EXPECT_EQ(default_url_, last_handled_url_); | 154 EXPECT_EQ(default_url_, last_handled_url_); |
166 } | 155 } |
167 | 156 |
168 // Tests that a no-cache HTML resource will not get diverted | |
169 // to the PrerenderManager. | |
170 TEST_F(PrerenderResourceHandlerTest, PrerenderNoCache) { | |
171 StartPrerendering("text/html", | |
172 "HTTP/1.1 200 OK\n" | |
173 "cache-control: no-cache\n"); | |
174 EXPECT_TRUE(last_handled_url_.is_empty()); | |
175 } | |
176 | |
177 // Tests that a cacheable HTML resource which needs to be revalidated | |
178 // shortly will not be prerendered. | |
179 TEST_F(PrerenderResourceHandlerTest, PrerenderShortMaxAge) { | |
180 StartPrerendering("text/html", | |
181 "HTTP/1.1 200 OK\n" | |
182 "cache-control: max-age=5\n"); | |
183 EXPECT_TRUE(last_handled_url_.is_empty()); | |
184 } | |
185 | |
186 // Tests that a resource with the wrong MIME type (a GIF in this example) | |
187 // will not be diverted to the PrerenderManager. | |
188 TEST_F(PrerenderResourceHandlerTest, PrerenderWrongMimeType) { | |
189 StartPrerendering("image/gif", | |
190 "HTTP/1.1 200 OK\n" | |
191 "cache-control: max-age=86400\n"); | |
192 EXPECT_TRUE(last_handled_url_.is_empty()); | |
193 } | |
194 | |
195 // Tests that a resource with a non-200 response will not be diverted | |
196 // to the PrerenderManager | |
197 TEST_F(PrerenderResourceHandlerTest, PrerenderBadResponseCode) { | |
198 StartPrerendering("text/html", | |
199 "HTTP/1.1 403 Forbidden\n" | |
200 "cache-control: max-age=86400\n"); | |
201 EXPECT_TRUE(last_handled_url_.is_empty()); | |
202 } | |
203 | |
204 // Tests that the final request in a redirect chain will | 157 // Tests that the final request in a redirect chain will |
205 // get diverted to the PrerenderManager. | 158 // get diverted to the PrerenderManager. |
206 TEST_F(PrerenderResourceHandlerTest, PrerenderRedirect) { | 159 TEST_F(PrerenderResourceHandlerTest, PrerenderRedirect) { |
207 int request_id = 1; | 160 int request_id = 1; |
208 GURL url_redirect("http://www.redirect.com"); | 161 GURL url_redirect("http://www.redirect.com"); |
209 bool defer = false; | 162 bool defer = false; |
210 EXPECT_TRUE(pre_handler_->OnWillStart(request_id, default_url_, &defer)); | 163 EXPECT_TRUE(pre_handler_->OnWillStart(request_id, default_url_, &defer)); |
211 EXPECT_FALSE(defer); | 164 EXPECT_FALSE(defer); |
212 EXPECT_TRUE(pre_handler_->OnRequestRedirected(request_id, | 165 EXPECT_TRUE(pre_handler_->OnRequestRedirected(request_id, |
213 url_redirect, | 166 url_redirect, |
214 NULL, | 167 NULL, |
215 &defer)); | 168 &defer)); |
216 EXPECT_FALSE(defer); | 169 EXPECT_FALSE(defer); |
217 scoped_refptr<ResourceResponse> response(new ResourceResponse); | 170 scoped_refptr<ResourceResponse> response(new ResourceResponse); |
218 response->response_head.mime_type = "text/html"; | 171 response->response_head.mime_type = "text/html"; |
219 response->response_head.request_time = FixedGetCurrentTime(); | |
220 response->response_head.response_time = FixedGetCurrentTime(); | |
221 response->response_head.headers = CreateResponseHeaders( | 172 response->response_head.headers = CreateResponseHeaders( |
222 "HTTP/1.1 200 OK\n" | 173 "HTTP/1.1 200 OK\n"); |
223 "cache-control: max-age=86400\n"); | |
224 EXPECT_TRUE(pre_handler_->OnResponseStarted(request_id, response)); | 174 EXPECT_TRUE(pre_handler_->OnResponseStarted(request_id, response)); |
225 EXPECT_TRUE(last_handled_url_.is_empty()); | 175 EXPECT_TRUE(last_handled_url_.is_empty()); |
226 loop_.RunAllPending(); | 176 loop_.RunAllPending(); |
227 EXPECT_EQ(url_redirect, last_handled_url_); | 177 EXPECT_EQ(url_redirect, last_handled_url_); |
228 EXPECT_EQ(true, ContainsAliasURL(url_redirect)); | 178 EXPECT_EQ(true, ContainsAliasURL(url_redirect)); |
229 EXPECT_EQ(true, ContainsAliasURL(default_url_)); | 179 EXPECT_EQ(true, ContainsAliasURL(default_url_)); |
230 EXPECT_EQ(2, static_cast<int>(alias_urls_.size())); | 180 EXPECT_EQ(2, static_cast<int>(alias_urls_.size())); |
231 } | 181 } |
232 | 182 |
233 } | 183 } |
OLD | NEW |