network_connection_handler_unittest.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
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(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
141namespace {
142
143const char* kConfigConnectable =
144    "{ \"GUID\": \"wifi0\", \"Type\": \"wifi\", \"State\": \"idle\", "
145    "  \"Connectable\": true }";
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