| 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 "chromeos/dbus/services/proxy_resolution_service_provider.h" | 5 #include "chromeos/dbus/services/proxy_resolution_service_provider.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "net/proxy/proxy_info.h" | 24 #include "net/proxy/proxy_info.h" |
| 25 #include "net/proxy/proxy_resolver.h" | 25 #include "net/proxy/proxy_resolver.h" |
| 26 #include "net/url_request/url_request_context.h" | 26 #include "net/url_request/url_request_context.h" |
| 27 #include "net/url_request/url_request_test_util.h" | 27 #include "net/url_request/url_request_test_util.h" |
| 28 #include "third_party/cros_system_api/dbus/service_constants.h" | 28 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 29 | 29 |
| 30 namespace chromeos { | 30 namespace chromeos { |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 // ProxyResolutionServiceProvider will return the proxy info as a D-Bus | |
| 35 // signal, to the following signal interface and the signal name. | |
| 36 const char kReturnSignalInterface[] = "org.chromium.TestInterface"; | |
| 37 const char kReturnSignalName[] = "TestSignal"; | |
| 38 | |
| 39 // Maximum time to wait for D-Bus signals to be received, in seconds. | |
| 40 int kSignalTimeoutSec = 60; | |
| 41 | |
| 42 // Runs pending, non-delayed tasks on |task_runner|. Note that delayed tasks or | 34 // Runs pending, non-delayed tasks on |task_runner|. Note that delayed tasks or |
| 43 // additional tasks posted by pending tests will not be run. | 35 // additional tasks posted by pending tests will not be run. |
| 44 void RunPendingTasks(scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | 36 void RunPendingTasks(scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| 45 scoped_refptr<base::ThreadTestHelper> helper = | 37 scoped_refptr<base::ThreadTestHelper> helper = |
| 46 new base::ThreadTestHelper(task_runner); | 38 new base::ThreadTestHelper(task_runner); |
| 47 ASSERT_TRUE(helper->Run()); | 39 ASSERT_TRUE(helper->Run()); |
| 48 } | 40 } |
| 49 | 41 |
| 50 // Trivial net::ProxyResolver implementation that returns canned data either | 42 // Trivial net::ProxyResolver implementation that returns canned data either |
| 51 // synchronously or asynchronously. | 43 // synchronously or asynchronously. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 } // namespace | 181 } // namespace |
| 190 | 182 |
| 191 class ProxyResolutionServiceProviderTest : public testing::Test { | 183 class ProxyResolutionServiceProviderTest : public testing::Test { |
| 192 public: | 184 public: |
| 193 ProxyResolutionServiceProviderTest() : network_thread_("NetworkThread") { | 185 ProxyResolutionServiceProviderTest() : network_thread_("NetworkThread") { |
| 194 CHECK(network_thread_.Start()); | 186 CHECK(network_thread_.Start()); |
| 195 | 187 |
| 196 proxy_resolver_ = | 188 proxy_resolver_ = |
| 197 base::MakeUnique<TestProxyResolver>(network_thread_.task_runner()); | 189 base::MakeUnique<TestProxyResolver>(network_thread_.task_runner()); |
| 198 service_provider_ = base::MakeUnique<ProxyResolutionServiceProvider>( | 190 service_provider_ = base::MakeUnique<ProxyResolutionServiceProvider>( |
| 199 kNetworkProxyServiceInterface, kNetworkProxyServiceResolveProxyMethod, | |
| 200 base::MakeUnique<TestDelegate>(network_thread_.task_runner(), | 191 base::MakeUnique<TestDelegate>(network_thread_.task_runner(), |
| 201 proxy_resolver_.get())); | 192 proxy_resolver_.get())); |
| 202 test_helper_.SetUp( | 193 test_helper_.SetUp( |
| 203 kNetworkProxyServiceName, dbus::ObjectPath(kNetworkProxyServicePath), | 194 kNetworkProxyServiceName, dbus::ObjectPath(kNetworkProxyServicePath), |
| 204 kNetworkProxyServiceInterface, kNetworkProxyServiceResolveProxyMethod, | 195 kNetworkProxyServiceInterface, kNetworkProxyServiceResolveProxyMethod, |
| 205 service_provider_.get()); | 196 service_provider_.get()); |
| 206 } | 197 } |
| 207 | 198 |
| 208 ~ProxyResolutionServiceProviderTest() override { | 199 ~ProxyResolutionServiceProviderTest() override { |
| 209 test_helper_.TearDown(); | 200 test_helper_.TearDown(); |
| 210 | 201 |
| 211 // URLRequestContextGetter posts a task to delete itself to its task runner, | 202 // URLRequestContextGetter posts a task to delete itself to its task runner, |
| 212 // so give it a chance to do that. | 203 // so give it a chance to do that. |
| 213 service_provider_.reset(); | 204 service_provider_.reset(); |
| 214 RunPendingTasks(network_thread_.task_runner()); | 205 RunPendingTasks(network_thread_.task_runner()); |
| 215 | 206 |
| 216 network_thread_.Stop(); | 207 network_thread_.Stop(); |
| 217 } | 208 } |
| 218 | 209 |
| 219 protected: | 210 protected: |
| 220 // Arguments extracted from a D-Bus signal. | 211 // Makes a D-Bus call to |service_provider_|'s ResolveProxy method and returns |
| 221 struct SignalInfo { | 212 // the response. |
| 222 std::string source_url; | 213 std::unique_ptr<dbus::Response> CallMethod(const std::string& source_url) { |
| 223 std::string proxy_info; | |
| 224 std::string error_message; | |
| 225 }; | |
| 226 | |
| 227 // Called when a signal is received. | |
| 228 void OnSignalReceived(dbus::Signal* signal) { | |
| 229 EXPECT_EQ(kReturnSignalInterface, signal->GetInterface()); | |
| 230 EXPECT_EQ(kReturnSignalName, signal->GetMember()); | |
| 231 | |
| 232 ASSERT_FALSE(signal_); | |
| 233 signal_ = base::MakeUnique<SignalInfo>(); | |
| 234 | |
| 235 // The signal should contain three strings. | |
| 236 dbus::MessageReader reader(signal); | |
| 237 EXPECT_TRUE(reader.PopString(&signal_->source_url)); | |
| 238 EXPECT_TRUE(reader.PopString(&signal_->proxy_info)); | |
| 239 EXPECT_TRUE(reader.PopString(&signal_->error_message)); | |
| 240 | |
| 241 // Stop the message loop. | |
| 242 ASSERT_FALSE(quit_closure_.is_null()) << "Unexpected D-Bus signal"; | |
| 243 quit_closure_.Run(); | |
| 244 quit_closure_.Reset(); | |
| 245 } | |
| 246 | |
| 247 // Called when connected to a signal. | |
| 248 void OnConnectedToSignal(const std::string& signal_interface, | |
| 249 const std::string& signal_name, | |
| 250 bool success){ | |
| 251 EXPECT_EQ(kReturnSignalInterface, signal_interface); | |
| 252 EXPECT_EQ(kReturnSignalName, signal_name); | |
| 253 EXPECT_TRUE(success); | |
| 254 } | |
| 255 | |
| 256 // Makes a D-Bus call to |service_provider_|'s ResolveProxy method. If | |
| 257 // |request_signal| is true, requests that the proxy information be returned | |
| 258 // via a signal; otherwise it should be included in the response. | |
| 259 // |response_out| is updated to hold the response, and |signal_out| is updated | |
| 260 // to hold information about the emitted signal, if any. | |
| 261 void CallMethod(const std::string& source_url, | |
| 262 bool request_signal, | |
| 263 std::unique_ptr<dbus::Response>* response_out, | |
| 264 std::unique_ptr<SignalInfo>* signal_out) { | |
| 265 dbus::MethodCall method_call(kNetworkProxyServiceInterface, | 214 dbus::MethodCall method_call(kNetworkProxyServiceInterface, |
| 266 kNetworkProxyServiceResolveProxyMethod); | 215 kNetworkProxyServiceResolveProxyMethod); |
| 267 dbus::MessageWriter writer(&method_call); | 216 dbus::MessageWriter writer(&method_call); |
| 268 writer.AppendString(source_url); | 217 writer.AppendString(source_url); |
| 269 if (request_signal) { | 218 return test_helper_.CallMethod(&method_call); |
| 270 writer.AppendString(kReturnSignalInterface); | |
| 271 writer.AppendString(kReturnSignalName); | |
| 272 | |
| 273 // Connect to the signal that will be sent to kReturnSignalInterface and | |
| 274 // kReturnSignalName. | |
| 275 test_helper_.SetUpReturnSignal( | |
| 276 kReturnSignalInterface, kReturnSignalName, | |
| 277 base::Bind(&ProxyResolutionServiceProviderTest::OnSignalReceived, | |
| 278 base::Unretained(this)), | |
| 279 base::Bind(&ProxyResolutionServiceProviderTest::OnConnectedToSignal, | |
| 280 base::Unretained(this))); | |
| 281 } | |
| 282 | |
| 283 *response_out = test_helper_.CallMethod(&method_call); | |
| 284 | |
| 285 // If a signal is being emitted, run the main message loop until it's | |
| 286 // received or we get tired of waiting. | |
| 287 if (request_signal) { | |
| 288 base::RunLoop run_loop; | |
| 289 quit_closure_ = run_loop.QuitClosure(); | |
| 290 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 291 FROM_HERE, quit_closure_, | |
| 292 base::TimeDelta::FromSeconds(kSignalTimeoutSec)); | |
| 293 run_loop.Run(); | |
| 294 } | |
| 295 | |
| 296 *signal_out = std::move(signal_); | |
| 297 } | 219 } |
| 298 | 220 |
| 299 // Thread used to perform network operations. | 221 // Thread used to perform network operations. |
| 300 base::Thread network_thread_; | 222 base::Thread network_thread_; |
| 301 | 223 |
| 302 // Information about the last D-Bus signal received by OnSignalReceived(). | |
| 303 std::unique_ptr<SignalInfo> signal_; | |
| 304 | |
| 305 // Closure used to stop the message loop after receiving a D-Bus signal. | |
| 306 base::Closure quit_closure_; | |
| 307 | |
| 308 std::unique_ptr<TestProxyResolver> proxy_resolver_; | 224 std::unique_ptr<TestProxyResolver> proxy_resolver_; |
| 309 std::unique_ptr<ProxyResolutionServiceProvider> service_provider_; | 225 std::unique_ptr<ProxyResolutionServiceProvider> service_provider_; |
| 310 ServiceProviderTestHelper test_helper_; | 226 ServiceProviderTestHelper test_helper_; |
| 311 | 227 |
| 312 DISALLOW_COPY_AND_ASSIGN(ProxyResolutionServiceProviderTest); | 228 DISALLOW_COPY_AND_ASSIGN(ProxyResolutionServiceProviderTest); |
| 313 }; | 229 }; |
| 314 | 230 |
| 315 // Tests that synchronously-resolved proxy information is returned via a signal. | 231 TEST_F(ProxyResolutionServiceProviderTest, Sync) { |
| 316 TEST_F(ProxyResolutionServiceProviderTest, SignalSync) { | |
| 317 const char kSourceURL[] = "http://www.gmail.com/"; | 232 const char kSourceURL[] = "http://www.gmail.com/"; |
| 318 | 233 std::unique_ptr<dbus::Response> response = CallMethod(kSourceURL); |
| 319 std::unique_ptr<dbus::Response> response; | |
| 320 std::unique_ptr<SignalInfo> signal; | |
| 321 CallMethod(kSourceURL, true /* request_signal */, &response, &signal); | |
| 322 | |
| 323 // An empty response should be returned. | |
| 324 ASSERT_TRUE(response); | |
| 325 EXPECT_FALSE(dbus::MessageReader(response.get()).HasMoreData()); | |
| 326 | |
| 327 // Confirm that the signal is received successfully. | |
| 328 ASSERT_TRUE(signal); | |
| 329 EXPECT_EQ(kSourceURL, signal->source_url); | |
| 330 EXPECT_EQ(proxy_resolver_->proxy_info().ToPacString(), signal->proxy_info); | |
| 331 EXPECT_EQ("", signal->error_message); | |
| 332 } | |
| 333 | |
| 334 // Tests that asynchronously-resolved proxy information is returned via a | |
| 335 // signal. | |
| 336 TEST_F(ProxyResolutionServiceProviderTest, SignalAsync) { | |
| 337 const char kSourceURL[] = "http://www.gmail.com/"; | |
| 338 proxy_resolver_->set_async(true); | |
| 339 proxy_resolver_->mutable_proxy_info()->UseNamedProxy("http://localhost:8080"); | |
| 340 | |
| 341 std::unique_ptr<dbus::Response> response; | |
| 342 std::unique_ptr<SignalInfo> signal; | |
| 343 CallMethod(kSourceURL, true /* request_signal */, &response, &signal); | |
| 344 | |
| 345 // An empty response should be returned. | |
| 346 ASSERT_TRUE(response); | |
| 347 EXPECT_FALSE(dbus::MessageReader(response.get()).HasMoreData()); | |
| 348 | |
| 349 // Confirm that the signal is received successfully. | |
| 350 ASSERT_TRUE(signal); | |
| 351 EXPECT_EQ(kSourceURL, signal->source_url); | |
| 352 EXPECT_EQ(proxy_resolver_->proxy_info().ToPacString(), signal->proxy_info); | |
| 353 EXPECT_EQ("", signal->error_message); | |
| 354 } | |
| 355 | |
| 356 TEST_F(ProxyResolutionServiceProviderTest, ResponseSync) { | |
| 357 const char kSourceURL[] = "http://www.gmail.com/"; | |
| 358 std::unique_ptr<dbus::Response> response; | |
| 359 std::unique_ptr<SignalInfo> signal; | |
| 360 CallMethod(kSourceURL, false /* request_signal */, &response, &signal); | |
| 361 | 234 |
| 362 // The response should contain the proxy info and an empty error. | 235 // The response should contain the proxy info and an empty error. |
| 363 ASSERT_TRUE(response); | 236 ASSERT_TRUE(response); |
| 364 dbus::MessageReader reader(response.get()); | 237 dbus::MessageReader reader(response.get()); |
| 365 std::string proxy_info, error; | 238 std::string proxy_info, error; |
| 366 EXPECT_TRUE(reader.PopString(&proxy_info)); | 239 EXPECT_TRUE(reader.PopString(&proxy_info)); |
| 367 EXPECT_TRUE(reader.PopString(&error)); | 240 EXPECT_TRUE(reader.PopString(&error)); |
| 368 EXPECT_EQ(proxy_resolver_->proxy_info().ToPacString(), proxy_info); | 241 EXPECT_EQ(proxy_resolver_->proxy_info().ToPacString(), proxy_info); |
| 369 EXPECT_EQ("", error); | 242 EXPECT_EQ("", error); |
| 370 | |
| 371 // No signal should've been emitted. | |
| 372 EXPECT_FALSE(signal); | |
| 373 } | 243 } |
| 374 | 244 |
| 375 TEST_F(ProxyResolutionServiceProviderTest, ResponseAsync) { | 245 TEST_F(ProxyResolutionServiceProviderTest, Async) { |
| 376 const char kSourceURL[] = "http://www.gmail.com/"; | 246 const char kSourceURL[] = "http://www.gmail.com/"; |
| 377 proxy_resolver_->set_async(true); | 247 proxy_resolver_->set_async(true); |
| 378 proxy_resolver_->mutable_proxy_info()->UseNamedProxy("http://localhost:8080"); | 248 proxy_resolver_->mutable_proxy_info()->UseNamedProxy("http://localhost:8080"); |
| 379 std::unique_ptr<dbus::Response> response; | 249 std::unique_ptr<dbus::Response> response = CallMethod(kSourceURL); |
| 380 std::unique_ptr<SignalInfo> signal; | |
| 381 CallMethod(kSourceURL, false /* request_signal */, &response, &signal); | |
| 382 | 250 |
| 383 // The response should contain the proxy info and an empty error. | 251 // The response should contain the proxy info and an empty error. |
| 384 ASSERT_TRUE(response); | 252 ASSERT_TRUE(response); |
| 385 dbus::MessageReader reader(response.get()); | 253 dbus::MessageReader reader(response.get()); |
| 386 std::string proxy_info, error; | 254 std::string proxy_info, error; |
| 387 EXPECT_TRUE(reader.PopString(&proxy_info)); | 255 EXPECT_TRUE(reader.PopString(&proxy_info)); |
| 388 EXPECT_TRUE(reader.PopString(&error)); | 256 EXPECT_TRUE(reader.PopString(&error)); |
| 389 EXPECT_EQ(proxy_resolver_->proxy_info().ToPacString(), proxy_info); | 257 EXPECT_EQ(proxy_resolver_->proxy_info().ToPacString(), proxy_info); |
| 390 EXPECT_EQ("", error); | 258 EXPECT_EQ("", error); |
| 391 | |
| 392 // No signal should've been emitted. | |
| 393 EXPECT_FALSE(signal); | |
| 394 } | 259 } |
| 395 | 260 |
| 396 TEST_F(ProxyResolutionServiceProviderTest, ResponseError) { | 261 TEST_F(ProxyResolutionServiceProviderTest, Error) { |
| 397 const char kSourceURL[] = "http://www.gmail.com/"; | 262 const char kSourceURL[] = "http://www.gmail.com/"; |
| 398 proxy_resolver_->set_result(net::ERR_FAILED); | 263 proxy_resolver_->set_result(net::ERR_FAILED); |
| 399 std::unique_ptr<dbus::Response> response; | 264 std::unique_ptr<dbus::Response> response = CallMethod(kSourceURL); |
| 400 std::unique_ptr<SignalInfo> signal; | |
| 401 CallMethod(kSourceURL, false /* request_signal */, &response, &signal); | |
| 402 | 265 |
| 403 // The response should contain empty proxy info and a "mandatory proxy config | 266 // The response should contain empty proxy info and a "mandatory proxy config |
| 404 // failed" error (which the error from the resolver will be mapped to). | 267 // failed" error (which the error from the resolver will be mapped to). |
| 405 ASSERT_TRUE(response); | 268 ASSERT_TRUE(response); |
| 406 dbus::MessageReader reader(response.get()); | 269 dbus::MessageReader reader(response.get()); |
| 407 std::string proxy_info, error; | 270 std::string proxy_info, error; |
| 408 EXPECT_TRUE(reader.PopString(&proxy_info)); | 271 EXPECT_TRUE(reader.PopString(&proxy_info)); |
| 409 EXPECT_TRUE(reader.PopString(&error)); | 272 EXPECT_TRUE(reader.PopString(&error)); |
| 410 EXPECT_EQ("DIRECT", proxy_info); | 273 EXPECT_EQ("DIRECT", proxy_info); |
| 411 EXPECT_EQ(net::ErrorToString(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED), | 274 EXPECT_EQ(net::ErrorToString(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED), |
| 412 error); | 275 error); |
| 413 | |
| 414 // No signal should've been emitted. | |
| 415 EXPECT_FALSE(signal); | |
| 416 } | 276 } |
| 417 | 277 |
| 418 } // namespace chromeos | 278 } // namespace chromeos |
| OLD | NEW |