Home | History | Annotate | Download | only in dbus
      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 // This test is relatively complicated. Here's the summary of what it does:
      6 //
      7 // - Set up mock D-Bus related objects to mock out D-Bus calls.
      8 // - Set up a mock proxy resolver to mock out the proxy resolution.
      9 // - Create ProxyResolutionServiceProvider by injecting the mocks
     10 // - Start the service provider.
     11 // - Request ProxyResolutionServiceProvider to resolve proxy for kSourceURL.
     12 // - ProxyResolutionServiceProvider will return the result as a signal.
     13 // - Confirm that we receive the signal and check the contents of the signal.
     14 
     15 #include "chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h"
     16 
     17 #include "base/bind.h"
     18 #include "chrome/browser/chromeos/dbus/service_provider_test_helper.h"
     19 #include "dbus/message.h"
     20 #include "dbus/mock_exported_object.h"
     21 #include "third_party/cros_system_api/dbus/service_constants.h"
     22 
     23 using ::testing::_;
     24 
     25 namespace chromeos {
     26 
     27 // We want to know about the proxy info for the URL.
     28 const char kSourceURL[] = "http://www.gmail.com/";
     29 
     30 // ProxyResolutionServiceProvider will return the proxy info as a D-Bus
     31 // signal, to the following signal interface and the signal name.
     32 const char kReturnSignalInterface[] = "org.chromium.TestInterface";
     33 const char kReturnSignalName[] = "TestSignal";
     34 
     35 // The returned proxy info.
     36 const char kReturnProxyInfo[] = "PROXY cache.example.com:12345";
     37 
     38 // The error message is empty if proxy resolution is successful.
     39 const char kReturnEmptyErrorMessage[] = "";
     40 
     41 // Mock for ProxyResolverInterface. We'll inject this to
     42 // ProxyResolutionServiceProvider to mock out the proxy resolution.
     43 class MockProxyResolver : public ProxyResolverInterface {
     44  public:
     45   MOCK_METHOD4(ResolveProxy,
     46                void(const std::string& source_url,
     47                     const std::string& signal_interface,
     48                     const std::string& signal_name,
     49                     scoped_refptr<dbus::ExportedObject> exported_object));
     50 };
     51 
     52 class ProxyResolutionServiceProviderTest : public testing::Test {
     53  public:
     54   ProxyResolutionServiceProviderTest()
     55       : signal_received_successfully_(false) {
     56   }
     57 
     58   virtual void SetUp() OVERRIDE {
     59     // Create a mock proxy resolver. Will be owned by
     60     // |proxy_resolution_service|.
     61     MockProxyResolver* mock_resolver = new MockProxyResolver;
     62     // |mock_resolver_|'s ResolveProxy() will use MockResolveProxy().
     63     EXPECT_CALL(*mock_resolver,
     64                 ResolveProxy(kSourceURL, kReturnSignalInterface,
     65                              kReturnSignalName, _))
     66         .WillOnce(Invoke(
     67             this,
     68             &ProxyResolutionServiceProviderTest::MockResolveProxy));
     69 
     70     // Create the proxy resolution service with the mock bus and the mock
     71     // resolver injected.
     72     service_provider_.reset(
     73         ProxyResolutionServiceProvider::CreateForTesting(mock_resolver));
     74 
     75     test_helper_.SetUp(kResolveNetworkProxy, service_provider_.get());
     76 
     77     // Connect to the signal that will be sent to kReturnSignalInterface and
     78     // kReturnSignalName. ResolveNetworkProxy() will send the result as a
     79     // signal. OnSignalReceived() will be called upon the delivery.
     80     test_helper_.SetUpReturnSignal(
     81         kReturnSignalInterface,
     82         kReturnSignalName,
     83         base::Bind(&ProxyResolutionServiceProviderTest::OnSignalReceived,
     84                    base::Unretained(this)),
     85         base::Bind(&ProxyResolutionServiceProviderTest::OnConnectedToSignal,
     86                    base::Unretained(this)));
     87   }
     88 
     89   virtual void TearDown() OVERRIDE {
     90     test_helper_.TearDown();
     91     service_provider_.reset();
     92   }
     93 
     94  protected:
     95   // Called when a signal is received.
     96   void OnSignalReceived(dbus::Signal* signal) {
     97     ASSERT_EQ(kReturnSignalInterface, signal->GetInterface());
     98     ASSERT_EQ(kReturnSignalName, signal->GetMember());
     99 
    100     std::string source_url;
    101     std::string proxy_info;
    102     std::string error_message;
    103 
    104     // The signal should contain three strings.
    105     dbus::MessageReader reader(signal);
    106     ASSERT_TRUE(reader.PopString(&source_url));
    107     ASSERT_TRUE(reader.PopString(&proxy_info));
    108     ASSERT_TRUE(reader.PopString(&error_message));
    109 
    110     // Check the signal contents.
    111     EXPECT_EQ(kSourceURL, source_url);
    112     EXPECT_EQ(kReturnProxyInfo, proxy_info);
    113     EXPECT_EQ(kReturnEmptyErrorMessage, error_message);
    114 
    115     // Mark that the signal is received successfully.
    116     signal_received_successfully_ = true;
    117   }
    118 
    119   // Called when connected to a signal.
    120   void OnConnectedToSignal(const std::string& signal_interface,
    121                            const std::string& signal_name,
    122                            bool success){
    123     ASSERT_EQ(kReturnSignalInterface, signal_interface);
    124     ASSERT_EQ(kReturnSignalName, signal_name);
    125 
    126     ASSERT_TRUE(success);
    127   }
    128 
    129   // Behaves as |mock_resolver_|'s ResolveProxy().
    130   void MockResolveProxy(const std::string& source_url,
    131                         const std::string& signal_interface,
    132                         const std::string& signal_name,
    133                         scoped_refptr<dbus::ExportedObject> exported_object) {
    134     if (source_url == kSourceURL) {
    135       dbus::Signal signal(signal_interface,
    136                           signal_name);
    137       dbus::MessageWriter writer(&signal);
    138       writer.AppendString(kSourceURL);
    139       writer.AppendString(kReturnProxyInfo);
    140       writer.AppendString(kReturnEmptyErrorMessage);
    141       // Send the signal back to the requested signal interface and the
    142       // signal name.
    143       exported_object->SendSignal(&signal);
    144       return;
    145     }
    146 
    147     LOG(ERROR) << "Unexpected source URL: " << source_url;
    148   }
    149 
    150   bool signal_received_successfully_;
    151   ServiceProviderTestHelper test_helper_;
    152   scoped_ptr<CrosDBusService::ServiceProviderInterface> service_provider_;
    153 };
    154 
    155 TEST_F(ProxyResolutionServiceProviderTest, ResolveProxy) {
    156   // The signal is not yet received.
    157   ASSERT_FALSE(signal_received_successfully_);
    158 
    159   // Create a method call to resolve proxy config for kSourceURL.
    160   dbus::MethodCall method_call(kLibCrosServiceInterface, kResolveNetworkProxy);
    161   dbus::MessageWriter writer(&method_call);
    162   writer.AppendString(kSourceURL);
    163   writer.AppendString(kReturnSignalInterface);
    164   writer.AppendString(kReturnSignalName);
    165 
    166   // Call the ResolveNetworkProxy method.
    167   scoped_ptr<dbus::Response> response(test_helper_.CallMethod(&method_call));
    168 
    169   // An empty response should be returned.
    170   ASSERT_TRUE(response.get());
    171   dbus::MessageReader reader(response.get());
    172   ASSERT_FALSE(reader.HasMoreData());
    173 
    174   // Confirm that the signal is received successfully.
    175   // The contents of the signal are checked in OnSignalReceived().
    176   ASSERT_TRUE(signal_received_successfully_);
    177 }
    178 
    179 }  // namespace chromeos
    180