Add default implementations for AppWindowRegistry::Observer notifications.
[chromium-blink-merge.git] / chromeos / network / shill_property_handler_unittest.cc
bloba6b7b8e1e46cd25fddd10d0ded8c2b94aad8c58e
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.
5 #include "chromeos/network/shill_property_handler.h"
7 #include <map>
8 #include <set>
9 #include <string>
11 #include "base/bind.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/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_ipconfig_client.h"
18 #include "chromeos/dbus/shill_manager_client.h"
19 #include "chromeos/dbus/shill_profile_client.h"
20 #include "chromeos/dbus/shill_service_client.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"
25 namespace chromeos {
27 namespace {
29 void DoNothingWithCallStatus(DBusMethodCallStatus call_status) {
32 void ErrorCallbackFunction(const std::string& error_name,
33 const std::string& error_message) {
34 LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
37 class TestListener : public internal::ShillPropertyHandler::Listener {
38 public:
39 TestListener() : technology_list_updates_(0),
40 errors_(0) {
43 virtual void UpdateManagedList(ManagedState::ManagedType type,
44 const base::ListValue& entries) OVERRIDE {
45 UpdateEntries(GetTypeString(type), entries);
48 virtual void UpdateManagedStateProperties(
49 ManagedState::ManagedType type,
50 const std::string& path,
51 const base::DictionaryValue& properties) OVERRIDE {
52 AddInitialPropertyUpdate(GetTypeString(type), path);
55 virtual void ProfileListChanged() OVERRIDE {
58 virtual void UpdateNetworkServiceProperty(
59 const std::string& service_path,
60 const std::string& key,
61 const base::Value& value) OVERRIDE {
62 AddPropertyUpdate(shill::kServicesProperty, service_path);
65 virtual void UpdateDeviceProperty(
66 const std::string& device_path,
67 const std::string& key,
68 const base::Value& value) OVERRIDE {
69 AddPropertyUpdate(shill::kDevicesProperty, device_path);
72 virtual void TechnologyListChanged() OVERRIDE {
73 ++technology_list_updates_;
76 virtual void CheckPortalListChanged(
77 const std::string& check_portal_list) OVERRIDE {
80 virtual void ManagedStateListChanged(
81 ManagedState::ManagedType type) OVERRIDE {
82 AddStateListUpdate(GetTypeString(type));
85 virtual void DefaultNetworkServiceChanged(
86 const std::string& service_path) OVERRIDE {
89 std::vector<std::string>& entries(const std::string& type) {
90 return entries_[type];
92 std::map<std::string, int>& property_updates(const std::string& type) {
93 return property_updates_[type];
95 std::map<std::string, int>& initial_property_updates(
96 const std::string& type) {
97 return initial_property_updates_[type];
99 int list_updates(const std::string& type) { return list_updates_[type]; }
100 void reset_list_updates() { list_updates_.clear(); }
101 int technology_list_updates() { return technology_list_updates_; }
102 int errors() { return errors_; }
104 private:
105 std::string GetTypeString(ManagedState::ManagedType type) {
106 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
107 return shill::kServicesProperty;
108 } else if (type == ManagedState::MANAGED_TYPE_FAVORITE) {
109 return shill::kServiceCompleteListProperty;
110 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
111 return shill::kDevicesProperty;
113 LOG(ERROR) << "UpdateManagedList called with unrecognized type: " << type;
114 ++errors_;
115 return std::string();
118 void UpdateEntries(const std::string& type, const base::ListValue& entries) {
119 if (type.empty())
120 return;
121 entries_[type].clear();
122 for (base::ListValue::const_iterator iter = entries.begin();
123 iter != entries.end(); ++iter) {
124 std::string path;
125 if ((*iter)->GetAsString(&path))
126 entries_[type].push_back(path);
130 void AddPropertyUpdate(const std::string& type, const std::string& path) {
131 if (type.empty())
132 return;
133 property_updates(type)[path] += 1;
136 void AddInitialPropertyUpdate(const std::string& type,
137 const std::string& path) {
138 if (type.empty())
139 return;
140 initial_property_updates(type)[path] += 1;
143 void AddStateListUpdate(const std::string& type) {
144 if (type.empty())
145 return;
146 list_updates_[type] += 1;
149 // Map of list-type -> paths
150 std::map<std::string, std::vector<std::string> > entries_;
151 // Map of list-type -> map of paths -> update counts
152 std::map<std::string, std::map<std::string, int> > property_updates_;
153 std::map<std::string, std::map<std::string, int> > initial_property_updates_;
154 // Map of list-type -> list update counts
155 std::map<std::string, int > list_updates_;
156 int technology_list_updates_;
157 int errors_;
160 } // namespace
162 class ShillPropertyHandlerTest : public testing::Test {
163 public:
164 ShillPropertyHandlerTest()
165 : manager_test_(NULL),
166 device_test_(NULL),
167 service_test_(NULL),
168 profile_test_(NULL) {
170 virtual ~ShillPropertyHandlerTest() {
173 virtual void SetUp() OVERRIDE {
174 // Initialize DBusThreadManager with a stub implementation.
175 DBusThreadManager::InitializeWithStub();
176 // Get the test interface for manager / device / service and clear the
177 // default stub properties.
178 manager_test_ =
179 DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
180 ASSERT_TRUE(manager_test_);
181 device_test_ =
182 DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
183 ASSERT_TRUE(device_test_);
184 service_test_ =
185 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
186 ASSERT_TRUE(service_test_);
187 profile_test_ =
188 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
189 ASSERT_TRUE(profile_test_);
190 SetupShillPropertyHandler();
191 message_loop_.RunUntilIdle();
194 virtual void TearDown() OVERRIDE {
195 shill_property_handler_.reset();
196 listener_.reset();
197 DBusThreadManager::Shutdown();
200 void AddDevice(const std::string& type, const std::string& id) {
201 ASSERT_TRUE(IsValidType(type));
202 device_test_->AddDevice(id, type, std::string("/device/" + id));
205 void RemoveDevice(const std::string& id) {
206 device_test_->RemoveDevice(id);
209 void AddService(const std::string& type,
210 const std::string& id,
211 const std::string& state,
212 bool add_to_watch_list) {
213 ASSERT_TRUE(IsValidType(type));
214 service_test_->AddService(id, id, type, state,
215 true /* visible */, add_to_watch_list);
218 void AddServiceWithIPConfig(const std::string& type,
219 const std::string& id,
220 const std::string& state,
221 const std::string& ipconfig_path,
222 bool add_to_watch_list) {
223 ASSERT_TRUE(IsValidType(type));
224 service_test_->AddServiceWithIPConfig(id, id, type, state,
225 ipconfig_path,
226 true /* visible */,
227 add_to_watch_list);
230 void AddServiceToProfile(const std::string& type,
231 const std::string& id,
232 bool visible) {
233 service_test_->AddService(id, id, type, shill::kStateIdle,
234 visible, false /* watch */);
235 std::vector<std::string> profiles;
236 profile_test_->GetProfilePaths(&profiles);
237 ASSERT_TRUE(profiles.size() > 0);
238 base::DictionaryValue properties; // Empty entry
239 profile_test_->AddService(profiles[0], id);
242 void RemoveService(const std::string& id) {
243 service_test_->RemoveService(id);
246 // Call this after any initial Shill client setup
247 void SetupShillPropertyHandler() {
248 SetupDefaultShillState();
249 listener_.reset(new TestListener);
250 shill_property_handler_.reset(
251 new internal::ShillPropertyHandler(listener_.get()));
252 shill_property_handler_->Init();
255 bool IsValidType(const std::string& type) {
256 return (type == shill::kTypeEthernet ||
257 type == shill::kTypeEthernetEap ||
258 type == shill::kTypeWifi ||
259 type == shill::kTypeWimax ||
260 type == shill::kTypeBluetooth ||
261 type == shill::kTypeCellular ||
262 type == shill::kTypeVPN);
265 protected:
266 void SetupDefaultShillState() {
267 message_loop_.RunUntilIdle(); // Process any pending updates
268 device_test_->ClearDevices();
269 AddDevice(shill::kTypeWifi, "stub_wifi_device1");
270 AddDevice(shill::kTypeCellular, "stub_cellular_device1");
271 service_test_->ClearServices();
272 const bool add_to_watchlist = true;
273 AddService(shill::kTypeEthernet, "stub_ethernet",
274 shill::kStateOnline, add_to_watchlist);
275 AddService(shill::kTypeWifi, "stub_wifi1",
276 shill::kStateOnline, add_to_watchlist);
277 AddService(shill::kTypeWifi, "stub_wifi2",
278 shill::kStateIdle, add_to_watchlist);
279 AddService(shill::kTypeCellular, "stub_cellular1",
280 shill::kStateIdle, add_to_watchlist);
283 base::MessageLoopForUI message_loop_;
284 scoped_ptr<TestListener> listener_;
285 scoped_ptr<internal::ShillPropertyHandler> shill_property_handler_;
286 ShillManagerClient::TestInterface* manager_test_;
287 ShillDeviceClient::TestInterface* device_test_;
288 ShillServiceClient::TestInterface* service_test_;
289 ShillProfileClient::TestInterface* profile_test_;
291 private:
292 DISALLOW_COPY_AND_ASSIGN(ShillPropertyHandlerTest);
295 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerStub) {
296 EXPECT_TRUE(shill_property_handler_->IsTechnologyAvailable(shill::kTypeWifi));
297 EXPECT_TRUE(shill_property_handler_->IsTechnologyEnabled(shill::kTypeWifi));
298 const size_t kNumShillManagerClientStubImplDevices = 2;
299 EXPECT_EQ(kNumShillManagerClientStubImplDevices,
300 listener_->entries(shill::kDevicesProperty).size());
301 const size_t kNumShillManagerClientStubImplServices = 4;
302 EXPECT_EQ(kNumShillManagerClientStubImplServices,
303 listener_->entries(shill::kServicesProperty).size());
305 EXPECT_EQ(0, listener_->errors());
308 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerTechnologyChanged) {
309 const int initial_technology_updates = 2; // Available and Enabled lists
310 EXPECT_EQ(initial_technology_updates, listener_->technology_list_updates());
312 // Remove an enabled technology. Updates both the Available and Enabled lists.
313 manager_test_->RemoveTechnology(shill::kTypeWifi);
314 message_loop_.RunUntilIdle();
315 EXPECT_EQ(initial_technology_updates + 2,
316 listener_->technology_list_updates());
318 // Add a disabled technology.
319 manager_test_->AddTechnology(shill::kTypeWifi, false);
320 message_loop_.RunUntilIdle();
321 EXPECT_EQ(initial_technology_updates + 3,
322 listener_->technology_list_updates());
323 EXPECT_TRUE(shill_property_handler_->IsTechnologyAvailable(
324 shill::kTypeWifi));
325 EXPECT_FALSE(shill_property_handler_->IsTechnologyEnabled(shill::kTypeWifi));
327 // Enable the technology.
328 DBusThreadManager::Get()->GetShillManagerClient()->EnableTechnology(
329 shill::kTypeWifi,
330 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
331 message_loop_.RunUntilIdle();
332 EXPECT_EQ(initial_technology_updates + 4,
333 listener_->technology_list_updates());
334 EXPECT_TRUE(shill_property_handler_->IsTechnologyEnabled(shill::kTypeWifi));
336 EXPECT_EQ(0, listener_->errors());
339 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerDevicePropertyChanged) {
340 const size_t kNumShillManagerClientStubImplDevices = 2;
341 EXPECT_EQ(kNumShillManagerClientStubImplDevices,
342 listener_->entries(shill::kDevicesProperty).size());
343 // Add a device.
344 listener_->reset_list_updates();
345 const std::string kTestDevicePath("test_wifi_device1");
346 AddDevice(shill::kTypeWifi, kTestDevicePath);
347 message_loop_.RunUntilIdle();
348 EXPECT_EQ(1, listener_->list_updates(shill::kDevicesProperty));
349 EXPECT_EQ(kNumShillManagerClientStubImplDevices + 1,
350 listener_->entries(shill::kDevicesProperty).size());
351 // Device changes are not observed.
352 // Remove a device
353 listener_->reset_list_updates();
354 RemoveDevice(kTestDevicePath);
355 message_loop_.RunUntilIdle();
356 EXPECT_EQ(1, listener_->list_updates(shill::kDevicesProperty));
357 EXPECT_EQ(kNumShillManagerClientStubImplDevices,
358 listener_->entries(shill::kDevicesProperty).size());
360 EXPECT_EQ(0, listener_->errors());
363 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServicePropertyChanged) {
364 const size_t kNumShillManagerClientStubImplServices = 4;
365 EXPECT_EQ(kNumShillManagerClientStubImplServices,
366 listener_->entries(shill::kServicesProperty).size());
368 // Add an unwatched service.
369 listener_->reset_list_updates();
370 const std::string kTestServicePath("test_wifi_service1");
371 AddService(shill::kTypeWifi, kTestServicePath, shill::kStateIdle, false);
372 message_loop_.RunUntilIdle();
373 // Watched and unwatched services trigger a service list update.
374 EXPECT_EQ(1, listener_->list_updates(shill::kServicesProperty));
375 EXPECT_EQ(kNumShillManagerClientStubImplServices + 1,
376 listener_->entries(shill::kServicesProperty).size());
377 // Service receives an initial property update.
378 EXPECT_EQ(1, listener_->initial_property_updates(
379 shill::kServicesProperty)[kTestServicePath]);
380 // Change a property.
381 base::FundamentalValue scan_interval(3);
382 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
383 dbus::ObjectPath(kTestServicePath),
384 shill::kScanIntervalProperty,
385 scan_interval,
386 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
387 message_loop_.RunUntilIdle();
388 // Property change triggers an update.
389 EXPECT_EQ(1, listener_->property_updates(
390 shill::kServicesProperty)[kTestServicePath]);
392 // Add the existing service to the watch list.
393 listener_->reset_list_updates();
394 AddService(shill::kTypeWifi, kTestServicePath, shill::kStateIdle, true);
395 message_loop_.RunUntilIdle();
396 // Service list update should be received when watch list changes.
397 EXPECT_EQ(1, listener_->list_updates(shill::kServicesProperty));
398 // Number of services shouldn't change.
399 EXPECT_EQ(kNumShillManagerClientStubImplServices + 1,
400 listener_->entries(shill::kServicesProperty).size());
402 // Change a property.
403 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
404 dbus::ObjectPath(kTestServicePath),
405 shill::kScanIntervalProperty,
406 scan_interval,
407 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
408 message_loop_.RunUntilIdle();
409 // Property change should trigger another update.
410 EXPECT_EQ(2, listener_->property_updates(
411 shill::kServicesProperty)[kTestServicePath]);
413 // Remove a service
414 listener_->reset_list_updates();
415 RemoveService(kTestServicePath);
416 message_loop_.RunUntilIdle();
417 EXPECT_EQ(1, listener_->list_updates(shill::kServicesProperty));
418 EXPECT_EQ(kNumShillManagerClientStubImplServices,
419 listener_->entries(shill::kServicesProperty).size());
421 EXPECT_EQ(0, listener_->errors());
424 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerIPConfigPropertyChanged) {
425 // Set the properties for an IP Config object.
426 const std::string kTestIPConfigPath("test_ip_config_path");
428 base::StringValue ip_address("192.168.1.1");
429 DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
430 dbus::ObjectPath(kTestIPConfigPath),
431 shill::kAddressProperty, ip_address,
432 base::Bind(&DoNothingWithCallStatus));
433 base::ListValue dns_servers;
434 dns_servers.Append(base::Value::CreateStringValue("192.168.1.100"));
435 dns_servers.Append(base::Value::CreateStringValue("192.168.1.101"));
436 DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
437 dbus::ObjectPath(kTestIPConfigPath),
438 shill::kNameServersProperty, dns_servers,
439 base::Bind(&DoNothingWithCallStatus));
440 base::FundamentalValue prefixlen(8);
441 DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
442 dbus::ObjectPath(kTestIPConfigPath),
443 shill::kPrefixlenProperty, prefixlen,
444 base::Bind(&DoNothingWithCallStatus));
445 base::StringValue gateway("192.0.0.1");
446 DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
447 dbus::ObjectPath(kTestIPConfigPath),
448 shill::kGatewayProperty, gateway,
449 base::Bind(&DoNothingWithCallStatus));
450 message_loop_.RunUntilIdle();
452 // Add a service with an empty ipconfig and then update
453 // its ipconfig property.
454 const std::string kTestServicePath1("test_wifi_service1");
455 AddService(shill::kTypeWifi, kTestServicePath1, shill::kStateIdle, true);
456 message_loop_.RunUntilIdle();
457 // This is the initial property update.
458 EXPECT_EQ(1, listener_->initial_property_updates(
459 shill::kServicesProperty)[kTestServicePath1]);
460 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
461 dbus::ObjectPath(kTestServicePath1),
462 shill::kIPConfigProperty,
463 base::StringValue(kTestIPConfigPath),
464 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
465 message_loop_.RunUntilIdle();
466 // IPConfig property change on the service should trigger property updates for
467 // IP Address, DNS, prefixlen, and gateway.
468 EXPECT_EQ(4, listener_->property_updates(
469 shill::kServicesProperty)[kTestServicePath1]);
471 // Now, Add a new watched service with the IPConfig already set.
472 const std::string kTestServicePath2("test_wifi_service2");
473 AddServiceWithIPConfig(shill::kTypeWifi, kTestServicePath2,
474 shill::kStateIdle, kTestIPConfigPath, true);
475 message_loop_.RunUntilIdle();
476 // A watched service with the IPConfig property already set must trigger
477 // property updates for IP Address, DNS, prefixlen, and gateway when added.
478 EXPECT_EQ(4, listener_->property_updates(
479 shill::kServicesProperty)[kTestServicePath2]);
482 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServiceCompleteList) {
483 // Add a new entry to the profile only (triggers a Services update).
484 const std::string kTestServicePath1("stub_wifi_profile_only1");
485 AddServiceToProfile(shill::kTypeWifi, kTestServicePath1, false);
486 message_loop_.RunUntilIdle();
488 // Update the Manager properties. This should trigger a single list update
489 // for both Services and ServiceCompleteList, and a single property update
490 // for ServiceCompleteList.
491 listener_->reset_list_updates();
492 shill_property_handler_->UpdateManagerProperties();
493 message_loop_.RunUntilIdle();
494 EXPECT_EQ(1, listener_->list_updates(shill::kServicesProperty));
495 EXPECT_EQ(1, listener_->list_updates(shill::kServiceCompleteListProperty));
496 EXPECT_EQ(0, listener_->initial_property_updates(
497 shill::kServicesProperty)[kTestServicePath1]);
498 EXPECT_EQ(1, listener_->initial_property_updates(
499 shill::kServiceCompleteListProperty)[kTestServicePath1]);
500 EXPECT_EQ(0, listener_->property_updates(
501 shill::kServicesProperty)[kTestServicePath1]);
502 EXPECT_EQ(0, listener_->property_updates(
503 shill::kServiceCompleteListProperty)[kTestServicePath1]);
505 // Add a new entry to the services and the profile; should also trigger a
506 // single list update for both Services and ServiceCompleteList, and should
507 // trigger tow property updates for Services (one when the Profile propety
508 // changes, and one for the Request) and one ServiceCompleteList change for
509 // the Request.
510 listener_->reset_list_updates();
511 const std::string kTestServicePath2("stub_wifi_profile_only2");
512 AddServiceToProfile(shill::kTypeWifi, kTestServicePath2, true);
513 shill_property_handler_->UpdateManagerProperties();
514 message_loop_.RunUntilIdle();
515 EXPECT_EQ(1, listener_->list_updates(shill::kServicesProperty));
516 EXPECT_EQ(1, listener_->list_updates(shill::kServiceCompleteListProperty));
517 EXPECT_EQ(1, listener_->initial_property_updates(
518 shill::kServicesProperty)[kTestServicePath2]);
519 EXPECT_EQ(1, listener_->initial_property_updates(
520 shill::kServiceCompleteListProperty)[kTestServicePath2]);
521 // Expect one property update for the Profile property of the Network.
522 EXPECT_EQ(1, listener_->property_updates(
523 shill::kServicesProperty)[kTestServicePath2]);
524 EXPECT_EQ(0, listener_->property_updates(
525 shill::kServiceCompleteListProperty)[kTestServicePath2]);
527 // Change a property of a Network in a Profile.
528 base::FundamentalValue scan_interval(3);
529 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
530 dbus::ObjectPath(kTestServicePath2),
531 shill::kScanIntervalProperty,
532 scan_interval,
533 base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
534 message_loop_.RunUntilIdle();
535 // Property change should trigger an update for the Network only; no
536 // property updates pushed by Shill affect Favorites.
537 EXPECT_EQ(2, listener_->property_updates(
538 shill::kServicesProperty)[kTestServicePath2]);
539 EXPECT_EQ(0, listener_->property_updates(
540 shill::kServiceCompleteListProperty)[kTestServicePath2]);
543 } // namespace chromeos