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