1// Copyright 2013 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 "base/bind.h"
6#include "base/memory/scoped_ptr.h"
7#include "base/message_loop/message_loop.h"
8#include "base/values.h"
9#include "chromeos/dbus/dbus_thread_manager.h"
10#include "chromeos/dbus/fake_shill_device_client.h"
11#include "chromeos/dbus/fake_shill_manager_client.h"
12#include "chromeos/network/network_device_handler_impl.h"
13#include "chromeos/network/network_state_handler.h"
14#include "testing/gtest/include/gtest/gtest.h"
15#include "third_party/cros_system_api/dbus/service_constants.h"
16
17namespace chromeos {
18
19namespace {
20
21const char kDefaultCellularDevicePath[] = "stub_cellular_device";
22const char kUnknownCellularDevicePath[] = "unknown_cellular_device";
23const char kDefaultWifiDevicePath[] = "stub_wifi_device";
24const char kResultSuccess[] = "success";
25const char kDefaultPin[] = "1111";
26
27}  // namespace
28
29class NetworkDeviceHandlerTest : public testing::Test {
30 public:
31  NetworkDeviceHandlerTest() : fake_device_client_(NULL) {}
32  virtual ~NetworkDeviceHandlerTest() {}
33
34  virtual void SetUp() OVERRIDE {
35    fake_device_client_ = new FakeShillDeviceClient;
36    DBusThreadManager::GetSetterForTesting()->SetShillDeviceClient(
37        scoped_ptr<ShillDeviceClient>(fake_device_client_));
38
39    success_callback_ = base::Bind(&NetworkDeviceHandlerTest::SuccessCallback,
40                                   base::Unretained(this));
41    properties_success_callback_ =
42        base::Bind(&NetworkDeviceHandlerTest::PropertiesSuccessCallback,
43                   base::Unretained(this));
44    string_success_callback_ =
45        base::Bind(&NetworkDeviceHandlerTest::StringSuccessCallback,
46                   base::Unretained(this));
47    error_callback_ = base::Bind(&NetworkDeviceHandlerTest::ErrorCallback,
48                                 base::Unretained(this));
49
50    network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
51    NetworkDeviceHandlerImpl* device_handler = new NetworkDeviceHandlerImpl;
52    device_handler->Init(network_state_handler_.get());
53    network_device_handler_.reset(device_handler);
54
55    // Add devices after handlers have been initialized.
56    ShillDeviceClient::TestInterface* device_test =
57        fake_device_client_->GetTestInterface();
58    device_test->AddDevice(
59        kDefaultCellularDevicePath, shill::kTypeCellular, "cellular1");
60    device_test->AddDevice(kDefaultWifiDevicePath, shill::kTypeWifi, "wifi1");
61
62    base::ListValue test_ip_configs;
63    test_ip_configs.AppendString("ip_config1");
64    device_test->SetDeviceProperty(
65        kDefaultWifiDevicePath, shill::kIPConfigsProperty, test_ip_configs);
66
67    message_loop_.RunUntilIdle();
68  }
69
70  virtual void TearDown() OVERRIDE {
71    network_device_handler_.reset();
72    network_state_handler_.reset();
73    DBusThreadManager::Shutdown();
74  }
75
76  void ErrorCallback(const std::string& error_name,
77                     scoped_ptr<base::DictionaryValue> error_data) {
78    LOG(ERROR) << "ErrorCallback: " << error_name;
79    result_ = error_name;
80  }
81
82  void SuccessCallback() {
83    result_ = kResultSuccess;
84  }
85
86  void PropertiesSuccessCallback(const std::string& device_path,
87                                 const base::DictionaryValue& properties) {
88    result_ = kResultSuccess;
89    properties_.reset(properties.DeepCopy());
90  }
91
92  void StringSuccessCallback(const std::string& result) {
93    LOG(ERROR) << "StringSuccessCallback: " << result;
94    result_ = kResultSuccess;
95  }
96
97 protected:
98  std::string result_;
99
100  FakeShillDeviceClient* fake_device_client_;
101  scoped_ptr<NetworkDeviceHandler> network_device_handler_;
102  scoped_ptr<NetworkStateHandler> network_state_handler_;
103  base::MessageLoopForUI message_loop_;
104  base::Closure success_callback_;
105  network_handler::DictionaryResultCallback properties_success_callback_;
106  network_handler::StringResultCallback string_success_callback_;
107  network_handler::ErrorCallback error_callback_;
108  scoped_ptr<base::DictionaryValue> properties_;
109
110 private:
111  DISALLOW_COPY_AND_ASSIGN(NetworkDeviceHandlerTest);
112};
113
114TEST_F(NetworkDeviceHandlerTest, GetDeviceProperties) {
115  network_device_handler_->GetDeviceProperties(
116      kDefaultWifiDevicePath, properties_success_callback_, error_callback_);
117  message_loop_.RunUntilIdle();
118  EXPECT_EQ(kResultSuccess, result_);
119  std::string type;
120  properties_->GetString(shill::kTypeProperty, &type);
121  EXPECT_EQ(shill::kTypeWifi, type);
122}
123
124TEST_F(NetworkDeviceHandlerTest, SetDeviceProperty) {
125  // Set the shill::kScanIntervalProperty to true. The call
126  // should succeed and the value should be set.
127  network_device_handler_->SetDeviceProperty(kDefaultCellularDevicePath,
128                                             shill::kScanIntervalProperty,
129                                             base::FundamentalValue(1),
130                                             success_callback_,
131                                             error_callback_);
132  message_loop_.RunUntilIdle();
133  EXPECT_EQ(kResultSuccess, result_);
134
135  // GetDeviceProperties should return the value set by SetDeviceProperty.
136  network_device_handler_->GetDeviceProperties(kDefaultCellularDevicePath,
137                                               properties_success_callback_,
138                                               error_callback_);
139  message_loop_.RunUntilIdle();
140  EXPECT_EQ(kResultSuccess, result_);
141  int interval = 0;
142  EXPECT_TRUE(properties_->GetIntegerWithoutPathExpansion(
143      shill::kScanIntervalProperty, &interval));
144  EXPECT_EQ(1, interval);
145
146  // Repeat the same with value false.
147  network_device_handler_->SetDeviceProperty(kDefaultCellularDevicePath,
148                                             shill::kScanIntervalProperty,
149                                             base::FundamentalValue(2),
150                                             success_callback_,
151                                             error_callback_);
152  message_loop_.RunUntilIdle();
153  EXPECT_EQ(kResultSuccess, result_);
154
155  network_device_handler_->GetDeviceProperties(kDefaultCellularDevicePath,
156                                               properties_success_callback_,
157                                               error_callback_);
158  message_loop_.RunUntilIdle();
159  EXPECT_EQ(kResultSuccess, result_);
160  EXPECT_TRUE(properties_->GetIntegerWithoutPathExpansion(
161      shill::kScanIntervalProperty, &interval));
162  EXPECT_EQ(2, interval);
163
164  // Set property on an invalid path.
165  network_device_handler_->SetDeviceProperty(kUnknownCellularDevicePath,
166                                             shill::kScanIntervalProperty,
167                                             base::FundamentalValue(1),
168                                             success_callback_,
169                                             error_callback_);
170  message_loop_.RunUntilIdle();
171  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
172
173  // Setting a owner-protected device property through SetDeviceProperty must
174  // fail.
175  network_device_handler_->SetDeviceProperty(
176      kDefaultCellularDevicePath,
177      shill::kCellularAllowRoamingProperty,
178      base::FundamentalValue(true),
179      success_callback_,
180      error_callback_);
181  message_loop_.RunUntilIdle();
182  EXPECT_NE(kResultSuccess, result_);
183
184}
185
186TEST_F(NetworkDeviceHandlerTest, CellularAllowRoaming) {
187  // Start with disabled data roaming.
188  ShillDeviceClient::TestInterface* device_test =
189      fake_device_client_->GetTestInterface();
190  device_test->SetDeviceProperty(kDefaultCellularDevicePath,
191                                 shill::kCellularAllowRoamingProperty,
192                                 base::FundamentalValue(false));
193
194  network_device_handler_->SetCellularAllowRoaming(true);
195  message_loop_.RunUntilIdle();
196
197  // Roaming should be enabled now.
198  network_device_handler_->GetDeviceProperties(kDefaultCellularDevicePath,
199                                               properties_success_callback_,
200                                               error_callback_);
201  message_loop_.RunUntilIdle();
202  EXPECT_EQ(kResultSuccess, result_);
203  bool allow_roaming;
204  EXPECT_TRUE(properties_->GetBooleanWithoutPathExpansion(
205      shill::kCellularAllowRoamingProperty, &allow_roaming));
206  EXPECT_TRUE(allow_roaming);
207
208  network_device_handler_->SetCellularAllowRoaming(false);
209  message_loop_.RunUntilIdle();
210
211  // Roaming should be disable again.
212  network_device_handler_->GetDeviceProperties(kDefaultCellularDevicePath,
213                                               properties_success_callback_,
214                                               error_callback_);
215  message_loop_.RunUntilIdle();
216  EXPECT_EQ(kResultSuccess, result_);
217  EXPECT_TRUE(properties_->GetBooleanWithoutPathExpansion(
218      shill::kCellularAllowRoamingProperty, &allow_roaming));
219  EXPECT_FALSE(allow_roaming);
220}
221
222TEST_F(NetworkDeviceHandlerTest, SetWifiTDLSEnabled) {
223  // We add a wifi device by default, initial call should succeed.
224  network_device_handler_->SetWifiTDLSEnabled(
225      "fake_ip_address", true, string_success_callback_, error_callback_);
226  message_loop_.RunUntilIdle();
227  EXPECT_EQ(kResultSuccess, result_);
228}
229
230TEST_F(NetworkDeviceHandlerTest, SetWifiTDLSEnabledMissing) {
231  // Remove the wifi device. Call should fail with "device missing" error.
232  fake_device_client_->GetTestInterface()->RemoveDevice(kDefaultWifiDevicePath);
233  message_loop_.RunUntilIdle();
234  network_device_handler_->SetWifiTDLSEnabled(
235      "fake_ip_address", true, string_success_callback_, error_callback_);
236  message_loop_.RunUntilIdle();
237  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
238}
239
240TEST_F(NetworkDeviceHandlerTest, SetWifiTDLSEnabledBusy) {
241  // Set the busy count, call should succeed after repeat attempt.
242  fake_device_client_->set_tdls_busy_count(1);
243  network_device_handler_->SetWifiTDLSEnabled(
244      "fake_ip_address", true, string_success_callback_, error_callback_);
245  message_loop_.RunUntilIdle();
246  EXPECT_EQ(kResultSuccess, result_);
247
248  // Set the busy count to a large number, call should fail after max number
249  // of repeat attempt.
250  fake_device_client_->set_tdls_busy_count(100000);
251  network_device_handler_->SetWifiTDLSEnabled(
252      "fake_ip_address", true, string_success_callback_, error_callback_);
253  message_loop_.RunUntilIdle();
254  EXPECT_EQ(NetworkDeviceHandler::kErrorTimeout, result_);
255}
256
257TEST_F(NetworkDeviceHandlerTest, GetWifiTDLSStatus) {
258  // We add a wifi device by default, initial call should succeed.
259  network_device_handler_->GetWifiTDLSStatus(
260      "fake_ip_address", string_success_callback_, error_callback_);
261  message_loop_.RunUntilIdle();
262  EXPECT_EQ(kResultSuccess, result_);
263
264  // Remove the wifi device. Call should fail with "device missing" error.
265  fake_device_client_->GetTestInterface()->RemoveDevice(kDefaultWifiDevicePath);
266  message_loop_.RunUntilIdle();
267  network_device_handler_->GetWifiTDLSStatus(
268      "fake_ip_address", string_success_callback_, error_callback_);
269  message_loop_.RunUntilIdle();
270  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
271}
272
273TEST_F(NetworkDeviceHandlerTest, RequestRefreshIPConfigs) {
274  network_device_handler_->RequestRefreshIPConfigs(
275      kDefaultWifiDevicePath, success_callback_, error_callback_);
276  message_loop_.RunUntilIdle();
277  EXPECT_EQ(kResultSuccess, result_);
278  // TODO(stevenjb): Add test interface to ShillIPConfigClient and test
279  // refresh calls.
280}
281
282TEST_F(NetworkDeviceHandlerTest, SetCarrier) {
283  const char kCarrier[] = "carrier";
284
285  // Test that the success callback gets called.
286  network_device_handler_->SetCarrier(
287      kDefaultCellularDevicePath, kCarrier, success_callback_, error_callback_);
288  message_loop_.RunUntilIdle();
289  EXPECT_EQ(kResultSuccess, result_);
290
291  // Test that the shill error propagates to the error callback.
292  network_device_handler_->SetCarrier(
293      kUnknownCellularDevicePath, kCarrier, success_callback_, error_callback_);
294  message_loop_.RunUntilIdle();
295  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
296}
297
298TEST_F(NetworkDeviceHandlerTest, RequirePin) {
299  // Test that the success callback gets called.
300  network_device_handler_->RequirePin(kDefaultCellularDevicePath,
301                                      true,
302                                      kDefaultPin,
303                                      success_callback_,
304                                      error_callback_);
305  message_loop_.RunUntilIdle();
306  EXPECT_EQ(kResultSuccess, result_);
307
308  // Test that the shill error propagates to the error callback.
309  network_device_handler_->RequirePin(kUnknownCellularDevicePath,
310                                      true,
311                                      kDefaultPin,
312                                      success_callback_,
313                                      error_callback_);
314  message_loop_.RunUntilIdle();
315  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
316}
317
318TEST_F(NetworkDeviceHandlerTest, EnterPin) {
319  // Test that the success callback gets called.
320  network_device_handler_->EnterPin(kDefaultCellularDevicePath,
321                                    kDefaultPin,
322                                    success_callback_,
323                                    error_callback_);
324  message_loop_.RunUntilIdle();
325  EXPECT_EQ(kResultSuccess, result_);
326
327  // Test that the shill error propagates to the error callback.
328  network_device_handler_->EnterPin(kUnknownCellularDevicePath,
329                                    kDefaultPin,
330                                    success_callback_,
331                                    error_callback_);
332  message_loop_.RunUntilIdle();
333  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
334}
335
336TEST_F(NetworkDeviceHandlerTest, UnblockPin) {
337  const char kPuk[] = "12345678";
338  const char kPin[] = "1234";
339
340  // Test that the success callback gets called.
341  network_device_handler_->UnblockPin(kDefaultCellularDevicePath,
342                                      kPin,
343                                      kPuk,
344                                      success_callback_,
345                                      error_callback_);
346  message_loop_.RunUntilIdle();
347  EXPECT_EQ(kResultSuccess, result_);
348
349  // Test that the shill error propagates to the error callback.
350  network_device_handler_->UnblockPin(kUnknownCellularDevicePath,
351                                      kPin,
352                                      kPuk,
353                                      success_callback_,
354                                      error_callback_);
355  message_loop_.RunUntilIdle();
356  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
357}
358
359TEST_F(NetworkDeviceHandlerTest, ChangePin) {
360  const char kOldPin[] = "4321";
361  const char kNewPin[] = "1234";
362
363  // Test that the success callback gets called.
364  network_device_handler_->ChangePin(kDefaultCellularDevicePath,
365                                     kOldPin,
366                                     kNewPin,
367                                     success_callback_,
368                                     error_callback_);
369  message_loop_.RunUntilIdle();
370  EXPECT_EQ(kResultSuccess, result_);
371
372  // Test that the shill error propagates to the error callback.
373  network_device_handler_->ChangePin(kUnknownCellularDevicePath,
374                                     kOldPin,
375                                     kNewPin,
376                                     success_callback_,
377                                     error_callback_);
378  message_loop_.RunUntilIdle();
379  EXPECT_EQ(NetworkDeviceHandler::kErrorDeviceMissing, result_);
380}
381
382}  // namespace chromeos
383