Index: chromeos/network/shill_property_handler_unittest.cc |
diff --git a/chromeos/network/shill_property_handler_unittest.cc b/chromeos/network/shill_property_handler_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f9954d69067bbd9a3048a0ae068c5fcf99eb7518 |
--- /dev/null |
+++ b/chromeos/network/shill_property_handler_unittest.cc |
@@ -0,0 +1,368 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chromeos/network/shill_property_handler.h" |
+ |
+#include <map> |
+#include <set> |
+#include <string> |
+ |
+#include "base/bind.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop.h" |
+#include "base/values.h" |
+#include "chromeos/dbus/dbus_thread_manager.h" |
+#include "chromeos/dbus/shill_device_client.h" |
+#include "chromeos/dbus/shill_manager_client.h" |
+#include "chromeos/dbus/shill_service_client.h" |
+#include "dbus/object_path.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "third_party/cros_system_api/dbus/service_constants.h" |
+ |
+namespace chromeos { |
+ |
+namespace { |
+ |
+void ErrorCallbackFunction(const std::string& error_name, |
+ const std::string& error_message) { |
+ LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message; |
+} |
+ |
+class TestListener : public internal::ShillPropertyHandler::Listener { |
+ public: |
+ TestListener() : manager_updates_(0), errors_(0) { |
+ } |
+ |
+ virtual void UpdateManagedList(ManagedState::ManagedType type, |
+ const base::ListValue& entries) OVERRIDE { |
+ UpdateEntries(GetTypeString(type), entries); |
+ } |
+ |
+ virtual void UpdateAvailableTechnologies( |
+ const base::ListValue& technologies) OVERRIDE { |
+ UpdateEntries(flimflam::kAvailableTechnologiesProperty, technologies); |
+ } |
+ |
+ virtual void UpdateEnabledTechnologies( |
+ const base::ListValue& technologies) OVERRIDE { |
+ UpdateEntries(flimflam::kEnabledTechnologiesProperty, technologies); |
+ } |
+ |
+ virtual void UpdateManagedStateProperties( |
+ ManagedState::ManagedType type, |
+ const std::string& path, |
+ const base::DictionaryValue& properties) OVERRIDE { |
+ AddPropertyUpdate(GetTypeString(type), path); |
+ } |
+ |
+ virtual void UpdateNetworkServiceProperty( |
+ const std::string& service_path, |
+ const std::string& key, |
+ const base::Value& value) OVERRIDE { |
+ AddPropertyUpdate(flimflam::kServicesProperty, service_path); |
+ } |
+ |
+ virtual void ManagerPropertyChanged() OVERRIDE { |
+ ++manager_updates_; |
+ } |
+ |
+ virtual void UpdateNetworkServiceIPAddress( |
+ const std::string& service_path, |
+ const std::string& ip_address) OVERRIDE { |
+ AddPropertyUpdate(flimflam::kServicesProperty, service_path); |
+ } |
+ |
+ virtual void ManagedStateListChanged( |
+ ManagedState::ManagedType type) OVERRIDE { |
+ AddStateListUpdate(GetTypeString(type)); |
+ } |
+ |
+ std::vector<std::string>& entries(const std::string& type) { |
+ return entries_[type]; |
+ } |
+ std::map<std::string, int>& property_updates(const std::string& type) { |
+ return property_updates_[type]; |
+ } |
+ int list_updates(const std::string& type) { return list_updates_[type]; } |
+ int manager_updates() { return manager_updates_; } |
+ int errors() { return errors_; } |
+ |
+ private: |
+ std::string GetTypeString(ManagedState::ManagedType type) { |
+ if (type == ManagedState::MANAGED_TYPE_NETWORK) { |
+ return flimflam::kServicesProperty; |
+ } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { |
+ return flimflam::kDevicesProperty; |
+ } |
+ LOG(ERROR) << "UpdateManagedList called with unrecognized type: " << type; |
+ ++errors_; |
+ return std::string(); |
+ } |
+ |
+ void UpdateEntries(const std::string& type, const base::ListValue& entries) { |
+ if (type.empty()) |
+ return; |
+ entries_[type].clear(); |
+ for (base::ListValue::const_iterator iter = entries.begin(); |
+ iter != entries.end(); ++iter) { |
+ std::string path; |
+ if ((*iter)->GetAsString(&path)) |
+ entries_[type].push_back(path); |
+ } |
+ } |
+ |
+ void AddPropertyUpdate(const std::string& type, const std::string& path) { |
+ if (type.empty()) |
+ return; |
+ property_updates(type)[path] += 1; |
+ } |
+ |
+ void AddStateListUpdate(const std::string& type) { |
+ if (type.empty()) |
+ return; |
+ list_updates_[type] += 1; |
+ } |
+ |
+ // Map of list-type -> paths |
+ std::map<std::string, std::vector<std::string> > entries_; |
+ // Map of list-type -> map of paths -> update counts |
+ std::map<std::string, std::map<std::string, int> > property_updates_; |
+ // Map of list-type -> list update counts |
+ std::map<std::string, int > list_updates_; |
+ int manager_updates_; |
+ int errors_; |
+}; |
+ |
+} // namespace |
+ |
+class ShillPropertyHandlerTest : public testing::Test { |
+ public: |
+ ShillPropertyHandlerTest() |
+ : manager_test_(NULL), |
+ device_test_(NULL), |
+ service_test_(NULL) { |
+ } |
+ virtual ~ShillPropertyHandlerTest() { |
+ } |
+ |
+ virtual void SetUp() OVERRIDE { |
+ // Initialize DBusThreadManager with a stub implementation. |
+ DBusThreadManager::InitializeWithStub(); |
+ // Get the test interface for manager / device / service and clear the |
+ // default stub properties. |
+ manager_test_ = |
+ DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface(); |
+ ASSERT_TRUE(manager_test_); |
+ device_test_ = |
+ DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface(); |
+ ASSERT_TRUE(device_test_); |
+ service_test_ = |
+ DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); |
+ ASSERT_TRUE(service_test_); |
+ } |
+ |
+ virtual void TearDown() OVERRIDE { |
+ shill_property_handler_.reset(); |
+ listener_.reset(); |
+ DBusThreadManager::Shutdown(); |
+ } |
+ |
+ void AddDevice(const std::string& type, const std::string& id) { |
+ ASSERT_TRUE(IsValidType(type)); |
+ manager_test_->AddDevice(id); |
+ device_test_->AddDevice(id, type, std::string("/device/" + id), "/stub"); |
+ } |
+ |
+ void RemoveDevice(const std::string& id) { |
+ manager_test_->RemoveDevice(id); |
+ device_test_->RemoveDevice(id); |
+ } |
+ |
+ void AddService(const std::string& type, |
+ const std::string& id, |
+ const std::string& state, |
+ bool add_to_watch_list) { |
+ ASSERT_TRUE(IsValidType(type)); |
+ manager_test_->AddService(id, add_to_watch_list); |
+ service_test_->AddService(id, id, type, state); |
+ } |
+ |
+ void RemoveService(const std::string& id) { |
+ manager_test_->RemoveService(id); |
+ service_test_->RemoveService(id); |
+ } |
+ |
+ // Call this after any initial Shill client setup |
+ void SetupShillPropertyHandler() { |
+ listener_.reset(new TestListener); |
+ shill_property_handler_.reset( |
+ new internal::ShillPropertyHandler(listener_.get())); |
+ shill_property_handler_->Init(); |
+ } |
+ |
+ bool IsValidType(const std::string& type) { |
+ return (type == flimflam::kTypeEthernet || |
+ type == flimflam::kTypeWifi || |
+ type == flimflam::kTypeWimax || |
+ type == flimflam::kTypeBluetooth || |
+ type == flimflam::kTypeCellular || |
+ type == flimflam::kTypeVPN); |
+ } |
+ |
+ protected: |
+ MessageLoopForUI message_loop_; |
+ scoped_ptr<TestListener> listener_; |
+ scoped_ptr<internal::ShillPropertyHandler> shill_property_handler_; |
+ ShillManagerClient::TestInterface* manager_test_; |
+ ShillDeviceClient::TestInterface* device_test_; |
+ ShillServiceClient::TestInterface* service_test_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ShillPropertyHandlerTest); |
+}; |
+ |
+TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerStub) { |
+ SetupShillPropertyHandler(); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(1, listener_->manager_updates()); |
+ // ShillManagerClient default stub entries are in shill_manager_client.cc. |
+ // TODO(stevenjb): Eliminate default stub entries and add them explicitly. |
+ const size_t kNumShillManagerClientStubImplTechnologies = 3; |
+ EXPECT_EQ(kNumShillManagerClientStubImplTechnologies, |
+ listener_->entries( |
+ flimflam::kAvailableTechnologiesProperty).size()); |
+ EXPECT_EQ(kNumShillManagerClientStubImplTechnologies, |
+ listener_->entries( |
+ flimflam::kEnabledTechnologiesProperty).size()); |
+ const size_t kNumShillManagerClientStubImplDevices = 2; |
+ EXPECT_EQ(kNumShillManagerClientStubImplDevices, |
+ listener_->entries(flimflam::kDevicesProperty).size()); |
+ const size_t kNumShillManagerClientStubImplServices = 4; |
+ EXPECT_EQ(kNumShillManagerClientStubImplServices, |
+ listener_->entries(flimflam::kServicesProperty).size()); |
+ |
+ EXPECT_EQ(0, listener_->errors()); |
+} |
+ |
+TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerTechnologyChanged) { |
+ // This relies on the stub dbus implementations for ShillManagerClient, |
+ SetupShillPropertyHandler(); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(1, listener_->manager_updates()); |
+ // Add a disabled technology. |
+ manager_test_->AddTechnology(flimflam::kTypeWimax, false); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(2, listener_->manager_updates()); |
+ const size_t kNumShillManagerClientStubImplTechnologies = 3; |
+ EXPECT_EQ(kNumShillManagerClientStubImplTechnologies + 1, |
+ listener_->entries( |
+ flimflam::kAvailableTechnologiesProperty).size()); |
+ EXPECT_EQ(kNumShillManagerClientStubImplTechnologies, |
+ listener_->entries( |
+ flimflam::kEnabledTechnologiesProperty).size()); |
+ // Enable the technology. |
+ DBusThreadManager::Get()->GetShillManagerClient()->EnableTechnology( |
+ flimflam::kTypeWimax, |
+ base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(3, listener_->manager_updates()); |
+ EXPECT_EQ(kNumShillManagerClientStubImplTechnologies + 1, |
+ listener_->entries( |
+ flimflam::kEnabledTechnologiesProperty).size()); |
+ |
+ EXPECT_EQ(0, listener_->errors()); |
+} |
+ |
+TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerDevicePropertyChanged) { |
+ // This relies on the stub dbus implementations for ShillManagerClient, |
+ SetupShillPropertyHandler(); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(1, listener_->manager_updates()); |
+ EXPECT_EQ(1, listener_->list_updates(flimflam::kDevicesProperty)); |
+ const size_t kNumShillManagerClientStubImplDevices = 2; |
+ EXPECT_EQ(kNumShillManagerClientStubImplDevices, |
+ listener_->entries(flimflam::kDevicesProperty).size()); |
+ // Add a device. |
+ const std::string kTestDevicePath("test_wifi_device1"); |
+ AddDevice(flimflam::kTypeWifi, kTestDevicePath); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(1, listener_->manager_updates()); // No new manager updates. |
+ EXPECT_EQ(2, listener_->list_updates(flimflam::kDevicesProperty)); |
+ EXPECT_EQ(kNumShillManagerClientStubImplDevices + 1, |
+ listener_->entries(flimflam::kDevicesProperty).size()); |
+ // Device changes are not observed. |
+ // Remove a device |
+ RemoveDevice(kTestDevicePath); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(3, listener_->list_updates(flimflam::kDevicesProperty)); |
+ EXPECT_EQ(kNumShillManagerClientStubImplDevices, |
+ listener_->entries(flimflam::kDevicesProperty).size()); |
+ |
+ EXPECT_EQ(0, listener_->errors()); |
+} |
+ |
+TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServicePropertyChanged) { |
+ // This relies on the stub dbus implementations for ShillManagerClient, |
+ SetupShillPropertyHandler(); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(1, listener_->manager_updates()); |
+ EXPECT_EQ(1, listener_->list_updates(flimflam::kServicesProperty)); |
+ const size_t kNumShillManagerClientStubImplServices = 4; |
+ EXPECT_EQ(kNumShillManagerClientStubImplServices, |
+ listener_->entries(flimflam::kServicesProperty).size()); |
+ |
+ // Add an unwatched service. |
+ const std::string kTestServicePath("test_wifi_service1"); |
+ AddService(flimflam::kTypeWifi, kTestServicePath, |
+ flimflam::kStateIdle, false); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(1, listener_->manager_updates()); // No new manager updates. |
+ EXPECT_EQ(2, listener_->list_updates(flimflam::kServicesProperty)); |
+ EXPECT_EQ(kNumShillManagerClientStubImplServices + 1, |
+ listener_->entries(flimflam::kServicesProperty).size()); |
+ // Change a property. |
+ base::FundamentalValue scan_interval(3); |
+ DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( |
+ dbus::ObjectPath(kTestServicePath), |
+ flimflam::kScanIntervalProperty, |
+ scan_interval, |
+ base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); |
+ message_loop_.RunUntilIdle(); |
+ // Property change should NOT trigger an update. |
+ EXPECT_EQ(0, listener_-> |
+ property_updates(flimflam::kServicesProperty)[kTestServicePath]); |
+ |
+ // Add the existing service to the watch list. |
+ AddService(flimflam::kTypeWifi, kTestServicePath, |
+ flimflam::kStateIdle, true); |
+ message_loop_.RunUntilIdle(); |
+ // No new updates or services: |
+ EXPECT_EQ(1, listener_->manager_updates()); |
+ EXPECT_EQ(2, listener_->list_updates(flimflam::kServicesProperty)); |
+ EXPECT_EQ(kNumShillManagerClientStubImplServices + 1, |
+ listener_->entries(flimflam::kServicesProperty).size()); |
+ // Change a property. |
+ DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( |
+ dbus::ObjectPath(kTestServicePath), |
+ flimflam::kScanIntervalProperty, |
+ scan_interval, |
+ base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); |
+ message_loop_.RunUntilIdle(); |
+ // Property change SHOULD trigger an update. |
+ EXPECT_EQ(1, listener_-> |
+ property_updates(flimflam::kServicesProperty)[kTestServicePath]); |
+ |
+ // Remove a service |
+ RemoveService(kTestServicePath); |
+ message_loop_.RunUntilIdle(); |
+ EXPECT_EQ(3, listener_->list_updates(flimflam::kServicesProperty)); |
+ EXPECT_EQ(kNumShillManagerClientStubImplServices, |
+ listener_->entries(flimflam::kServicesProperty).size()); |
+ |
+ EXPECT_EQ(0, listener_->errors()); |
+} |
+ |
+// TODO(stevenjb): Test IP Configs. |
+ |
+} // namespace chromeos |