network_state_handler_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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_state_handler.h"
6
7#include <map>
8#include <set>
9#include <string>
10
11#include "base/bind.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/message_loop.h"
14#include "base/values.h"
15#include "chromeos/dbus/dbus_thread_manager.h"
16#include "chromeos/dbus/shill_device_client.h"
17#include "chromeos/dbus/shill_manager_client.h"
18#include "chromeos/dbus/shill_service_client.h"
19#include "chromeos/network/network_state.h"
20#include "chromeos/network/network_state_handler_observer.h"
21#include "dbus/object_path.h"
22#include "testing/gtest/include/gtest/gtest.h"
23#include "third_party/cros_system_api/dbus/service_constants.h"
24
25namespace {
26
27void ErrorCallbackFunction(const std::string& error_name,
28                           const std::string& error_message) {
29  LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
30}
31
32const std::string kShillManagerClientStubDefaultService = "stub_ethernet";
33const std::string kShillManagerClientStubDefaultWireless = "stub_wifi1";
34const std::string kShillManagerClientStubWireless2 = "stub_wifi2";
35const std::string kShillManagerClientStubCellular = "stub_cellular";
36
37using chromeos::NetworkState;
38using chromeos::NetworkStateHandler;
39
40class TestObserver : public chromeos::NetworkStateHandlerObserver {
41 public:
42  explicit TestObserver(NetworkStateHandler* handler)
43      : handler_(handler),
44        manager_changed_count_(0),
45        network_count_(0) {
46  }
47
48  virtual ~TestObserver() {
49  }
50
51  virtual void NetworkManagerChanged() OVERRIDE {
52    ++manager_changed_count_;
53  }
54
55  virtual void NetworkListChanged() OVERRIDE {
56    NetworkStateHandler::NetworkStateList networks;
57    handler_->GetNetworkList(&networks);
58    network_count_ = networks.size();
59    if (network_count_ == 0) {
60      default_network_ = "";
61      default_network_connection_state_ = "";
62    }
63  }
64
65  virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE {
66    default_network_ = network ? network->path() : "";
67    default_network_connection_state_ =
68        network ?  network->connection_state() : "";
69  }
70
71  virtual void NetworkConnectionStateChanged(
72      const NetworkState* network) OVERRIDE {
73    network_connection_state_[network->path()] = network->connection_state();
74    connection_state_changes_[network->path()]++;
75  }
76
77  virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE {
78    DCHECK(network);
79    property_updates_[network->path()]++;
80  }
81
82  size_t manager_changed_count() { return manager_changed_count_; }
83  size_t network_count() { return network_count_; }
84  std::string default_network() { return default_network_; }
85  std::string default_network_connection_state() {
86    return default_network_connection_state_;
87  }
88
89  int PropertyUpdatesForService(const std::string& service_path) {
90    return property_updates_[service_path];
91  }
92
93  int ConnectionStateChangesForService(const std::string& service_path) {
94    return connection_state_changes_[service_path];
95  }
96
97  std::string NetworkConnectionStateForService(
98      const std::string& service_path) {
99    return network_connection_state_[service_path];
100  }
101
102 private:
103  NetworkStateHandler* handler_;
104  size_t manager_changed_count_;
105  size_t network_count_;
106  std::string default_network_;
107  std::string default_network_connection_state_;
108  std::map<std::string, int> property_updates_;
109  std::map<std::string, int> connection_state_changes_;
110  std::map<std::string, std::string> network_connection_state_;
111
112  DISALLOW_COPY_AND_ASSIGN(TestObserver);
113};
114
115}  // namespace
116
117namespace chromeos {
118
119class NetworkStateHandlerTest : public testing::Test {
120 public:
121  NetworkStateHandlerTest() {}
122  virtual ~NetworkStateHandlerTest() {}
123
124  virtual void SetUp() OVERRIDE {
125    // Initialize DBusThreadManager with a stub implementation.
126    DBusThreadManager::InitializeWithStub();
127  }
128
129  virtual void TearDown() OVERRIDE {
130    network_state_handler_.reset();
131    test_observer_.reset();
132    DBusThreadManager::Shutdown();
133  }
134
135  void SetupNetworkStateHandler() {
136    SetupDefaultShillState();
137    network_state_handler_.reset(new NetworkStateHandler);
138    test_observer_.reset(new TestObserver(network_state_handler_.get()));
139    network_state_handler_->AddObserver(test_observer_.get());
140    network_state_handler_->InitShillPropertyHandler();
141  }
142
143 protected:
144  void SetupDefaultShillState() {
145    message_loop_.RunUntilIdle();  // Process any pending updates
146    ShillDeviceClient::TestInterface* device_test =
147        DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
148    device_test->ClearDevices();
149    device_test->AddDevice("/device/stub_wifi_device1",
150                           flimflam::kTypeWifi, "stub_wifi_device1");
151    device_test->AddDevice("/device/stub_cellular_device1",
152                           flimflam::kTypeCellular, "stub_cellular_device1");
153
154    ShillServiceClient::TestInterface* service_test =
155        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
156    service_test->ClearServices();
157    const bool add_to_watchlist = true;
158    service_test->AddService(kShillManagerClientStubDefaultService,
159                             kShillManagerClientStubDefaultService,
160                             flimflam::kTypeEthernet, flimflam::kStateOnline,
161                             add_to_watchlist);
162    service_test->AddService(kShillManagerClientStubDefaultWireless,
163                             kShillManagerClientStubDefaultWireless,
164                             flimflam::kTypeWifi, flimflam::kStateOnline,
165                             add_to_watchlist);
166    service_test->AddService(kShillManagerClientStubWireless2,
167                             kShillManagerClientStubWireless2,
168                             flimflam::kTypeWifi, flimflam::kStateIdle,
169                             add_to_watchlist);
170    service_test->AddService(kShillManagerClientStubCellular,
171                             kShillManagerClientStubCellular,
172                             flimflam::kTypeCellular, flimflam::kStateIdle,
173                             add_to_watchlist);
174  }
175
176  MessageLoopForUI message_loop_;
177  scoped_ptr<NetworkStateHandler> network_state_handler_;
178  scoped_ptr<TestObserver> test_observer_;
179
180 private:
181  DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest);
182};
183
184TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) {
185  SetupNetworkStateHandler();
186  message_loop_.RunUntilIdle();
187  EXPECT_EQ(1u, test_observer_->manager_changed_count());
188  // Ensure that the network list is the expected size.
189  const size_t kNumShillManagerClientStubImplServices = 4;
190  EXPECT_EQ(kNumShillManagerClientStubImplServices,
191            test_observer_->network_count());
192  // Ensure that the first stub network is the default network.
193  EXPECT_EQ(kShillManagerClientStubDefaultService,
194            test_observer_->default_network());
195  EXPECT_EQ(kShillManagerClientStubDefaultService,
196            network_state_handler_->ConnectedNetworkByType(
197                NetworkStateHandler::kMatchTypeDefault)->path());
198  EXPECT_EQ(kShillManagerClientStubDefaultService,
199            network_state_handler_->ConnectedNetworkByType(
200                flimflam::kTypeEthernet)->path());
201  EXPECT_EQ(kShillManagerClientStubDefaultWireless,
202            network_state_handler_->ConnectedNetworkByType(
203                NetworkStateHandler::kMatchTypeWireless)->path());
204  EXPECT_EQ(flimflam::kStateOnline,
205            test_observer_->default_network_connection_state());
206}
207
208TEST_F(NetworkStateHandlerTest, TechnologyChanged) {
209  SetupNetworkStateHandler();
210  message_loop_.RunUntilIdle();
211  EXPECT_EQ(1u, test_observer_->manager_changed_count());
212  // Enable a technology.
213  EXPECT_FALSE(network_state_handler_->TechnologyEnabled(flimflam::kTypeWimax));
214  network_state_handler_->SetTechnologyEnabled(
215      flimflam::kTypeWimax, true, network_handler::ErrorCallback());
216  message_loop_.RunUntilIdle();
217  // Ensure we get a manager changed callback when we change a property.
218  EXPECT_EQ(2u, test_observer_->manager_changed_count());
219  EXPECT_TRUE(network_state_handler_->TechnologyEnabled(flimflam::kTypeWimax));
220}
221
222TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) {
223  SetupNetworkStateHandler();
224  message_loop_.RunUntilIdle();
225  // Set a service property.
226  const std::string eth0 = "stub_ethernet";
227  EXPECT_EQ("", network_state_handler_->GetNetworkState(eth0)->security());
228  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth0));
229  base::StringValue security_value("TestSecurity");
230  DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
231      dbus::ObjectPath(eth0),
232      flimflam::kSecurityProperty, security_value,
233      base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
234  message_loop_.RunUntilIdle();
235  EXPECT_EQ("TestSecurity",
236            network_state_handler_->GetNetworkState(eth0)->security());
237  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth0));
238}
239
240TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) {
241  SetupNetworkStateHandler();
242  message_loop_.RunUntilIdle();
243  // Change a network state.
244  ShillServiceClient::TestInterface* service_test =
245      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
246  const std::string eth0 = "stub_ethernet";
247  base::StringValue connection_state_idle_value(flimflam::kStateIdle);
248  service_test->SetServiceProperty(eth0, flimflam::kStateProperty,
249                                   connection_state_idle_value);
250  message_loop_.RunUntilIdle();
251  EXPECT_EQ(flimflam::kStateIdle,
252            test_observer_->NetworkConnectionStateForService(eth0));
253  EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth0));
254  // Confirm that changing the connection state to the same value does *not*
255  // signal the observer.
256  service_test->SetServiceProperty(eth0, flimflam::kStateProperty,
257                                   connection_state_idle_value);
258  message_loop_.RunUntilIdle();
259  EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(eth0));
260}
261
262TEST_F(NetworkStateHandlerTest, DefaultServiceChanged) {
263  SetupNetworkStateHandler();
264  message_loop_.RunUntilIdle();
265
266  ShillManagerClient::TestInterface* manager_test =
267      DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
268  ASSERT_TRUE(manager_test);
269  ShillServiceClient::TestInterface* service_test =
270      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
271  ASSERT_TRUE(service_test);
272
273  // Change the default network by inserting wifi1 at the front of the list
274  // and changing the state of stub_ethernet to Idle.
275  const std::string wifi1 = "stub_wifi1";
276  manager_test->AddServiceAtIndex(wifi1, 0, true);
277  const std::string eth0 = "stub_ethernet";
278  base::StringValue connection_state_idle_value(flimflam::kStateIdle);
279  service_test->SetServiceProperty(eth0, flimflam::kStateProperty,
280                                   connection_state_idle_value);
281  message_loop_.RunUntilIdle();
282  EXPECT_EQ(wifi1, test_observer_->default_network());
283  EXPECT_EQ(flimflam::kStateOnline,
284            test_observer_->default_network_connection_state());
285}
286
287}  // namespace chromeos
288