| // 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/network_state_handler.h" |
| |
| #include <map> |
| #include <set> |
| #include <string> |
| |
| #include "base/bind.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop/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_ipconfig_client.h" |
| #include "chromeos/dbus/shill_manager_client.h" |
| #include "chromeos/dbus/shill_profile_client.h" |
| #include "chromeos/dbus/shill_service_client.h" |
| #include "chromeos/network/device_state.h" |
| #include "chromeos/network/network_state.h" |
| #include "chromeos/network/network_state_handler.h" |
| #include "chromeos/network/network_state_handler_observer.h" |
| #include "dbus/object_path.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| |
| namespace { |
| |
| void ErrorCallbackFunction(const std::string& error_name, |
| const std::string& error_message) { |
| LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message; |
| } |
| |
| const std::string kShillManagerClientStubWifiDevice = |
| "/device/stub_wifi_device1"; |
| const std::string kShillManagerClientStubCellularDevice = |
| "/device/stub_cellular_device1"; |
| const std::string kShillManagerClientStubDefaultService = "/service/eth1"; |
| const std::string kShillManagerClientStubDefaultWifi = "/service/wifi1"; |
| const std::string kShillManagerClientStubWifi2 = "/service/wifi2"; |
| const std::string kShillManagerClientStubCellular = "/service/cellular1"; |
| |
| using chromeos::DeviceState; |
| using chromeos::NetworkState; |
| using chromeos::NetworkStateHandler; |
| |
| class TestObserver : public chromeos::NetworkStateHandlerObserver { |
| public: |
| explicit TestObserver(NetworkStateHandler* handler) |
| : handler_(handler), |
| device_list_changed_count_(0), |
| device_count_(0), |
| network_list_changed_count_(0), |
| network_count_(0), |
| default_network_change_count_(0) { |
| } |
| |
| ~TestObserver() override {} |
| |
| void DeviceListChanged() override { |
| NetworkStateHandler::DeviceStateList devices; |
| handler_->GetDeviceList(&devices); |
| device_count_ = devices.size(); |
| ++device_list_changed_count_; |
| } |
| |
| void NetworkListChanged() override { |
| NetworkStateHandler::NetworkStateList networks; |
| handler_->GetNetworkListByType(chromeos::NetworkTypePattern::Default(), |
| false /* configured_only */, |
| false /* visible_only */, |
| 0 /* no limit */, |
| &networks); |
| network_count_ = networks.size(); |
| if (network_count_ == 0) { |
| default_network_ = ""; |
| default_network_connection_state_ = ""; |
| } |
| ++network_list_changed_count_; |
| } |
| |
| void DefaultNetworkChanged(const NetworkState* network) override { |
| EXPECT_TRUE(!network || network->IsConnectedState()); |
| ++default_network_change_count_; |
| default_network_ = network ? network->path() : ""; |
| default_network_connection_state_ = |
| network ? network->connection_state() : ""; |
| DVLOG(1) << "DefaultNetworkChanged: " << default_network_ |
| << " State: " << default_network_connection_state_; |
| } |
| |
| void NetworkConnectionStateChanged(const NetworkState* network) override { |
| network_connection_state_[network->path()] = network->connection_state(); |
| connection_state_changes_[network->path()]++; |
| } |
| |
| void NetworkPropertiesUpdated(const NetworkState* network) override { |
| DCHECK(network); |
| property_updates_[network->path()]++; |
| } |
| |
| void DevicePropertiesUpdated(const DeviceState* device) override { |
| DCHECK(device); |
| device_property_updates_[device->path()]++; |
| } |
| |
| size_t device_list_changed_count() { return device_list_changed_count_; } |
| size_t device_count() { return device_count_; } |
| size_t network_list_changed_count() { return network_list_changed_count_; } |
| size_t network_count() { return network_count_; } |
| size_t default_network_change_count() { |
| return default_network_change_count_; |
| } |
| void reset_change_counts() { |
| DVLOG(1) << "=== RESET CHANGE COUNTS ==="; |
| default_network_change_count_ = 0; |
| device_list_changed_count_ = 0; |
| network_list_changed_count_ = 0; |
| connection_state_changes_.clear(); |
| } |
| void reset_updates() { |
| property_updates_.clear(); |
| device_property_updates_.clear(); |
| } |
| std::string default_network() { return default_network_; } |
| std::string default_network_connection_state() { |
| return default_network_connection_state_; |
| } |
| |
| int PropertyUpdatesForService(const std::string& service_path) { |
| return property_updates_[service_path]; |
| } |
| |
| int PropertyUpdatesForDevice(const std::string& device_path) { |
| return device_property_updates_[device_path]; |
| } |
| |
| int ConnectionStateChangesForService(const std::string& service_path) { |
| return connection_state_changes_[service_path]; |
| } |
| |
| std::string NetworkConnectionStateForService( |
| const std::string& service_path) { |
| return network_connection_state_[service_path]; |
| } |
| |
| private: |
| NetworkStateHandler* handler_; |
| size_t device_list_changed_count_; |
| size_t device_count_; |
| size_t network_list_changed_count_; |
| size_t network_count_; |
| size_t default_network_change_count_; |
| std::string default_network_; |
| std::string default_network_connection_state_; |
| std::map<std::string, int> property_updates_; |
| std::map<std::string, int> device_property_updates_; |
| std::map<std::string, int> connection_state_changes_; |
| std::map<std::string, std::string> network_connection_state_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestObserver); |
| }; |
| |
| } // namespace |
| |
| namespace chromeos { |
| |
| class NetworkStateHandlerTest : public testing::Test { |
| public: |
| NetworkStateHandlerTest() |
| : device_test_(nullptr), |
| manager_test_(nullptr), |
| profile_test_(nullptr), |
| service_test_(nullptr) {} |
| ~NetworkStateHandlerTest() override {} |
| |
| void SetUp() override { |
| // Initialize DBusThreadManager with a stub implementation. |
| DBusThreadManager::Initialize(); |
| SetupDefaultShillState(); |
| network_state_handler_.reset(new NetworkStateHandler); |
| test_observer_.reset(new TestObserver(network_state_handler_.get())); |
| network_state_handler_->AddObserver(test_observer_.get(), FROM_HERE); |
| network_state_handler_->InitShillPropertyHandler(); |
| message_loop_.RunUntilIdle(); |
| test_observer_->reset_change_counts(); |
| } |
| |
| void TearDown() override { |
| network_state_handler_->RemoveObserver(test_observer_.get(), FROM_HERE); |
| test_observer_.reset(); |
| network_state_handler_.reset(); |
| DBusThreadManager::Shutdown(); |
| } |
| |
| protected: |
| void AddService(const std::string& service_path, |
| const std::string& guid, |
| const std::string& name, |
| const std::string& type, |
| const std::string& state) { |
| service_test_->AddService(service_path, guid, name, type, state, |
| true /* add_to_visible */); |
| } |
| |
| void SetupDefaultShillState() { |
| message_loop_.RunUntilIdle(); // Process any pending updates |
| device_test_ = |
| DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface(); |
| ASSERT_TRUE(device_test_); |
| device_test_->ClearDevices(); |
| device_test_->AddDevice(kShillManagerClientStubWifiDevice, |
| shill::kTypeWifi, "stub_wifi_device1"); |
| device_test_->AddDevice(kShillManagerClientStubCellularDevice, |
| shill::kTypeCellular, "stub_cellular_device1"); |
| |
| manager_test_ = |
| DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface(); |
| ASSERT_TRUE(manager_test_); |
| |
| profile_test_ = |
| DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface(); |
| ASSERT_TRUE(profile_test_); |
| profile_test_->ClearProfiles(); |
| |
| service_test_ = |
| DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); |
| ASSERT_TRUE(service_test_); |
| service_test_->ClearServices(); |
| AddService(kShillManagerClientStubDefaultService, |
| "eth1_guid", |
| "eth1", |
| shill::kTypeEthernet, |
| shill::kStateOnline); |
| AddService(kShillManagerClientStubDefaultWifi, |
| "wifi1_guid", |
| "wifi1", |
| shill::kTypeWifi, |
| shill::kStateOnline); |
| AddService(kShillManagerClientStubWifi2, |
| "wifi2_guid", |
| "wifi2", |
| shill::kTypeWifi, |
| shill::kStateIdle); |
| AddService(kShillManagerClientStubCellular, |
| "cellular1_guid", |
| "cellular1", |
| shill::kTypeCellular, |
| shill::kStateIdle); |
| } |
| |
| void UpdateManagerProperties() { |
| message_loop_.RunUntilIdle(); |
| } |
| |
| void SetServiceProperty(const std::string& service_path, |
| const std::string& key, |
| const base::Value& value) { |
| DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( |
| dbus::ObjectPath(service_path), key, value, |
| base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction)); |
| } |
| |
| base::MessageLoopForUI message_loop_; |
| scoped_ptr<NetworkStateHandler> network_state_handler_; |
| scoped_ptr<TestObserver> test_observer_; |
| ShillDeviceClient::TestInterface* device_test_; |
| ShillManagerClient::TestInterface* manager_test_; |
| ShillProfileClient::TestInterface* profile_test_; |
| ShillServiceClient::TestInterface* service_test_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest); |
| }; |
| |
| TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) { |
| // Ensure that the device and network list are the expected size. |
| const size_t kNumShillManagerClientStubImplDevices = 2; |
| EXPECT_EQ(kNumShillManagerClientStubImplDevices, |
| test_observer_->device_count()); |
| const size_t kNumShillManagerClientStubImplServices = 4; |
| EXPECT_EQ(kNumShillManagerClientStubImplServices, |
| test_observer_->network_count()); |
| // Ensure that the first stub network is the default network. |
| EXPECT_EQ(kShillManagerClientStubDefaultService, |
| test_observer_->default_network()); |
| ASSERT_TRUE(network_state_handler_->DefaultNetwork()); |
| EXPECT_EQ(kShillManagerClientStubDefaultService, |
| network_state_handler_->DefaultNetwork()->path()); |
| EXPECT_EQ(kShillManagerClientStubDefaultService, |
| network_state_handler_->ConnectedNetworkByType( |
| NetworkTypePattern::Ethernet())->path()); |
| EXPECT_EQ(kShillManagerClientStubDefaultWifi, |
| network_state_handler_->ConnectedNetworkByType( |
| NetworkTypePattern::WiFi())->path()); |
| EXPECT_EQ(kShillManagerClientStubCellular, |
| network_state_handler_->FirstNetworkByType( |
| NetworkTypePattern::Mobile())->path()); |
| EXPECT_EQ( |
| kShillManagerClientStubCellular, |
| network_state_handler_->FirstNetworkByType(NetworkTypePattern::Cellular()) |
| ->path()); |
| EXPECT_EQ(shill::kStateOnline, |
| test_observer_->default_network_connection_state()); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, GetNetworkList) { |
| // Ensure that the network list is the expected size. |
| const size_t kNumShillManagerClientStubImplServices = 4; |
| EXPECT_EQ(kNumShillManagerClientStubImplServices, |
| test_observer_->network_count()); |
| // Add a non-visible network to the profile. |
| const std::string profile = "/profile/profile1"; |
| const std::string wifi_favorite_path = "/service/wifi_faviorite"; |
| service_test_->AddService(wifi_favorite_path, |
| "wifi_faviorite_guid", |
| "wifi_faviorite", |
| shill::kTypeWifi, |
| shill::kStateIdle, |
| false /* add_to_visible */); |
| profile_test_->AddProfile(profile, "" /* userhash */); |
| EXPECT_TRUE(profile_test_->AddService(profile, wifi_favorite_path)); |
| UpdateManagerProperties(); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(kNumShillManagerClientStubImplServices + 1, |
| test_observer_->network_count()); |
| |
| // Get all networks. |
| NetworkStateHandler::NetworkStateList networks; |
| network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(), |
| false /* configured_only */, |
| false /* visible_only */, |
| 0 /* no limit */, |
| &networks); |
| EXPECT_EQ(kNumShillManagerClientStubImplServices + 1, networks.size()); |
| // Limit number of results. |
| network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(), |
| false /* configured_only */, |
| false /* visible_only */, |
| 2 /* limit */, |
| &networks); |
| EXPECT_EQ(2u, networks.size()); |
| // Get all wifi networks. |
| network_state_handler_->GetNetworkListByType(NetworkTypePattern::WiFi(), |
| false /* configured_only */, |
| false /* visible_only */, |
| 0 /* no limit */, |
| &networks); |
| EXPECT_EQ(3u, networks.size()); |
| // Get visible networks. |
| network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(), |
| false /* configured_only */, |
| true /* visible_only */, |
| 0 /* no limit */, |
| &networks); |
| EXPECT_EQ(kNumShillManagerClientStubImplServices, networks.size()); |
| network_state_handler_->GetVisibleNetworkList(&networks); |
| EXPECT_EQ(kNumShillManagerClientStubImplServices, networks.size()); |
| // Get configured (profile) networks. |
| network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(), |
| true /* configured_only */, |
| false /* visible_only */, |
| 0 /* no limit */, |
| &networks); |
| EXPECT_EQ(1u, networks.size()); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, NetworkListChanged) { |
| size_t stub_network_count = test_observer_->network_count(); |
| // Set up two additional visible networks. |
| const std::string wifi3 = "/service/wifi3"; |
| const std::string wifi4 = "/service/wifi4"; |
| service_test_->SetServiceProperties( |
| wifi3, "wifi3_guid", "wifi3", |
| shill::kTypeWifi, shill::kStateIdle, true /* visible */); |
| service_test_->SetServiceProperties( |
| wifi4, "wifi4_guid", "wifi4", |
| shill::kTypeWifi, shill::kStateIdle, true /* visible */); |
| // Add the services to the Manager. Only notify when the second service is |
| // added. |
| manager_test_->AddManagerService(wifi3, false); |
| manager_test_->AddManagerService(wifi4, true); |
| UpdateManagerProperties(); |
| // Expect two service updates and one list update. |
| EXPECT_EQ(stub_network_count + 2, test_observer_->network_count()); |
| EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi3)); |
| EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi4)); |
| EXPECT_EQ(1u, test_observer_->network_list_changed_count()); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, GetVisibleNetworks) { |
| // Ensure that the network list is the expected size. |
| const size_t kNumShillManagerClientStubImplServices = 4; |
| EXPECT_EQ(kNumShillManagerClientStubImplServices, |
| test_observer_->network_count()); |
| // Add a non-visible network to the profile. |
| const std::string profile = "/profile/profile1"; |
| const std::string wifi_favorite_path = "/service/wifi_faviorite"; |
| service_test_->AddService(wifi_favorite_path, |
| "wifi_faviorite_guid", |
| "wifi_faviorite", |
| shill::kTypeWifi, |
| shill::kStateIdle, |
| false /* add_to_visible */); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(kNumShillManagerClientStubImplServices + 1, |
| test_observer_->network_count()); |
| |
| // Get visible networks. |
| NetworkStateHandler::NetworkStateList networks; |
| network_state_handler_->GetVisibleNetworkList(&networks); |
| EXPECT_EQ(kNumShillManagerClientStubImplServices, networks.size()); |
| |
| // Change the visible state of a network. |
| SetServiceProperty(kShillManagerClientStubWifi2, shill::kVisibleProperty, |
| base::FundamentalValue(false)); |
| message_loop_.RunUntilIdle(); |
| network_state_handler_->GetVisibleNetworkList(&networks); |
| EXPECT_EQ(kNumShillManagerClientStubImplServices - 1, networks.size()); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, TechnologyChanged) { |
| // Disable a technology. Will immediately set the state to AVAILABLE and |
| // notify observers. |
| network_state_handler_->SetTechnologyEnabled( |
| NetworkTypePattern::WiFi(), false, network_handler::ErrorCallback()); |
| EXPECT_EQ(1u, test_observer_->device_list_changed_count()); |
| EXPECT_EQ( |
| NetworkStateHandler::TECHNOLOGY_AVAILABLE, |
| network_state_handler_->GetTechnologyState(NetworkTypePattern::WiFi())); |
| |
| // Run the message loop. An additional notification will be received when |
| // Shill updates the enabled technologies. The state should remain AVAILABLE. |
| test_observer_->reset_change_counts(); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(1u, test_observer_->device_list_changed_count()); |
| EXPECT_EQ( |
| NetworkStateHandler::TECHNOLOGY_AVAILABLE, |
| network_state_handler_->GetTechnologyState(NetworkTypePattern::WiFi())); |
| |
| // Enable a technology. Will immediately set the state to ENABLING and |
| // notify observers. |
| test_observer_->reset_change_counts(); |
| network_state_handler_->SetTechnologyEnabled( |
| NetworkTypePattern::WiFi(), true, network_handler::ErrorCallback()); |
| EXPECT_EQ(1u, test_observer_->device_list_changed_count()); |
| EXPECT_EQ( |
| NetworkStateHandler::TECHNOLOGY_ENABLING, |
| network_state_handler_->GetTechnologyState(NetworkTypePattern::WiFi())); |
| |
| // Run the message loop. State should change to ENABLED. |
| test_observer_->reset_change_counts(); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(1u, test_observer_->device_list_changed_count()); |
| EXPECT_EQ( |
| NetworkStateHandler::TECHNOLOGY_ENABLED, |
| network_state_handler_->GetTechnologyState(NetworkTypePattern::WiFi())); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, TechnologyState) { |
| manager_test_->RemoveTechnology(shill::kTypeWimax); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ( |
| NetworkStateHandler::TECHNOLOGY_UNAVAILABLE, |
| network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); |
| |
| manager_test_->AddTechnology(shill::kTypeWimax, false); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ( |
| NetworkStateHandler::TECHNOLOGY_AVAILABLE, |
| network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); |
| |
| manager_test_->SetTechnologyInitializing(shill::kTypeWimax, true); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ( |
| NetworkStateHandler::TECHNOLOGY_UNINITIALIZED, |
| network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); |
| |
| manager_test_->SetTechnologyInitializing(shill::kTypeWimax, false); |
| network_state_handler_->SetTechnologyEnabled( |
| NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback()); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ( |
| NetworkStateHandler::TECHNOLOGY_ENABLED, |
| network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); |
| |
| manager_test_->RemoveTechnology(shill::kTypeWimax); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ( |
| NetworkStateHandler::TECHNOLOGY_UNAVAILABLE, |
| network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax())); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) { |
| // Set a service property. |
| const std::string eth1 = kShillManagerClientStubDefaultService; |
| const NetworkState* ethernet = network_state_handler_->GetNetworkState(eth1); |
| ASSERT_TRUE(ethernet); |
| EXPECT_EQ("", ethernet->security_class()); |
| EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth1)); |
| base::StringValue security_class_value("TestSecurityClass"); |
| SetServiceProperty(eth1, shill::kSecurityClassProperty, security_class_value); |
| message_loop_.RunUntilIdle(); |
| ethernet = network_state_handler_->GetNetworkState(eth1); |
| EXPECT_EQ("TestSecurityClass", ethernet->security_class()); |
| EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1)); |
| |
| // Changing a service to the existing value should not trigger an update. |
| SetServiceProperty(eth1, shill::kSecurityClassProperty, security_class_value); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1)); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, GetState) { |
| const std::string profile = "/profile/profile1"; |
| const std::string wifi_path = kShillManagerClientStubDefaultWifi; |
| |
| // Add a wifi service to a Profile. |
| profile_test_->AddProfile(profile, "" /* userhash */); |
| EXPECT_TRUE(profile_test_->AddService(profile, wifi_path)); |
| UpdateManagerProperties(); |
| |
| // Ensure that a NetworkState exists. |
| const NetworkState* wifi_network = |
| network_state_handler_->GetNetworkStateFromServicePath( |
| wifi_path, true /* configured_only */); |
| ASSERT_TRUE(wifi_network); |
| |
| // Test looking up by GUID. |
| ASSERT_FALSE(wifi_network->guid().empty()); |
| const NetworkState* wifi_network_guid = |
| network_state_handler_->GetNetworkStateFromGuid(wifi_network->guid()); |
| EXPECT_EQ(wifi_network, wifi_network_guid); |
| |
| // Remove the service, verify that there is no longer a NetworkState for it. |
| service_test_->RemoveService(wifi_path); |
| UpdateManagerProperties(); |
| EXPECT_FALSE(network_state_handler_->GetNetworkState(wifi_path)); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) { |
| const std::string eth1 = kShillManagerClientStubDefaultService; |
| EXPECT_EQ(0, test_observer_->ConnectionStateChangesForService(eth1)); |
| |
| // Change a network state. |
| base::StringValue connection_state_idle_value(shill::kStateIdle); |
| service_test_->SetServiceProperty(eth1, shill::kStateProperty, |
| connection_state_idle_value); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(shill::kStateIdle, |
| test_observer_->NetworkConnectionStateForService(eth1)); |
| EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(eth1)); |
| // Confirm that changing the connection state to the same value does *not* |
| // signal the observer. |
| service_test_->SetServiceProperty(eth1, shill::kStateProperty, |
| connection_state_idle_value); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(eth1)); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, DefaultServiceDisconnected) { |
| const std::string eth1 = kShillManagerClientStubDefaultService; |
| const std::string wifi1 = kShillManagerClientStubDefaultWifi; |
| |
| EXPECT_EQ(0u, test_observer_->default_network_change_count()); |
| // Disconnect ethernet. |
| base::StringValue connection_state_idle_value(shill::kStateIdle); |
| service_test_->SetServiceProperty(eth1, shill::kStateProperty, |
| connection_state_idle_value); |
| message_loop_.RunUntilIdle(); |
| // Expect two changes: first when eth1 becomes disconnected, second when |
| // wifi1 becomes the default. |
| EXPECT_EQ(2u, test_observer_->default_network_change_count()); |
| EXPECT_EQ(wifi1, test_observer_->default_network()); |
| |
| // Disconnect wifi. |
| test_observer_->reset_change_counts(); |
| service_test_->SetServiceProperty(wifi1, shill::kStateProperty, |
| connection_state_idle_value); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(1u, test_observer_->default_network_change_count()); |
| EXPECT_EQ("", test_observer_->default_network()); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, DefaultServiceConnected) { |
| const std::string eth1 = kShillManagerClientStubDefaultService; |
| const std::string wifi1 = kShillManagerClientStubDefaultWifi; |
| |
| // Disconnect ethernet and wifi. |
| base::StringValue connection_state_idle_value(shill::kStateIdle); |
| service_test_->SetServiceProperty(eth1, shill::kStateProperty, |
| connection_state_idle_value); |
| service_test_->SetServiceProperty(wifi1, shill::kStateProperty, |
| connection_state_idle_value); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(std::string(), test_observer_->default_network()); |
| |
| // Connect ethernet, should become the default network. |
| test_observer_->reset_change_counts(); |
| base::StringValue connection_state_ready_value(shill::kStateReady); |
| service_test_->SetServiceProperty(eth1, shill::kStateProperty, |
| connection_state_ready_value); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(eth1, test_observer_->default_network()); |
| EXPECT_EQ(shill::kStateReady, |
| test_observer_->default_network_connection_state()); |
| EXPECT_EQ(1u, test_observer_->default_network_change_count()); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, DefaultServiceChanged) { |
| const std::string eth1 = kShillManagerClientStubDefaultService; |
| // The default service should be eth1. |
| EXPECT_EQ(eth1, test_observer_->default_network()); |
| |
| // Change the default network by changing Manager.DefaultService. |
| // This should only generate one default network notification when the |
| // DefaultService property changes. |
| const std::string wifi1 = kShillManagerClientStubDefaultWifi; |
| SetServiceProperty(eth1, shill::kStateProperty, |
| base::StringValue(shill::kStateIdle)); |
| manager_test_->SetManagerProperty(shill::kDefaultServiceProperty, |
| base::StringValue(wifi1)); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(wifi1, test_observer_->default_network()); |
| EXPECT_EQ(1u, test_observer_->default_network_change_count()); |
| |
| // Change the state of the default network. This should generate a |
| // default network notification. |
| test_observer_->reset_change_counts(); |
| service_test_->SetServiceProperty(wifi1, shill::kStateProperty, |
| base::StringValue(shill::kStateReady)); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(shill::kStateReady, |
| test_observer_->default_network_connection_state()); |
| EXPECT_EQ(1u, test_observer_->default_network_change_count()); |
| |
| // Updating a property on the default network should also trigger |
| // a default network change. |
| test_observer_->reset_change_counts(); |
| SetServiceProperty(wifi1, shill::kSecurityClassProperty, |
| base::StringValue("TestSecurityClass")); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(1u, test_observer_->default_network_change_count()); |
| |
| // No default network updates for signal strength changes. |
| test_observer_->reset_change_counts(); |
| SetServiceProperty(wifi1, shill::kSignalStrengthProperty, |
| base::FundamentalValue(32)); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(0u, test_observer_->default_network_change_count()); |
| |
| // Change the default network to a Connecting network, then set the |
| // state to Connected. The DefaultNetworkChange notification should only |
| // fire once when the network is connected. |
| test_observer_->reset_change_counts(); |
| SetServiceProperty(wifi1, shill::kStateProperty, |
| base::StringValue(shill::kStateIdle)); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(1u, test_observer_->default_network_change_count()); |
| EXPECT_EQ(std::string(), test_observer_->default_network()); |
| |
| const std::string wifi2 = kShillManagerClientStubWifi2; |
| manager_test_->SetManagerProperty(shill::kDefaultServiceProperty, |
| base::StringValue(wifi2)); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(1u, test_observer_->default_network_change_count()); |
| // Change the connection state of the default network, observer should fire. |
| SetServiceProperty(wifi2, shill::kStateProperty, |
| base::StringValue(shill::kStateReady)); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(wifi2, test_observer_->default_network()); |
| EXPECT_EQ(2u, test_observer_->default_network_change_count()); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, RequestUpdate) { |
| // Request an update for kShillManagerClientStubDefaultWifi. |
| EXPECT_EQ(1, test_observer_->PropertyUpdatesForService( |
| kShillManagerClientStubDefaultWifi)); |
| network_state_handler_->RequestUpdateForNetwork( |
| kShillManagerClientStubDefaultWifi); |
| message_loop_.RunUntilIdle(); |
| EXPECT_EQ(2, test_observer_->PropertyUpdatesForService( |
| kShillManagerClientStubDefaultWifi)); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, NetworkGuidInProfile) { |
| const std::string profile = "/profile/profile1"; |
| const std::string wifi_path = "/service/wifi_with_guid"; |
| const std::string wifi_guid = "wifi_guid"; |
| const std::string wifi_name = "WifiWithGuid"; |
| const bool is_service_configured = true; |
| |
| // Add a network to the default Profile with a specified GUID. |
| AddService(wifi_path, wifi_guid, wifi_name, |
| shill::kTypeWifi, shill::kStateOnline); |
| profile_test_->AddProfile(profile, "" /* userhash */); |
| EXPECT_TRUE(profile_test_->AddService(profile, wifi_path)); |
| UpdateManagerProperties(); |
| |
| // Verify that a NetworkState exists with a matching GUID. |
| const NetworkState* network = |
| network_state_handler_->GetNetworkStateFromServicePath( |
| wifi_path, is_service_configured); |
| ASSERT_TRUE(network); |
| EXPECT_EQ(wifi_guid, network->guid()); |
| |
| // Remove the service (simulating a network going out of range). |
| service_test_->RemoveService(wifi_path); |
| UpdateManagerProperties(); |
| EXPECT_FALSE(network_state_handler_->GetNetworkState(wifi_path)); |
| |
| // Add the service (simulating a network coming back in range) and verify that |
| // the NetworkState was created with the same GUID. |
| AddService(wifi_path, "" /* guid */, wifi_name, |
| shill::kTypeWifi, shill::kStateOnline); |
| UpdateManagerProperties(); |
| network = network_state_handler_->GetNetworkStateFromServicePath( |
| wifi_path, is_service_configured); |
| ASSERT_TRUE(network); |
| EXPECT_EQ(wifi_guid, network->guid()); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, NetworkGuidNotInProfile) { |
| const std::string wifi_path = "/service/wifi_with_guid"; |
| const std::string wifi_name = "WifiWithGuid"; |
| const bool is_service_configured = false; |
| |
| // Add a network without specifying a GUID or adding it to a profile. |
| AddService(wifi_path, "" /* guid */, wifi_name, |
| shill::kTypeWifi, shill::kStateOnline); |
| UpdateManagerProperties(); |
| |
| // Verify that a NetworkState exists with an assigned GUID. |
| const NetworkState* network = |
| network_state_handler_->GetNetworkStateFromServicePath( |
| wifi_path, is_service_configured); |
| ASSERT_TRUE(network); |
| std::string wifi_guid = network->guid(); |
| EXPECT_FALSE(wifi_guid.empty()); |
| |
| // Remove the service (simulating a network going out of range). |
| service_test_->RemoveService(wifi_path); |
| UpdateManagerProperties(); |
| EXPECT_FALSE(network_state_handler_->GetNetworkState(wifi_path)); |
| |
| // Add the service (simulating a network coming back in range) and verify that |
| // the NetworkState was created with the same GUID. |
| AddService(wifi_path, "" /* guid */, wifi_name, |
| shill::kTypeWifi, shill::kStateOnline); |
| UpdateManagerProperties(); |
| network = network_state_handler_->GetNetworkStateFromServicePath( |
| wifi_path, is_service_configured); |
| ASSERT_TRUE(network); |
| EXPECT_EQ(wifi_guid, network->guid()); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, DeviceListChanged) { |
| size_t stub_device_count = test_observer_->device_count(); |
| // Add an additional device. |
| const std::string wifi_device = "/service/stub_wifi_device2"; |
| device_test_->AddDevice(wifi_device, shill::kTypeWifi, "stub_wifi_device2"); |
| UpdateManagerProperties(); |
| // Expect a device list update. |
| EXPECT_EQ(stub_device_count + 1, test_observer_->device_count()); |
| EXPECT_EQ(0, test_observer_->PropertyUpdatesForDevice(wifi_device)); |
| // Change a device property. |
| device_test_->SetDeviceProperty( |
| wifi_device, shill::kScanningProperty, base::FundamentalValue(true)); |
| UpdateManagerProperties(); |
| EXPECT_EQ(1, test_observer_->PropertyUpdatesForDevice(wifi_device)); |
| } |
| |
| TEST_F(NetworkStateHandlerTest, IPConfigChanged) { |
| test_observer_->reset_updates(); |
| EXPECT_EQ(0, test_observer_->PropertyUpdatesForDevice( |
| kShillManagerClientStubWifiDevice)); |
| EXPECT_EQ(0, test_observer_->PropertyUpdatesForService( |
| kShillManagerClientStubDefaultWifi)); |
| |
| // Change IPConfigs property. |
| ShillIPConfigClient::TestInterface* ip_config_test = |
| DBusThreadManager::Get()->GetShillIPConfigClient()->GetTestInterface(); |
| const std::string kIPConfigPath = "test_ip_config"; |
| base::DictionaryValue ip_config_properties; |
| ip_config_test->AddIPConfig(kIPConfigPath, ip_config_properties); |
| base::ListValue device_ip_configs; |
| device_ip_configs.Append(new base::StringValue(kIPConfigPath)); |
| device_test_->SetDeviceProperty( |
| kShillManagerClientStubWifiDevice, shill::kIPConfigsProperty, |
| device_ip_configs); |
| service_test_->SetServiceProperty( |
| kShillManagerClientStubDefaultWifi, shill::kIPConfigProperty, |
| base::StringValue(kIPConfigPath)); |
| UpdateManagerProperties(); |
| EXPECT_EQ(1, test_observer_->PropertyUpdatesForDevice( |
| kShillManagerClientStubWifiDevice)); |
| EXPECT_EQ(1, test_observer_->PropertyUpdatesForService( |
| kShillManagerClientStubDefaultWifi)); |
| } |
| |
| } // namespace chromeos |