| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "net/proxy/dhcp_proxy_script_adapter_fetcher_win.h" | 5 #include "net/proxy/dhcp_proxy_script_adapter_fetcher_win.h" |
| 6 | 6 |
| 7 #include "base/synchronization/waitable_event.h" | 7 #include "base/synchronization/waitable_event.h" |
| 8 #include "base/test/test_timeouts.h" | 8 #include "base/test/test_timeouts.h" |
| 9 #include "base/threading/sequenced_worker_pool.h" | 9 #include "base/threading/sequenced_worker_pool.h" |
| 10 #include "base/timer/elapsed_timer.h" | 10 #include "base/timer/elapsed_timer.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 const char* const kPacUrl = "http://pacserver/script.pac"; | 24 const char* const kPacUrl = "http://pacserver/script.pac"; |
| 25 | 25 |
| 26 // In net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc there are a few | 26 // In net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc there are a few |
| 27 // tests that exercise DhcpProxyScriptAdapterFetcher end-to-end along with | 27 // tests that exercise DhcpProxyScriptAdapterFetcher end-to-end along with |
| 28 // DhcpProxyScriptFetcherWin, i.e. it tests the end-to-end usage of Win32 | 28 // DhcpProxyScriptFetcherWin, i.e. it tests the end-to-end usage of Win32 |
| 29 // APIs and the network. In this file we test only by stubbing out | 29 // APIs and the network. In this file we test only by stubbing out |
| 30 // functionality. | 30 // functionality. |
| 31 | 31 |
| 32 // Version of DhcpProxyScriptAdapterFetcher that mocks out dependencies | 32 // Version of DhcpProxyScriptAdapterFetcher that mocks out dependencies |
| 33 // to allow unit testing. | 33 // to allow unit testing. |
| 34 class MockDhcpProxyScriptAdapterFetcher | 34 class MockDhcpProxyScriptAdapterFetcher : public DhcpProxyScriptAdapterFetcher { |
| 35 : public DhcpProxyScriptAdapterFetcher { | |
| 36 public: | 35 public: |
| 37 explicit MockDhcpProxyScriptAdapterFetcher( | 36 explicit MockDhcpProxyScriptAdapterFetcher( |
| 38 URLRequestContext* context, | 37 URLRequestContext* context, |
| 39 scoped_refptr<base::TaskRunner> task_runner) | 38 scoped_refptr<base::TaskRunner> task_runner) |
| 40 : DhcpProxyScriptAdapterFetcher(context, task_runner), | 39 : DhcpProxyScriptAdapterFetcher(context, task_runner), |
| 41 dhcp_delay_(base::TimeDelta::FromMilliseconds(1)), | 40 dhcp_delay_(base::TimeDelta::FromMilliseconds(1)), |
| 42 timeout_(TestTimeouts::action_timeout()), | 41 timeout_(TestTimeouts::action_timeout()), |
| 43 configured_url_(kPacUrl), | 42 configured_url_(kPacUrl), |
| 44 fetcher_delay_ms_(1), | 43 fetcher_delay_ms_(1), |
| 45 fetcher_result_(OK), | 44 fetcher_result_(OK), |
| 46 pac_script_("bingo") { | 45 pac_script_("bingo") {} |
| 47 } | |
| 48 | 46 |
| 49 void Cancel() { | 47 void Cancel() { |
| 50 DhcpProxyScriptAdapterFetcher::Cancel(); | 48 DhcpProxyScriptAdapterFetcher::Cancel(); |
| 51 fetcher_ = NULL; | 49 fetcher_ = NULL; |
| 52 } | 50 } |
| 53 | 51 |
| 54 virtual ProxyScriptFetcher* ImplCreateScriptFetcher() OVERRIDE { | 52 virtual ProxyScriptFetcher* ImplCreateScriptFetcher() OVERRIDE { |
| 55 // We don't maintain ownership of the fetcher, it is transferred to | 53 // We don't maintain ownership of the fetcher, it is transferred to |
| 56 // the caller. | 54 // the caller. |
| 57 fetcher_ = new MockProxyScriptFetcher(); | 55 fetcher_ = new MockProxyScriptFetcher(); |
| 58 if (fetcher_delay_ms_ != -1) { | 56 if (fetcher_delay_ms_ != -1) { |
| 59 fetcher_timer_.Start(FROM_HERE, | 57 fetcher_timer_.Start(FROM_HERE, |
| 60 base::TimeDelta::FromMilliseconds(fetcher_delay_ms_), | 58 base::TimeDelta::FromMilliseconds(fetcher_delay_ms_), |
| 61 this, &MockDhcpProxyScriptAdapterFetcher::OnFetcherTimer); | 59 this, |
| 60 &MockDhcpProxyScriptAdapterFetcher::OnFetcherTimer); |
| 62 } | 61 } |
| 63 return fetcher_; | 62 return fetcher_; |
| 64 } | 63 } |
| 65 | 64 |
| 66 class DelayingDhcpQuery : public DhcpQuery { | 65 class DelayingDhcpQuery : public DhcpQuery { |
| 67 public: | 66 public: |
| 68 explicit DelayingDhcpQuery() | 67 explicit DelayingDhcpQuery() |
| 69 : DhcpQuery(), | 68 : DhcpQuery(), test_finished_event_(true, false) {} |
| 70 test_finished_event_(true, false) { | |
| 71 } | |
| 72 | 69 |
| 73 std::string ImplGetPacURLFromDhcp( | 70 std::string ImplGetPacURLFromDhcp( |
| 74 const std::string& adapter_name) OVERRIDE { | 71 const std::string& adapter_name) OVERRIDE { |
| 75 base::ElapsedTimer timer; | 72 base::ElapsedTimer timer; |
| 76 test_finished_event_.TimedWait(dhcp_delay_); | 73 test_finished_event_.TimedWait(dhcp_delay_); |
| 77 return configured_url_; | 74 return configured_url_; |
| 78 } | 75 } |
| 79 | 76 |
| 80 base::WaitableEvent test_finished_event_; | 77 base::WaitableEvent test_finished_event_; |
| 81 base::TimeDelta dhcp_delay_; | 78 base::TimeDelta dhcp_delay_; |
| 82 std::string configured_url_; | 79 std::string configured_url_; |
| 83 }; | 80 }; |
| 84 | 81 |
| 85 virtual DhcpQuery* ImplCreateDhcpQuery() OVERRIDE { | 82 virtual DhcpQuery* ImplCreateDhcpQuery() OVERRIDE { |
| 86 dhcp_query_ = new DelayingDhcpQuery(); | 83 dhcp_query_ = new DelayingDhcpQuery(); |
| 87 dhcp_query_->dhcp_delay_ = dhcp_delay_; | 84 dhcp_query_->dhcp_delay_ = dhcp_delay_; |
| 88 dhcp_query_->configured_url_ = configured_url_; | 85 dhcp_query_->configured_url_ = configured_url_; |
| 89 return dhcp_query_; | 86 return dhcp_query_; |
| 90 } | 87 } |
| 91 | 88 |
| 92 // Use a shorter timeout so tests can finish more quickly. | 89 // Use a shorter timeout so tests can finish more quickly. |
| 93 virtual base::TimeDelta ImplGetTimeout() const OVERRIDE { | 90 virtual base::TimeDelta ImplGetTimeout() const OVERRIDE { return timeout_; } |
| 94 return timeout_; | |
| 95 } | |
| 96 | 91 |
| 97 void OnFetcherTimer() { | 92 void OnFetcherTimer() { |
| 98 // Note that there is an assumption by this mock implementation that | 93 // Note that there is an assumption by this mock implementation that |
| 99 // DhcpProxyScriptAdapterFetcher::Fetch will call ImplCreateScriptFetcher | 94 // DhcpProxyScriptAdapterFetcher::Fetch will call ImplCreateScriptFetcher |
| 100 // and call Fetch on the fetcher before the message loop is re-entered. | 95 // and call Fetch on the fetcher before the message loop is re-entered. |
| 101 // This holds true today, but if you hit this DCHECK the problem can | 96 // This holds true today, but if you hit this DCHECK the problem can |
| 102 // possibly be resolved by having a separate subclass of | 97 // possibly be resolved by having a separate subclass of |
| 103 // MockProxyScriptFetcher that adds the delay internally (instead of | 98 // MockProxyScriptFetcher that adds the delay internally (instead of |
| 104 // the simple approach currently used in ImplCreateScriptFetcher above). | 99 // the simple approach currently used in ImplCreateScriptFetcher above). |
| 105 DCHECK(fetcher_ && fetcher_->has_pending_request()); | 100 DCHECK(fetcher_ && fetcher_->has_pending_request()); |
| 106 fetcher_->NotifyFetchCompletion(fetcher_result_, pac_script_); | 101 fetcher_->NotifyFetchCompletion(fetcher_result_, pac_script_); |
| 107 fetcher_ = NULL; | 102 fetcher_ = NULL; |
| 108 } | 103 } |
| 109 | 104 |
| 110 bool IsWaitingForFetcher() const { | 105 bool IsWaitingForFetcher() const { return state() == STATE_WAIT_URL; } |
| 111 return state() == STATE_WAIT_URL; | |
| 112 } | |
| 113 | 106 |
| 114 bool WasCancelled() const { | 107 bool WasCancelled() const { return state() == STATE_CANCEL; } |
| 115 return state() == STATE_CANCEL; | |
| 116 } | |
| 117 | 108 |
| 118 void FinishTest() { | 109 void FinishTest() { |
| 119 DCHECK(dhcp_query_); | 110 DCHECK(dhcp_query_); |
| 120 dhcp_query_->test_finished_event_.Signal(); | 111 dhcp_query_->test_finished_event_.Signal(); |
| 121 } | 112 } |
| 122 | 113 |
| 123 base::TimeDelta dhcp_delay_; | 114 base::TimeDelta dhcp_delay_; |
| 124 base::TimeDelta timeout_; | 115 base::TimeDelta timeout_; |
| 125 std::string configured_url_; | 116 std::string configured_url_; |
| 126 int fetcher_delay_ms_; | 117 int fetcher_delay_ms_; |
| 127 int fetcher_result_; | 118 int fetcher_result_; |
| 128 std::string pac_script_; | 119 std::string pac_script_; |
| 129 MockProxyScriptFetcher* fetcher_; | 120 MockProxyScriptFetcher* fetcher_; |
| 130 base::OneShotTimer<MockDhcpProxyScriptAdapterFetcher> fetcher_timer_; | 121 base::OneShotTimer<MockDhcpProxyScriptAdapterFetcher> fetcher_timer_; |
| 131 scoped_refptr<DelayingDhcpQuery> dhcp_query_; | 122 scoped_refptr<DelayingDhcpQuery> dhcp_query_; |
| 132 }; | 123 }; |
| 133 | 124 |
| 134 class FetcherClient { | 125 class FetcherClient { |
| 135 public: | 126 public: |
| 136 FetcherClient() | 127 FetcherClient() |
| 137 : url_request_context_(new TestURLRequestContext()), | 128 : url_request_context_(new TestURLRequestContext()), |
| 138 worker_pool_( | 129 worker_pool_( |
| 139 new base::SequencedWorkerPool(4, "DhcpAdapterFetcherTest")), | 130 new base::SequencedWorkerPool(4, "DhcpAdapterFetcherTest")), |
| 140 fetcher_(new MockDhcpProxyScriptAdapterFetcher( | 131 fetcher_(new MockDhcpProxyScriptAdapterFetcher( |
| 141 url_request_context_.get(), | 132 url_request_context_.get(), |
| 142 worker_pool_->GetTaskRunnerWithShutdownBehavior( | 133 worker_pool_->GetTaskRunnerWithShutdownBehavior( |
| 143 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN))) { | 134 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN))) {} |
| 144 } | |
| 145 | 135 |
| 146 ~FetcherClient() { | 136 ~FetcherClient() { worker_pool_->Shutdown(); } |
| 147 worker_pool_->Shutdown(); | |
| 148 } | |
| 149 | 137 |
| 150 void WaitForResult(int expected_error) { | 138 void WaitForResult(int expected_error) { |
| 151 EXPECT_EQ(expected_error, callback_.WaitForResult()); | 139 EXPECT_EQ(expected_error, callback_.WaitForResult()); |
| 152 } | 140 } |
| 153 | 141 |
| 154 void RunTest() { | 142 void RunTest() { fetcher_->Fetch("adapter name", callback_.callback()); } |
| 155 fetcher_->Fetch("adapter name", callback_.callback()); | |
| 156 } | |
| 157 | 143 |
| 158 void FinishTestAllowCleanup() { | 144 void FinishTestAllowCleanup() { |
| 159 fetcher_->FinishTest(); | 145 fetcher_->FinishTest(); |
| 160 base::MessageLoop::current()->RunUntilIdle(); | 146 base::MessageLoop::current()->RunUntilIdle(); |
| 161 } | 147 } |
| 162 | 148 |
| 163 TestCompletionCallback callback_; | 149 TestCompletionCallback callback_; |
| 164 scoped_ptr<URLRequestContext> url_request_context_; | 150 scoped_ptr<URLRequestContext> url_request_context_; |
| 165 scoped_refptr<base::SequencedWorkerPool> worker_pool_; | 151 scoped_refptr<base::SequencedWorkerPool> worker_pool_; |
| 166 scoped_ptr<MockDhcpProxyScriptAdapterFetcher> fetcher_; | 152 scoped_ptr<MockDhcpProxyScriptAdapterFetcher> fetcher_; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 } | 247 } |
| 262 | 248 |
| 263 // Does a real fetch on a mock DHCP configuration. | 249 // Does a real fetch on a mock DHCP configuration. |
| 264 class MockDhcpRealFetchProxyScriptAdapterFetcher | 250 class MockDhcpRealFetchProxyScriptAdapterFetcher |
| 265 : public MockDhcpProxyScriptAdapterFetcher { | 251 : public MockDhcpProxyScriptAdapterFetcher { |
| 266 public: | 252 public: |
| 267 explicit MockDhcpRealFetchProxyScriptAdapterFetcher( | 253 explicit MockDhcpRealFetchProxyScriptAdapterFetcher( |
| 268 URLRequestContext* context, | 254 URLRequestContext* context, |
| 269 scoped_refptr<base::TaskRunner> task_runner) | 255 scoped_refptr<base::TaskRunner> task_runner) |
| 270 : MockDhcpProxyScriptAdapterFetcher(context, task_runner), | 256 : MockDhcpProxyScriptAdapterFetcher(context, task_runner), |
| 271 url_request_context_(context) { | 257 url_request_context_(context) {} |
| 272 } | |
| 273 | 258 |
| 274 // Returns a real proxy script fetcher. | 259 // Returns a real proxy script fetcher. |
| 275 ProxyScriptFetcher* ImplCreateScriptFetcher() OVERRIDE { | 260 ProxyScriptFetcher* ImplCreateScriptFetcher() OVERRIDE { |
| 276 ProxyScriptFetcher* fetcher = | 261 ProxyScriptFetcher* fetcher = |
| 277 new ProxyScriptFetcherImpl(url_request_context_); | 262 new ProxyScriptFetcherImpl(url_request_context_); |
| 278 return fetcher; | 263 return fetcher; |
| 279 } | 264 } |
| 280 | 265 |
| 281 URLRequestContext* url_request_context_; | 266 URLRequestContext* url_request_context_; |
| 282 }; | 267 }; |
| 283 | 268 |
| 284 TEST(DhcpProxyScriptAdapterFetcher, MockDhcpRealFetch) { | 269 TEST(DhcpProxyScriptAdapterFetcher, MockDhcpRealFetch) { |
| 285 SpawnedTestServer test_server( | 270 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, |
| 286 SpawnedTestServer::TYPE_HTTP, | 271 SpawnedTestServer::kLocalhost, |
| 287 SpawnedTestServer::kLocalhost, | 272 base::FilePath(FILE_PATH_LITERAL( |
| 288 base::FilePath( | 273 "net/data/proxy_script_fetcher_unittest"))); |
| 289 FILE_PATH_LITERAL("net/data/proxy_script_fetcher_unittest"))); | |
| 290 ASSERT_TRUE(test_server.Start()); | 274 ASSERT_TRUE(test_server.Start()); |
| 291 | 275 |
| 292 GURL configured_url = test_server.GetURL("files/downloadable.pac"); | 276 GURL configured_url = test_server.GetURL("files/downloadable.pac"); |
| 293 | 277 |
| 294 FetcherClient client; | 278 FetcherClient client; |
| 295 TestURLRequestContext url_request_context; | 279 TestURLRequestContext url_request_context; |
| 296 scoped_refptr<base::TaskRunner> runner = | 280 scoped_refptr<base::TaskRunner> runner = |
| 297 client.worker_pool_->GetTaskRunnerWithShutdownBehavior( | 281 client.worker_pool_->GetTaskRunnerWithShutdownBehavior( |
| 298 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); | 282 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); |
| 299 client.fetcher_.reset( | 283 client.fetcher_.reset(new MockDhcpRealFetchProxyScriptAdapterFetcher( |
| 300 new MockDhcpRealFetchProxyScriptAdapterFetcher( | 284 &url_request_context, runner)); |
| 301 &url_request_context, runner)); | |
| 302 client.fetcher_->configured_url_ = configured_url.spec(); | 285 client.fetcher_->configured_url_ = configured_url.spec(); |
| 303 client.RunTest(); | 286 client.RunTest(); |
| 304 client.WaitForResult(OK); | 287 client.WaitForResult(OK); |
| 305 ASSERT_TRUE(client.fetcher_->DidFinish()); | 288 ASSERT_TRUE(client.fetcher_->DidFinish()); |
| 306 EXPECT_EQ(OK, client.fetcher_->GetResult()); | 289 EXPECT_EQ(OK, client.fetcher_->GetResult()); |
| 307 EXPECT_EQ(base::string16(L"-downloadable.pac-\n"), | 290 EXPECT_EQ(base::string16(L"-downloadable.pac-\n"), |
| 308 client.fetcher_->GetPacScript()); | 291 client.fetcher_->GetPacScript()); |
| 309 EXPECT_EQ(configured_url, | 292 EXPECT_EQ(configured_url, client.fetcher_->GetPacURL()); |
| 310 client.fetcher_->GetPacURL()); | |
| 311 } | 293 } |
| 312 | 294 |
| 313 #define BASE_URL "http://corpserver/proxy.pac" | 295 #define BASE_URL "http://corpserver/proxy.pac" |
| 314 | 296 |
| 315 TEST(DhcpProxyScriptAdapterFetcher, SanitizeDhcpApiString) { | 297 TEST(DhcpProxyScriptAdapterFetcher, SanitizeDhcpApiString) { |
| 316 const size_t kBaseUrlLen = strlen(BASE_URL); | 298 const size_t kBaseUrlLen = strlen(BASE_URL); |
| 317 | 299 |
| 318 // Default case. | 300 // Default case. |
| 319 EXPECT_EQ(BASE_URL, | 301 EXPECT_EQ(BASE_URL, |
| 320 DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString( | 302 DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString(BASE_URL, |
| 321 BASE_URL, kBaseUrlLen)); | 303 kBaseUrlLen)); |
| 322 | 304 |
| 323 // Trailing \n and no null-termination. | 305 // Trailing \n and no null-termination. |
| 324 EXPECT_EQ(BASE_URL, | 306 EXPECT_EQ(BASE_URL, |
| 325 DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString( | 307 DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString( |
| 326 BASE_URL "\nblablabla", kBaseUrlLen + 1)); | 308 BASE_URL "\nblablabla", kBaseUrlLen + 1)); |
| 327 | 309 |
| 328 // Embedded NULLs. | 310 // Embedded NULLs. |
| 329 EXPECT_EQ(BASE_URL, | 311 EXPECT_EQ(BASE_URL, |
| 330 DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString( | 312 DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString( |
| 331 BASE_URL "\0foo\0blat", kBaseUrlLen + 9)); | 313 BASE_URL "\0foo\0blat", kBaseUrlLen + 9)); |
| 332 } | 314 } |
| 333 | 315 |
| 334 #undef BASE_URL | 316 #undef BASE_URL |
| 335 | 317 |
| 336 } // namespace | 318 } // namespace |
| 337 | 319 |
| 338 } // namespace net | 320 } // namespace net |
| OLD | NEW |