network_connection_handler_unittest.cc revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
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
19namespace {
20
21const char* kSuccessResult = "success";
22
23void ConfigureCallback(const dbus::ObjectPath& result) {
24}
25
26void ConfigureErrorCallback(const std::string& error_name,
27                            const std::string& error_message) {
28}
29
30}  // namespace
31
32namespace chromeos {
33
34class 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(NULL /* cert_loader */,
56                                      network_state_handler_.get(),
57                                      network_configuration_handler_.get());
58  }
59
60  virtual void TearDown() OVERRIDE {
61    network_connection_handler_.reset();
62    network_configuration_handler_.reset();
63    network_state_handler_.reset();
64    LoginState::Shutdown();
65    DBusThreadManager::Shutdown();
66  }
67
68 protected:
69  bool Configure(const std::string& json_string) {
70    scoped_ptr<base::DictionaryValue> json_dict =
71        onc::ReadDictionaryFromJson(json_string);
72    if (!json_dict) {
73      LOG(ERROR) << "Error parsing json: " << json_string;
74      return false;
75    }
76    DBusThreadManager::Get()->GetShillManagerClient()->ConfigureService(
77        *json_dict,
78        base::Bind(&ConfigureCallback),
79        base::Bind(&ConfigureErrorCallback));
80    message_loop_.RunUntilIdle();
81    return true;
82  }
83
84  void Connect(const std::string& service_path) {
85    const bool ignore_error_state = false;
86    network_connection_handler_->ConnectToNetwork(
87        service_path,
88        base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
89                   base::Unretained(this)),
90        base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
91                   base::Unretained(this)),
92        ignore_error_state);
93    message_loop_.RunUntilIdle();
94  }
95
96  void Disconnect(const std::string& service_path) {
97    network_connection_handler_->DisconnectNetwork(
98        service_path,
99        base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
100                   base::Unretained(this)),
101        base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
102                   base::Unretained(this)));
103    message_loop_.RunUntilIdle();
104  }
105
106  void SuccessCallback() {
107    result_ = kSuccessResult;
108  }
109
110  void ErrorCallback(const std::string& error_name,
111                     scoped_ptr<base::DictionaryValue> error_data) {
112    result_ = error_name;
113  }
114
115  std::string GetResultAndReset() {
116    std::string result;
117    result.swap(result_);
118    return result;
119  }
120
121  std::string GetServiceStringProperty(const std::string& service_path,
122                                       const std::string& key) {
123    std::string result;
124    const base::DictionaryValue* properties =
125        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()->
126        GetServiceProperties(service_path);
127    if (properties)
128      properties->GetStringWithoutPathExpansion(key, &result);
129    return result;
130  }
131
132  scoped_ptr<NetworkStateHandler> network_state_handler_;
133  scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
134  scoped_ptr<NetworkConnectionHandler> network_connection_handler_;
135  base::MessageLoopForUI message_loop_;
136  std::string result_;
137
138 private:
139  DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerTest);
140};
141
142namespace {
143
144const char* kConfigConnectable =
145    "{ \"GUID\": \"wifi0\", \"Type\": \"wifi\", \"State\": \"idle\" }";
146const char* kConfigConnected =
147    "{ \"GUID\": \"wifi1\", \"Type\": \"wifi\", \"State\": \"online\" }";
148const char* kConfigConnecting =
149    "{ \"GUID\": \"wifi2\", \"Type\": \"wifi\", \"State\": \"association\" }";
150const char* kConfigRequiresPassphrase =
151    "{ \"GUID\": \"wifi3\", \"Type\": \"wifi\", "
152    "\"PassphraseRequired\": true }";
153const char* kConfigRequiresActivation =
154    "{ \"GUID\": \"cellular1\", \"Type\": \"cellular\","
155    "  \"Cellular.ActivationState\": \"not-activated\" }";
156
157}  // namespace
158
159TEST_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.
168TEST_F(NetworkConnectionHandlerTest, NetworkConnectionHandlerConnectFailure) {
169  Connect("no-network");
170  EXPECT_EQ(NetworkConnectionHandler::kErrorNotFound, GetResultAndReset());
171
172  EXPECT_TRUE(Configure(kConfigConnected));
173  Connect("wifi1");
174  EXPECT_EQ(NetworkConnectionHandler::kErrorConnected, GetResultAndReset());
175
176  EXPECT_TRUE(Configure(kConfigConnecting));
177  Connect("wifi2");
178  EXPECT_EQ(NetworkConnectionHandler::kErrorConnecting, GetResultAndReset());
179
180  EXPECT_TRUE(Configure(kConfigRequiresPassphrase));
181  Connect("wifi3");
182  EXPECT_EQ(NetworkConnectionHandler::kErrorPassphraseRequired,
183            GetResultAndReset());
184
185  EXPECT_TRUE(Configure(kConfigRequiresActivation));
186  Connect("cellular1");
187  EXPECT_EQ(NetworkConnectionHandler::kErrorActivationRequired,
188            GetResultAndReset());
189}
190
191namespace {
192
193const char* kConfigRequiresCertificate =
194    "{ \"GUID\": \"wifi4\", \"Type\": \"wifi\", \"Connectable\": false,"
195    "  \"Security\": \"802_1x\","
196    "  \"UIData\": \"{"
197    "    \\\"certificate_type\\\": \\\"pattern\\\","
198    "    \\\"certificate_pattern\\\": {"
199    "      \\\"Subject\\\": { \\\"CommonName\\\": \\\"Foo\\\" }"
200    "   } }\" }";
201
202}  // namespace
203
204// Handle certificates. TODO(stevenjb): Add certificate stubs to improve
205// test coverage.
206TEST_F(NetworkConnectionHandlerTest,
207       NetworkConnectionHandlerConnectCertificate) {
208  EXPECT_TRUE(Configure(kConfigRequiresCertificate));
209  Connect("wifi4");
210  EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired,
211            GetResultAndReset());
212}
213
214TEST_F(NetworkConnectionHandlerTest,
215       NetworkConnectionHandlerDisconnectSuccess) {
216  EXPECT_TRUE(Configure(kConfigConnected));
217  Disconnect("wifi1");
218  EXPECT_EQ(kSuccessResult, GetResultAndReset());
219}
220
221TEST_F(NetworkConnectionHandlerTest,
222       NetworkConnectionHandlerDisconnectFailure) {
223  Connect("no-network");
224  EXPECT_EQ(NetworkConnectionHandler::kErrorNotFound, GetResultAndReset());
225
226  EXPECT_TRUE(Configure(kConfigConnectable));
227  Disconnect("wifi0");
228  EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
229}
230
231}  // namespace chromeos
232