summaryrefslogtreecommitdiffstats
path: root/chromeos/network/shill_property_handler_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromeos/network/shill_property_handler_unittest.cc')
-rw-r--r--chromeos/network/shill_property_handler_unittest.cc368
1 files changed, 368 insertions, 0 deletions
diff --git a/chromeos/network/shill_property_handler_unittest.cc b/chromeos/network/shill_property_handler_unittest.cc
new file mode 100644
index 0000000..f9954d6
--- /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