Home | History | Annotate | Download | only in network
      1 // Copyright 2014 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 #include "chromeos/network/host_resolver_impl_chromeos.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/run_loop.h"
     10 #include "base/strings/stringprintf.h"
     11 #include "chromeos/dbus/dbus_thread_manager.h"
     12 #include "chromeos/dbus/shill_device_client.h"
     13 #include "chromeos/dbus/shill_ipconfig_client.h"
     14 #include "chromeos/dbus/shill_service_client.h"
     15 #include "chromeos/network/device_state.h"
     16 #include "chromeos/network/network_state.h"
     17 #include "chromeos/network/network_state_handler.h"
     18 #include "dbus/object_path.h"
     19 #include "net/base/net_errors.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "third_party/cros_system_api/dbus/service_constants.h"
     22 
     23 namespace {
     24 
     25 const char kTestIPv4Address[] = "1.2.3.4";
     26 const char kTestIPv6Address[] = "1:2:3:4:5:6:7:8";
     27 
     28 void DoNothingWithCallStatus(chromeos::DBusMethodCallStatus call_status) {}
     29 void ErrorCallbackFunction(const std::string& error_name,
     30                            const std::string& error_message) {
     31   LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
     32 }
     33 void ResolveCompletionCallback(int result) {}
     34 
     35 }  // namespace
     36 
     37 class HostResolverImplChromeOSTest : public testing::Test {
     38  public:
     39   HostResolverImplChromeOSTest() {}
     40 
     41   virtual ~HostResolverImplChromeOSTest() {}
     42 
     43   virtual void SetUp() OVERRIDE {
     44     chromeos::DBusThreadManager::Initialize();
     45 
     46     network_state_handler_.reset(
     47         chromeos::NetworkStateHandler::InitializeForTest());
     48     base::RunLoop().RunUntilIdle();
     49 
     50     const chromeos::NetworkState* default_network =
     51         network_state_handler_->DefaultNetwork();
     52     ASSERT_TRUE(default_network);
     53     const chromeos::DeviceState* default_device =
     54         network_state_handler_->GetDeviceState(default_network->device_path());
     55     ASSERT_TRUE(default_device);
     56     SetDefaultIPConfigs(default_device->path());
     57 
     58     // Create the host resolver from the IO message loop.
     59     io_message_loop_.PostTask(
     60         FROM_HERE,
     61         base::Bind(&HostResolverImplChromeOSTest::InitializeHostResolver,
     62                    base::Unretained(this)));
     63     io_message_loop_.RunUntilIdle();
     64 
     65     // Run the main message loop to create the network observer and initialize
     66     // the ip address values.
     67     base::RunLoop().RunUntilIdle();
     68   }
     69 
     70   virtual void TearDown() OVERRIDE {
     71     network_state_handler_.reset();
     72     chromeos::DBusThreadManager::Shutdown();
     73   }
     74 
     75  protected:
     76   // Run from main (UI) message loop, calls Resolve on IO message loop.
     77   int CallResolve(net::HostResolver::RequestInfo& info) {
     78     io_message_loop_.PostTask(
     79         FROM_HERE,
     80         base::Bind(&HostResolverImplChromeOSTest::Resolve,
     81                    base::Unretained(this),
     82                    info));
     83     io_message_loop_.RunUntilIdle();
     84     return result_;
     85   }
     86 
     87   net::AddressList addresses_;
     88   int result_;
     89 
     90  private:
     91   // Run from IO message loop.
     92   void InitializeHostResolver() {
     93     net::HostResolver::Options options;
     94     host_resolver_ =
     95         chromeos::HostResolverImplChromeOS::CreateHostResolverForTest(
     96             base::MessageLoopProxy::current(),
     97             network_state_handler_.get());
     98   }
     99 
    100   // Run from IO message loop.
    101   void Resolve(net::HostResolver::RequestInfo info) {
    102     result_ = host_resolver_->Resolve(
    103         info,
    104         net::DEFAULT_PRIORITY,
    105         &addresses_,
    106         base::Bind(&ResolveCompletionCallback),
    107         NULL,
    108         net_log_);
    109   }
    110 
    111   void SetDefaultIPConfigs(const std::string& default_device_path) {
    112     const std::string kTestIPv4ConfigPath("test_ip_v4_config_path");
    113     const std::string kTestIPv6ConfigPath("test_ip_v6_config_path");
    114 
    115     SetIPConfig(kTestIPv4ConfigPath, shill::kTypeIPv4, kTestIPv4Address);
    116     SetIPConfig(kTestIPv6ConfigPath, shill::kTypeIPv6, kTestIPv6Address);
    117     base::RunLoop().RunUntilIdle();
    118 
    119     base::ListValue ip_configs;
    120     ip_configs.AppendString(kTestIPv4ConfigPath);
    121     ip_configs.AppendString(kTestIPv6ConfigPath);
    122 
    123     chromeos::DBusThreadManager::Get()->GetShillDeviceClient()->SetProperty(
    124         dbus::ObjectPath(default_device_path),
    125         shill::kIPConfigsProperty,
    126         ip_configs,
    127         base::Bind(&base::DoNothing),
    128         base::Bind(&ErrorCallbackFunction));
    129     base::RunLoop().RunUntilIdle();
    130   }
    131 
    132   void SetIPConfig(const std::string& path,
    133                    const std::string& method,
    134                    const std::string& address) {
    135     chromeos::DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
    136         dbus::ObjectPath(path),
    137         shill::kAddressProperty,
    138         base::StringValue(address),
    139         base::Bind(&DoNothingWithCallStatus));
    140     chromeos::DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
    141         dbus::ObjectPath(path),
    142         shill::kMethodProperty,
    143         base::StringValue(method),
    144         base::Bind(&DoNothingWithCallStatus));
    145   }
    146 
    147   scoped_ptr<chromeos::NetworkStateHandler> network_state_handler_;
    148   scoped_ptr<net::HostResolver> host_resolver_;
    149   base::MessageLoop io_message_loop_;
    150   net::BoundNetLog net_log_;
    151 
    152   DISALLOW_COPY_AND_ASSIGN(HostResolverImplChromeOSTest);
    153 };
    154 
    155 TEST_F(HostResolverImplChromeOSTest, Resolve) {
    156   net::HostResolver::RequestInfo info(
    157       net::HostPortPair(net::GetHostName(), 80));
    158   info.set_address_family(net::ADDRESS_FAMILY_IPV4);
    159   info.set_is_my_ip_address(true);
    160   EXPECT_EQ(net::OK, CallResolve(info));
    161   ASSERT_EQ(1u, addresses_.size());
    162   std::string expected = base::StringPrintf("%s:%d", kTestIPv4Address, 0);
    163   EXPECT_EQ(expected, addresses_[0].ToString());
    164 
    165   info.set_address_family(net::ADDRESS_FAMILY_IPV6);
    166   EXPECT_EQ(net::OK, CallResolve(info));
    167   ASSERT_EQ(2u, addresses_.size());
    168   expected = base::StringPrintf("[%s]:%d", kTestIPv6Address, 0);
    169   EXPECT_EQ(expected, addresses_[0].ToString());
    170   expected = base::StringPrintf("%s:%d", kTestIPv4Address, 0);
    171   EXPECT_EQ(expected, addresses_[1].ToString());
    172 }
    173