blob: 3da383191d9e6d1890252cda8cd61ff751e8a286 [file] [log] [blame]
// 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