OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/message_loop_proxy.h" |
5 #include "base/thread.h" | 6 #include "base/thread.h" |
6 #include "base/time.h" | 7 #include "base/waitable_event.h" |
7 #include "base/timer.h" | |
8 #include "chrome/browser/chrome_thread.h" | 8 #include "chrome/browser/chrome_thread.h" |
9 #include "chrome/browser/net/url_fetcher.h" | 9 #include "chrome/browser/net/url_fetcher.h" |
10 #include "chrome/browser/net/url_fetcher_protect.h" | 10 #include "chrome/browser/net/url_fetcher_protect.h" |
11 #include "chrome/browser/net/url_request_context_getter.h" | 11 #include "chrome/browser/net/url_request_context_getter.h" |
12 #include "chrome/common/chrome_plugin_lib.h" | 12 #include "chrome/common/chrome_plugin_lib.h" |
13 #include "net/http/http_response_headers.h" | 13 #include "net/http/http_response_headers.h" |
14 #include "net/socket/ssl_test_util.h" | 14 #include "net/socket/ssl_test_util.h" |
15 #include "net/url_request/url_request_unittest.h" | 15 #include "net/url_request/url_request_unittest.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 | 17 |
18 using base::Time; | 18 using base::Time; |
19 using base::TimeDelta; | 19 using base::TimeDelta; |
20 | 20 |
21 // TODO(eroman): Add a regression test for http://crbug.com/40505. | 21 // TODO(eroman): Add a regression test for http://crbug.com/40505. |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 const wchar_t kDocRoot[] = L"chrome/test/data"; | 25 const wchar_t kDocRoot[] = L"chrome/test/data"; |
26 | 26 |
27 class TestURLRequestContextGetter : public URLRequestContextGetter { | 27 class TestURLRequestContextGetter : public URLRequestContextGetter { |
28 public: | 28 public: |
29 virtual URLRequestContext* GetURLRequestContext() { | 29 virtual URLRequestContext* GetURLRequestContext() { |
30 if (!context_) | 30 if (!context_) |
31 context_ = new TestURLRequestContext(); | 31 context_ = new TestURLRequestContext(); |
32 return context_; | 32 return context_; |
33 } | 33 } |
| 34 virtual scoped_refptr<MessageLoopProxy> GetIOMessageLoopProxy() { |
| 35 return ChromeThread::GetMessageLoopProxyForThread(ChromeThread::IO); |
| 36 } |
| 37 |
34 private: | 38 private: |
35 ~TestURLRequestContextGetter() {} | 39 ~TestURLRequestContextGetter() {} |
36 | 40 |
37 scoped_refptr<URLRequestContext> context_; | 41 scoped_refptr<URLRequestContext> context_; |
38 }; | 42 }; |
39 | 43 |
40 class URLFetcherTest : public testing::Test, public URLFetcher::Delegate { | 44 class URLFetcherTest : public testing::Test, public URLFetcher::Delegate { |
41 public: | 45 public: |
42 URLFetcherTest() | 46 URLFetcherTest() |
43 : io_thread_(ChromeThread::IO, &io_loop_), | 47 : io_thread_(ChromeThread::IO, &io_loop_), |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 virtual void CreateFetcher(const GURL& url); | 156 virtual void CreateFetcher(const GURL& url); |
153 // URLFetcher::Delegate | 157 // URLFetcher::Delegate |
154 virtual void OnURLFetchComplete(const URLFetcher* source, | 158 virtual void OnURLFetchComplete(const URLFetcher* source, |
155 const GURL& url, | 159 const GURL& url, |
156 const URLRequestStatus& status, | 160 const URLRequestStatus& status, |
157 int response_code, | 161 int response_code, |
158 const ResponseCookies& cookies, | 162 const ResponseCookies& cookies, |
159 const std::string& data); | 163 const std::string& data); |
160 | 164 |
161 void CancelRequest(); | 165 void CancelRequest(); |
162 | |
163 private: | |
164 base::OneShotTimer<URLFetcherCancelTest> timer_; | |
165 }; | 166 }; |
166 | 167 |
167 // Version of TestURLRequestContext that posts a Quit task to the IO | 168 // Version of TestURLRequestContext that posts a Quit task to the IO |
168 // thread once it is deleted. | 169 // thread once it is deleted. |
169 class CancelTestURLRequestContext : public TestURLRequestContext { | 170 class CancelTestURLRequestContext : public TestURLRequestContext { |
170 virtual ~CancelTestURLRequestContext() { | 171 virtual ~CancelTestURLRequestContext() { |
171 ChromeThread::PostTask( | 172 ChromeThread::PostTask( |
172 ChromeThread::IO, FROM_HERE, new MessageLoop::QuitTask()); | 173 ChromeThread::IO, FROM_HERE, new MessageLoop::QuitTask()); |
173 } | 174 } |
174 }; | 175 }; |
175 | 176 |
176 class CancelTestURLRequestContextGetter : public URLRequestContextGetter { | 177 class CancelTestURLRequestContextGetter : public URLRequestContextGetter { |
177 public: | 178 public: |
| 179 CancelTestURLRequestContextGetter() : context_created_(false, false) { |
| 180 } |
178 virtual URLRequestContext* GetURLRequestContext() { | 181 virtual URLRequestContext* GetURLRequestContext() { |
179 if (!context_) | 182 if (!context_) { |
180 context_ = new CancelTestURLRequestContext(); | 183 context_ = new CancelTestURLRequestContext(); |
| 184 context_created_.Signal(); |
| 185 } |
181 return context_; | 186 return context_; |
182 } | 187 } |
| 188 virtual scoped_refptr<MessageLoopProxy> GetIOMessageLoopProxy() { |
| 189 return ChromeThread::GetMessageLoopProxyForThread(ChromeThread::IO); |
| 190 } |
| 191 void WaitForContextCreation() { |
| 192 context_created_.Wait(); |
| 193 } |
183 | 194 |
184 private: | 195 private: |
185 ~CancelTestURLRequestContextGetter() {} | 196 ~CancelTestURLRequestContextGetter() {} |
186 | 197 |
| 198 base::WaitableEvent context_created_; |
187 scoped_refptr<URLRequestContext> context_; | 199 scoped_refptr<URLRequestContext> context_; |
188 }; | 200 }; |
189 | 201 |
190 // Wrapper that lets us call CreateFetcher() on a thread of our choice. We | 202 // Wrapper that lets us call CreateFetcher() on a thread of our choice. We |
191 // could make URLFetcherTest refcounted and use PostTask(FROM_HERE.. ) to call | 203 // could make URLFetcherTest refcounted and use PostTask(FROM_HERE.. ) to call |
192 // CreateFetcher() directly, but the ownership of the URLFetcherTest is a bit | 204 // CreateFetcher() directly, but the ownership of the URLFetcherTest is a bit |
193 // confusing in that case because GTest doesn't know about the refcounting. | 205 // confusing in that case because GTest doesn't know about the refcounting. |
194 // It's less confusing to just do it this way. | 206 // It's less confusing to just do it this way. |
195 class FetcherWrapperTask : public Task { | 207 class FetcherWrapperTask : public Task { |
196 public: | 208 public: |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 EXPECT_TRUE(data.empty()); | 379 EXPECT_TRUE(data.empty()); |
368 | 380 |
369 // The rest is the same as URLFetcherTest::OnURLFetchComplete. | 381 // The rest is the same as URLFetcherTest::OnURLFetchComplete. |
370 delete fetcher_; | 382 delete fetcher_; |
371 ChromeThread::PostTask( | 383 ChromeThread::PostTask( |
372 ChromeThread::IO, FROM_HERE, new MessageLoop::QuitTask()); | 384 ChromeThread::IO, FROM_HERE, new MessageLoop::QuitTask()); |
373 } | 385 } |
374 | 386 |
375 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { | 387 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { |
376 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | 388 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); |
377 // We need to force the creation of the URLRequestContext, since we | 389 CancelTestURLRequestContextGetter* context_getter = |
378 // rely on it being destroyed as a signal to end the test. | 390 new CancelTestURLRequestContextGetter; |
379 URLRequestContextGetter* context_getter = | |
380 new CancelTestURLRequestContextGetter(); | |
381 context_getter->GetURLRequestContext(); | |
382 fetcher_->set_request_context(context_getter); | 391 fetcher_->set_request_context(context_getter); |
383 fetcher_->Start(); | 392 fetcher_->Start(); |
384 // Make sure we give the IO thread a chance to run. | 393 // We need to wait for the creation of the URLRequestContext, since we |
385 timer_.Start(TimeDelta::FromMilliseconds(300), this, | 394 // rely on it being destroyed as a signal to end the test. |
386 &URLFetcherCancelTest::CancelRequest); | 395 context_getter->WaitForContextCreation(); |
| 396 CancelRequest(); |
387 } | 397 } |
388 | 398 |
389 void URLFetcherCancelTest::OnURLFetchComplete(const URLFetcher* source, | 399 void URLFetcherCancelTest::OnURLFetchComplete(const URLFetcher* source, |
390 const GURL& url, | 400 const GURL& url, |
391 const URLRequestStatus& status, | 401 const URLRequestStatus& status, |
392 int response_code, | 402 int response_code, |
393 const ResponseCookies& cookies, | 403 const ResponseCookies& cookies, |
394 const std::string& data) { | 404 const std::string& data) { |
395 // We should have cancelled the request before completion. | 405 // We should have cancelled the request before completion. |
396 ADD_FAILURE(); | 406 ADD_FAILURE(); |
397 delete fetcher_; | 407 delete fetcher_; |
398 ChromeThread::PostTask( | 408 ChromeThread::PostTask( |
399 ChromeThread::IO, FROM_HERE, new MessageLoop::QuitTask()); | 409 ChromeThread::IO, FROM_HERE, new MessageLoop::QuitTask()); |
400 } | 410 } |
401 | 411 |
402 void URLFetcherCancelTest::CancelRequest() { | 412 void URLFetcherCancelTest::CancelRequest() { |
403 delete fetcher_; | 413 delete fetcher_; |
404 timer_.Stop(); | |
405 // The URLFetcher's test context will post a Quit task once it is | 414 // The URLFetcher's test context will post a Quit task once it is |
406 // deleted. So if this test simply hangs, it means cancellation | 415 // deleted. So if this test simply hangs, it means cancellation |
407 // did not work. | 416 // did not work. |
408 } | 417 } |
409 | 418 |
410 TEST_F(URLFetcherTest, SameThreadsTest) { | 419 TEST_F(URLFetcherTest, SameThreadsTest) { |
411 // Create the fetcher on the main thread. Since IO will happen on the main | 420 // Create the fetcher on the main thread. Since IO will happen on the main |
412 // thread, this will test URLFetcher's ability to do everything on one | 421 // thread, this will test URLFetcher's ability to do everything on one |
413 // thread. | 422 // thread. |
414 scoped_refptr<HTTPTestServer> server = | 423 scoped_refptr<HTTPTestServer> server = |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 // time difference from now). | 590 // time difference from now). |
582 | 591 |
583 base::Thread t("URLFetcher test thread"); | 592 base::Thread t("URLFetcher test thread"); |
584 ASSERT_TRUE(t.Start()); | 593 ASSERT_TRUE(t.Start()); |
585 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); | 594 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); |
586 | 595 |
587 MessageLoop::current()->Run(); | 596 MessageLoop::current()->Run(); |
588 } | 597 } |
589 | 598 |
590 } // namespace. | 599 } // namespace. |
OLD | NEW |