Home | History | Annotate | Download | only in network
      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 #include "chromeos/network/network_connection_handler.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "chromeos/dbus/dbus_thread_manager.h"
     11 #include "chromeos/dbus/shill_manager_client.h"
     12 #include "chromeos/dbus/shill_service_client.h"
     13 #include "chromeos/network/network_configuration_handler.h"
     14 #include "chromeos/network/network_state_handler.h"
     15 #include "chromeos/network/onc/onc_utils.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 #include "third_party/cros_system_api/dbus/service_constants.h"
     18 
     19 namespace {
     20 
     21 const char* kSuccessResult = "success";
     22 
     23 void ConfigureCallback(const dbus::ObjectPath& result) {
     24 }
     25 
     26 void ConfigureErrorCallback(const std::string& error_name,
     27                             const std::string& error_message) {
     28 }
     29 
     30 }  // namespace
     31 
     32 namespace chromeos {
     33 
     34 class NetworkConnectionHandlerTest : public testing::Test {
     35  public:
     36   NetworkConnectionHandlerTest() {
     37   }
     38   virtual ~NetworkConnectionHandlerTest() {
     39   }
     40 
     41   virtual void SetUp() OVERRIDE {
     42     // Initialize DBusThreadManager with a stub implementation.
     43     DBusThreadManager::InitializeWithStub();
     44     message_loop_.RunUntilIdle();
     45     DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
     46         ->ClearServices();
     47     message_loop_.RunUntilIdle();
     48     LoginState::Initialize();
     49     network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
     50     network_configuration_handler_.reset(
     51         NetworkConfigurationHandler::InitializeForTest(
     52             network_state_handler_.get()));
     53     network_connection_handler_.reset(new NetworkConnectionHandler);
     54     // TODO(stevenjb): Test integration with CertLoader using a stub or mock.
     55     network_connection_handler_->Init(network_state_handler_.get(),
     56                                       network_configuration_handler_.get());
     57   }
     58 
     59   virtual void TearDown() OVERRIDE {
     60     network_connection_handler_.reset();
     61     network_configuration_handler_.reset();
     62     network_state_handler_.reset();
     63     LoginState::Shutdown();
     64     DBusThreadManager::Shutdown();
     65   }
     66 
     67  protected:
     68   bool Configure(const std::string& json_string) {
     69     scoped_ptr<base::DictionaryValue> json_dict =
     70         onc::ReadDictionaryFromJson(json_string);
     71     if (!json_dict) {
     72       LOG(ERROR) << "Error parsing json: " << json_string;
     73       return false;
     74     }
     75     DBusThreadManager::Get()->GetShillManagerClient()->ConfigureService(
     76         *json_dict,
     77         base::Bind(&ConfigureCallback),
     78         base::Bind(&ConfigureErrorCallback));
     79     message_loop_.RunUntilIdle();
     80     return true;
     81   }
     82 
     83   void Connect(const std::string& service_path) {
     84     const bool check_error_state = true;
     85     network_connection_handler_->ConnectToNetwork(
     86         service_path,
     87         base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
     88                    base::Unretained(this)),
     89         base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
     90                    base::Unretained(this)),
     91         check_error_state);
     92     message_loop_.RunUntilIdle();
     93   }
     94 
     95   void Disconnect(const std::string& service_path) {
     96     network_connection_handler_->DisconnectNetwork(
     97         service_path,
     98         base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
     99                    base::Unretained(this)),
    100         base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
    101                    base::Unretained(this)));
    102     message_loop_.RunUntilIdle();
    103   }
    104 
    105   void SuccessCallback() {
    106     result_ = kSuccessResult;
    107   }
    108 
    109   void ErrorCallback(const std::string& error_name,
    110                      scoped_ptr<base::DictionaryValue> error_data) {
    111     result_ = error_name;
    112   }
    113 
    114   std::string GetResultAndReset() {
    115     std::string result;
    116     result.swap(result_);
    117     return result;
    118   }
    119 
    120   std::string GetServiceStringProperty(const std::string& service_path,
    121                                        const std::string& key) {
    122     std::string result;
    123     const base::DictionaryValue* properties =
    124         DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()->
    125         GetServiceProperties(service_path);
    126     if (properties)
    127       properties->GetStringWithoutPathExpansion(key, &result);
    128     return result;
    129   }
    130 
    131   scoped_ptr<NetworkStateHandler> network_state_handler_;
    132   scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
    133   scoped_ptr<NetworkConnectionHandler> network_connection_handler_;
    134   base::MessageLoopForUI message_loop_;
    135   std::string result_;
    136 
    137  private:
    138   DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerTest);
    139 };
    140 
    141 namespace {
    142 
    143 const char* kConfigConnectable =
    144     "{ \"GUID\": \"wifi0\", \"Type\": \"wifi\", \"State\": \"idle\", "
    145     "  \"Connectable\": true }";
    146 const char* kConfigConnected =
    147     "{ \"GUID\": \"wifi1\", \"Type\": \"wifi\", \"State\": \"online\" }";
    148 const char* kConfigConnecting =
    149     "{ \"GUID\": \"wifi2\", \"Type\": \"wifi\", \"State\": \"association\" }";
    150 const char* kConfigRequiresPassphrase =
    151     "{ \"GUID\": \"wifi3\", \"Type\": \"wifi\", "
    152     "  \"PassphraseRequired\": true }";
    153 const char* kConfigRequiresActivation =
    154     "{ \"GUID\": \"cellular1\", \"Type\": \"cellular\","
    155     "  \"Cellular.ActivationState\": \"not-activated\" }";
    156 
    157 }  // namespace
    158 
    159 TEST_F(NetworkConnectionHandlerTest, NetworkConnectionHandlerConnectSuccess) {
    160   EXPECT_TRUE(Configure(kConfigConnectable));
    161   Connect("wifi0");
    162   EXPECT_EQ(kSuccessResult, GetResultAndReset());
    163   EXPECT_EQ(flimflam::kStateOnline,
    164             GetServiceStringProperty("wifi0", flimflam::kStateProperty));
    165 }
    166 
    167 // Handles basic failure cases.
    168 TEST_F(NetworkConnectionHandlerTest, NetworkConnectionHandlerConnectFailure) {
    169   Connect("no-network");
    170   EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
    171             GetResultAndReset());
    172 
    173   EXPECT_TRUE(Configure(kConfigConnected));
    174   Connect("wifi1");
    175   EXPECT_EQ(NetworkConnectionHandler::kErrorConnected, GetResultAndReset());
    176 
    177   EXPECT_TRUE(Configure(kConfigConnecting));
    178   Connect("wifi2");
    179   EXPECT_EQ(NetworkConnectionHandler::kErrorConnecting, GetResultAndReset());
    180 
    181   EXPECT_TRUE(Configure(kConfigRequiresPassphrase));
    182   Connect("wifi3");
    183   EXPECT_EQ(NetworkConnectionHandler::kErrorPassphraseRequired,
    184             GetResultAndReset());
    185 
    186   EXPECT_TRUE(Configure(kConfigRequiresActivation));
    187   Connect("cellular1");
    188   EXPECT_EQ(NetworkConnectionHandler::kErrorActivationRequired,
    189             GetResultAndReset());
    190 }
    191 
    192 namespace {
    193 
    194 const char* kConfigRequiresCertificate =
    195     "{ \"GUID\": \"wifi4\", \"Type\": \"wifi\", \"Connectable\": false,"
    196     "  \"Security\": \"802_1x\","
    197     "  \"UIData\": \"{"
    198     "    \\\"certificate_type\\\": \\\"pattern\\\","
    199     "    \\\"certificate_pattern\\\": {"
    200     "      \\\"Subject\\\": { \\\"CommonName\\\": \\\"Foo\\\" }"
    201     "   } }\" }";
    202 
    203 }  // namespace
    204 
    205 // Handle certificates. TODO(stevenjb): Add certificate stubs to improve
    206 // test coverage.
    207 TEST_F(NetworkConnectionHandlerTest,
    208        NetworkConnectionHandlerConnectCertificate) {
    209   EXPECT_TRUE(Configure(kConfigRequiresCertificate));
    210   Connect("wifi4");
    211   EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired,
    212             GetResultAndReset());
    213 }
    214 
    215 TEST_F(NetworkConnectionHandlerTest,
    216        NetworkConnectionHandlerDisconnectSuccess) {
    217   EXPECT_TRUE(Configure(kConfigConnected));
    218   Disconnect("wifi1");
    219   EXPECT_EQ(kSuccessResult, GetResultAndReset());
    220 }
    221 
    222 TEST_F(NetworkConnectionHandlerTest,
    223        NetworkConnectionHandlerDisconnectFailure) {
    224   Connect("no-network");
    225   EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
    226             GetResultAndReset());
    227 
    228   EXPECT_TRUE(Configure(kConfigConnectable));
    229   Disconnect("wifi0");
    230   EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
    231 }
    232 
    233 }  // namespace chromeos
    234