| Index: components/wifi_sync/wifi_config_observer_chromeos_unittest.cc
|
| diff --git a/components/wifi_sync/wifi_config_observer_chromeos_unittest.cc b/components/wifi_sync/wifi_config_observer_chromeos_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..52c11272cf7874f040e456f5b32f7ec529108d11
|
| --- /dev/null
|
| +++ b/components/wifi_sync/wifi_config_observer_chromeos_unittest.cc
|
| @@ -0,0 +1,985 @@
|
| +// Copyright 2015 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 "components/wifi_sync/wifi_config_observer_chromeos.h"
|
| +
|
| +#include <set>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/macros.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/stringprintf.h"
|
| +#include "base/values.h"
|
| +#include "chromeos/dbus/dbus_thread_manager.h"
|
| +#include "chromeos/network/managed_network_configuration_handler.h"
|
| +#include "chromeos/network/network_configuration_handler.h"
|
| +#include "chromeos/network/network_handler_callbacks.h"
|
| +#include "chromeos/network/network_state.h"
|
| +#include "chromeos/network/network_state_handler.h"
|
| +#include "components/wifi_sync/wifi_credential.h"
|
| +#include "components/wifi_sync/wifi_credential_syncable_service.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "third_party/cros_system_api/dbus/service_constants.h"
|
| +
|
| +using chromeos::network_handler::DictionaryResultCallback;
|
| +using chromeos::network_handler::ErrorCallback;
|
| +using chromeos::network_handler::StringResultCallback;
|
| +
|
| +namespace wifi_sync {
|
| +
|
| +namespace {
|
| +
|
| +const char kPassphrasePsk[] = "psk-passphrase";
|
| +const char kPassphraseWep[] = "abcde";
|
| +const char kServiceGuid[] = "32938100-1456-4138-88e6-6edee41c88c8";
|
| +const char kService2Guid[] = "4e715282-1299-40c8-b873-8d992b5999e2";
|
| +const char kServicePath[] = "/service/fake";
|
| +const char kService2Path[] = "/service/fake2";
|
| +const char kUserHash[] = "fake-user-hash";
|
| +const char kProfilePath[] = "/profile/fake";
|
| +
|
| +class FakeWifiCredentialSyncableService : public WifiCredentialSyncableService {
|
| + public:
|
| + FakeWifiCredentialSyncableService()
|
| + : add_to_synced_networks_call_count_(0) {}
|
| + ~FakeWifiCredentialSyncableService() override {}
|
| +
|
| + // syncer::SyncableService implementation.
|
| + syncer::SyncMergeResult MergeDataAndStartSyncing(
|
| + syncer::ModelType type,
|
| + const syncer::SyncDataList& initial_sync_data,
|
| + scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
|
| + scoped_ptr<syncer::SyncErrorFactory> error_handler) override {
|
| + NOTIMPLEMENTED();
|
| + return syncer::SyncMergeResult(type);
|
| + }
|
| + void StopSyncing(syncer::ModelType type) override {
|
| + NOTIMPLEMENTED();
|
| + }
|
| + syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override {
|
| + NOTIMPLEMENTED();
|
| + return syncer::SyncDataList();
|
| + }
|
| + syncer::SyncError ProcessSyncChanges(
|
| + const tracked_objects::Location& caller_location,
|
| + const syncer::SyncChangeList& change_list) override {
|
| + NOTIMPLEMENTED();
|
| + return syncer::SyncError();
|
| + }
|
| +
|
| + // WifiCredentialSyncableService implementation.
|
| + bool AddToSyncedNetworks(const WifiCredential& credential) override {
|
| + LOG(ERROR) << "*** QUICHE: " << __func__ << " on " << this;
|
| + ++add_to_synced_networks_call_count_;
|
| + last_passphrase_ = credential.passphrase();
|
| + return true;
|
| + }
|
| +
|
| + // XXX doc
|
| + size_t add_to_synced_networks_call_count() const {
|
| + return add_to_synced_networks_call_count_;
|
| + }
|
| +
|
| + // XXX doc
|
| + std::string last_passphrase() const {
|
| + return last_passphrase_;
|
| + }
|
| +
|
| + private:
|
| + // The number of times AddToSyncedNetworks has been called on this fake.
|
| + size_t add_to_synced_networks_call_count_;
|
| +
|
| + // The passphrase received in the most recent call to AddToSyncedNetworks.
|
| + std::string last_passphrase_;
|
| +};
|
| +
|
| +class FakeManagedNetworkConfigurationHandler
|
| + : public chromeos::ManagedNetworkConfigurationHandler {
|
| + public:
|
| + ~FakeManagedNetworkConfigurationHandler() override {}
|
| +
|
| + // ManagedNetworkConfigurationHandler implementation.
|
| + void AddObserver(chromeos::NetworkPolicyObserver* observer) override {
|
| + NOTIMPLEMENTED();
|
| + }
|
| + void RemoveObserver(chromeos::NetworkPolicyObserver* observer) override {
|
| + NOTIMPLEMENTED();
|
| + }
|
| + void GetProperties(
|
| + const std::string& service_path,
|
| + const DictionaryResultCallback& callback,
|
| + const ErrorCallback& error_callback) override {
|
| + NOTIMPLEMENTED();
|
| + }
|
| + void GetManagedProperties(
|
| + const std::string& userhash,
|
| + const std::string& service_path,
|
| + const DictionaryResultCallback& callback,
|
| + const ErrorCallback& error_callback) override {
|
| + NOTIMPLEMENTED();
|
| + }
|
| + void SetProperties(
|
| + const std::string& service_path,
|
| + const base::DictionaryValue& user_settings,
|
| + const base::Closure& callback,
|
| + const ErrorCallback& error_callback) const override {
|
| + NOTIMPLEMENTED();
|
| + }
|
| + void CreateConfiguration(
|
| + const std::string& userhash,
|
| + const base::DictionaryValue& properties,
|
| + const StringResultCallback& callback,
|
| + const ErrorCallback& error_callback) const override {
|
| + NOTIMPLEMENTED();
|
| + }
|
| + void RemoveConfiguration(
|
| + const std::string& service_path,
|
| + const base::Closure& callback,
|
| + const ErrorCallback& error_callback) const override {
|
| + NOTIMPLEMENTED();
|
| + }
|
| + void SetPolicy(
|
| + ::onc::ONCSource onc_source,
|
| + const std::string& userhash,
|
| + const base::ListValue& network_configs_onc,
|
| + const base::DictionaryValue& global_network_config) override {
|
| + NOTIMPLEMENTED();
|
| + }
|
| + bool IsAnyPolicyApplicationRunning() const override {
|
| + NOTIMPLEMENTED();
|
| + return false;
|
| + }
|
| + const base::DictionaryValue* FindPolicyByGUID(
|
| + const std::string userhash,
|
| + const std::string& guid,
|
| + ::onc::ONCSource* onc_source) const override {
|
| + if (userhash == "" &&
|
| + device_policy_network_guids_.find(guid) !=
|
| + device_policy_network_guids_.end())
|
| + return &dummy_dictionary_;
|
| +
|
| + if (userhash != "" &&
|
| + user_policy_network_guids_.find(guid) !=
|
| + user_policy_network_guids_.end())
|
| + return &dummy_dictionary_;
|
| +
|
| + return nullptr;
|
| + }
|
| + const GuidToPolicyMap* GetNetworkConfigsFromPolicy(
|
| + const std::string& userhash) const override {
|
| + NOTIMPLEMENTED();
|
| + return nullptr;
|
| + }
|
| + const base::DictionaryValue* GetGlobalConfigFromPolicy(
|
| + const std::string& userhash) const override {
|
| + NOTIMPLEMENTED();
|
| + return nullptr;
|
| + }
|
| + const base::DictionaryValue* FindPolicyByGuidAndProfile(
|
| + const std::string& guid,
|
| + const std::string& profile_path) const override {
|
| + NOTIMPLEMENTED();
|
| + return nullptr;
|
| + }
|
| +
|
| + // XXX doc
|
| + void AddToDevicePolicyNetworks(const std::string& guid) {
|
| + device_policy_network_guids_.insert(guid);
|
| + }
|
| +
|
| + // XXX doc
|
| + void AddToUserPolicyNetworks(const std::string& userhash,
|
| + const std::string& guid) {
|
| + CHECK(userhash_.empty() || userhash_ == userhash)
|
| + << "The fake only supports one user";
|
| + CHECK(!userhash.empty());
|
| + user_policy_network_guids_.insert(guid);
|
| + userhash_ = userhash;
|
| + }
|
| +
|
| + private:
|
| + // XXX doc
|
| + const base::DictionaryValue dummy_dictionary_;
|
| + std::set<std::string> device_policy_network_guids_;
|
| + std::set<std::string> user_policy_network_guids_;
|
| + std::string userhash_;
|
| +};
|
| +
|
| +class TestNetworkStateHandler : public chromeos::NetworkStateHandler {
|
| + public:
|
| + // XXX doc
|
| + void AddNetwork(
|
| + const std::string& service_path,
|
| + const base::DictionaryValue& service_properties) {
|
| + AddToKnownNetworks(service_path);
|
| + UpdateManagedStateProperties(
|
| + chromeos::ManagedState::MANAGED_TYPE_NETWORK,
|
| + service_path, service_properties);
|
| + }
|
| +
|
| + // XXX doc
|
| + void UpdateConnectionState(
|
| + const std::string& service_path,
|
| + const std::string& new_connection_state) {
|
| + base::DictionaryValue changed_properties;
|
| + changed_properties.SetStringWithoutPathExpansion(
|
| + shill::kStateProperty, new_connection_state);
|
| + UpdateManagedStateProperties(
|
| + chromeos::ManagedState::MANAGED_TYPE_NETWORK,
|
| + service_path, changed_properties);
|
| + }
|
| +
|
| + private:
|
| + // XXX doc
|
| + void AddToKnownNetworks(const std::string& network_path) {
|
| + known_network_paths_.push_back(network_path);
|
| + base::ListValue known_networks_list_value;
|
| + known_networks_list_value.AppendStrings(known_network_paths_);
|
| + UpdateManagedList(chromeos::ManagedState::MANAGED_TYPE_NETWORK,
|
| + known_networks_list_value);
|
| + }
|
| +
|
| + std::vector<std::string> known_network_paths_; // XXX doc
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class WifiConfigObserverChromeOsTest : public testing::Test {
|
| + protected:
|
| + WifiConfigObserverChromeOsTest() {
|
| + network_state_handler_.reset(
|
| + new TestNetworkStateHandler());
|
| + network_configuration_handler_.reset(
|
| + chromeos::NetworkConfigurationHandler::InitializeForTest(
|
| + network_state_handler_.get(),
|
| + nullptr /* network_device_handler */));
|
| + config_observer_.reset(
|
| + new WifiConfigObserverChromeOs(
|
| + kUserHash,
|
| + &managed_network_configuration_handler_,
|
| + network_configuration_handler_.get(),
|
| + network_state_handler_.get()));
|
| + }
|
| +
|
| + // XXX consider nuking. (we no longer initialize DBusThreadManager)
|
| + ~WifiConfigObserverChromeOsTest() override {
|
| + // We can't leave resetting these scoped_ptrs to the default dtor,
|
| + // because a) we need to shut down DBusThreadManager, and b) the
|
| + // objects managed by the scoped_ptrs depend on DBusThreadManager
|
| + // (either directly, or transitively).
|
| + config_observer_.reset();
|
| + network_configuration_handler_.reset();
|
| + network_state_handler_.reset();
|
| + }
|
| +
|
| + // Wrappers for WifiConfigObserver methods.
|
| + void StartSyncing() {
|
| + // XXX hdr?
|
| + config_observer_->StartSyncing(base::AsWeakPtr(&syncable_service_));
|
| + }
|
| + void StopSyncing() {
|
| + config_observer_->StopSyncing();
|
| + }
|
| + void OnConfigurationCreated(
|
| + const std::string& service_path,
|
| + const base::DictionaryValue& properties,
|
| + chromeos::NetworkConfigurationObserver::Source source) {
|
| + config_observer_->OnConfigurationCreated(
|
| + service_path, kProfilePath, properties, source);
|
| + }
|
| + void OnConfigurationProfileChanged(
|
| + const std::string& service_path,
|
| + const std::string& profile_path,
|
| + chromeos::NetworkConfigurationObserver::Source source) {
|
| + config_observer_->OnConfigurationProfileChanged(
|
| + service_path, profile_path, source);
|
| + }
|
| + void OnPropertiesSet(
|
| + const std::string& service_path,
|
| + const std::string& guid,
|
| + const base::DictionaryValue& properties,
|
| + chromeos::NetworkConfigurationObserver::Source source) {
|
| + config_observer_->OnPropertiesSet(
|
| + service_path, guid, properties, source);
|
| + // XXX strictly speaking, this should update NetworkStateHandler's
|
| + // state too, no? but we can get away with this cheat, because the
|
| + // only thing WCOCO reads out of NetworkState is the GUID.
|
| + }
|
| + // XXX merge in MakeNetworkState?
|
| + void NetworkConnectionStateChanged(
|
| + chromeos::NetworkState* network, const std::string& new_state) {
|
| + network->PropertyChanged(
|
| + shill::kStateProperty, base::StringValue(new_state));
|
| + config_observer_->NetworkConnectionStateChanged(network);
|
| + }
|
| +
|
| + scoped_ptr<base::DictionaryValue> MakeCommonServiceProperties(
|
| + const std::string& guid) {
|
| + scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue());
|
| + CHECK(properties);
|
| + const std::string ssid(kSsid); // XXX factor out?
|
| + properties->SetStringWithoutPathExpansion(
|
| + shill::kTypeProperty, shill::kTypeWifi);
|
| + properties->SetStringWithoutPathExpansion(
|
| + shill::kWifiHexSsid, base::HexEncode(ssid.data(), ssid.size()));
|
| + properties->SetStringWithoutPathExpansion(shill::kGuidProperty, guid);
|
| + return properties;
|
| + }
|
| +
|
| + scoped_ptr<base::DictionaryValue> Make8021XServiceProperties(
|
| + const std::string& guid) {
|
| + scoped_ptr<base::DictionaryValue> properties(
|
| + MakeCommonServiceProperties(guid));
|
| + properties->SetStringWithoutPathExpansion(
|
| + shill::kSecurityClassProperty, shill::kSecurity8021x);
|
| + return properties;
|
| + }
|
| +
|
| + // XXX doc. properties that would be passed by NCH to OnConfigurationCreated.
|
| + scoped_ptr<base::DictionaryValue> MakeOpenServiceProperties(
|
| + const std::string& guid) {
|
| + scoped_ptr<base::DictionaryValue> properties(
|
| + MakeCommonServiceProperties(guid));
|
| + properties->SetStringWithoutPathExpansion(
|
| + shill::kSecurityClassProperty, shill::kSecurityNone);
|
| + return properties;
|
| + }
|
| +
|
| + // XXX doc. properties that would be passed by NCH to OnConfigurationCreated.
|
| + scoped_ptr<base::DictionaryValue> MakePskServiceProperties(
|
| + const std::string& guid) {
|
| + scoped_ptr<base::DictionaryValue> properties(
|
| + MakeCommonServiceProperties(guid));
|
| + properties->SetStringWithoutPathExpansion(
|
| + shill::kSecurityClassProperty, shill::kSecurityPsk);
|
| + properties->SetStringWithoutPathExpansion(
|
| + shill::kPassphraseProperty, kPassphrasePsk); // XXX factor out?
|
| + return properties;
|
| + }
|
| +
|
| + // XXX doc. properties that would be passed by NCH to OnConfigurationCreated.
|
| + scoped_ptr<base::DictionaryValue> MakeWepServiceProperties(
|
| + const std::string& guid) {
|
| + scoped_ptr<base::DictionaryValue> properties(
|
| + MakeCommonServiceProperties(guid));
|
| + properties->SetStringWithoutPathExpansion(
|
| + shill::kSecurityClassProperty, shill::kSecurityWep);
|
| + properties->SetStringWithoutPathExpansion(
|
| + shill::kPassphraseProperty, kPassphraseWep); // XXX factor out?
|
| + return properties;
|
| + }
|
| +
|
| + // XXX document.
|
| + scoped_ptr<chromeos::NetworkState> MakeNetworkState(
|
| + const std::string& service_path,
|
| + const base::DictionaryValue& service_properties) {
|
| + // XXX don't return NetworkState
|
| + scoped_ptr<chromeos::NetworkState> network_state(
|
| + new chromeos::NetworkState(service_path));
|
| + CHECK(network_state);
|
| + network_state->PropertyChanged(shill::kVisibleProperty,
|
| + base::FundamentalValue(true));
|
| + for (base::DictionaryValue::Iterator it(service_properties);
|
| + !it.IsAtEnd(); it.Advance()) {
|
| + if (it.key() == shill::kPassphraseProperty)
|
| + continue; // Shill doesn't echo back the passphrase.
|
| + network_state->PropertyChanged(it.key(), it.value());
|
| + }
|
| + network_state->InitialPropertiesReceived(service_properties);
|
| + scoped_ptr<base::DictionaryValue> filtered_properties(
|
| + service_properties.DeepCopyWithoutEmptyChildren());
|
| + // Remove passphrase, since Shill doesn't echo it back.
|
| + filtered_properties->Remove(shill::kPassphraseProperty, nullptr);
|
| + network_state_handler_->AddNetwork(service_path, *filtered_properties);
|
| + return network_state;
|
| + }
|
| +
|
| + // XXX document.
|
| + void RegisterNetwork(
|
| + const std::string& service_path,
|
| + const base::DictionaryValue& service_properties) {
|
| + scoped_ptr<base::DictionaryValue> filtered_properties(
|
| + service_properties.DeepCopyWithoutEmptyChildren());
|
| + // Remove passphrase, since Shill doesn't echo it back.
|
| + filtered_properties->Remove(shill::kPassphraseProperty, nullptr);
|
| + // Add the visible property, as Shill would.
|
| + filtered_properties->SetBooleanWithoutPathExpansion(
|
| + shill::kVisibleProperty, true);
|
| + network_state_handler_->AddNetwork(service_path, *filtered_properties);
|
| + }
|
| +
|
| + // XXX doc
|
| + void SetNetworkPassphrase(
|
| + const std::string& service_path,
|
| + const std::string& service_guid,
|
| + const std::string& passphrase) {
|
| + base::DictionaryValue properties;
|
| + properties.SetStringWithoutPathExpansion(
|
| + shill::kPassphraseProperty, passphrase);
|
| + OnPropertiesSet(
|
| + service_path, service_guid, properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + }
|
| +
|
| + // XXX doc
|
| + void UpdateConnectionState(
|
| + const std::string& service_path,
|
| + const std::string& new_connection_state) {
|
| + network_state_handler_->UpdateConnectionState(
|
| + service_path, new_connection_state);
|
| + }
|
| +
|
| + // XXX doc
|
| + void AddToDevicePolicyNetworks(const std::string& guid) {
|
| + managed_network_configuration_handler_.AddToDevicePolicyNetworks(guid);
|
| + }
|
| +
|
| + void AddToUserPolicyNetworks(const std::string& guid) {
|
| + managed_network_configuration_handler_.AddToUserPolicyNetworks(
|
| + kUserHash, guid);
|
| + }
|
| +
|
| + // XXX doc
|
| + size_t add_to_synced_networks_call_count() const {
|
| + return syncable_service_.add_to_synced_networks_call_count();
|
| + }
|
| +
|
| + // XXX doc
|
| + std::string syncable_service_last_passphrase() const {
|
| + return syncable_service_.last_passphrase();
|
| + }
|
| +
|
| + private:
|
| + static const char kSsid[];
|
| +
|
| + base::MessageLoopForUI message_loop_; // For NetworkStateHandler.
|
| + FakeManagedNetworkConfigurationHandler managed_network_configuration_handler_;
|
| + scoped_ptr<TestNetworkStateHandler> network_state_handler_;
|
| + scoped_ptr<chromeos::NetworkConfigurationHandler>
|
| + network_configuration_handler_;
|
| + scoped_ptr<WifiConfigObserverChromeOs> config_observer_;
|
| + FakeWifiCredentialSyncableService syncable_service_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(WifiConfigObserverChromeOsTest);
|
| +};
|
| +
|
| +const char WifiConfigObserverChromeOsTest::kSsid[] = "fake-ssid";
|
| +
|
| +// Success tests for networks found in scan results. (These are the
|
| +// most common cases.)
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, FromScan_SyncNewOpenNetwork) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakeOpenServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, FromScan_SyncNewWepNetwork) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakeWepServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphraseWep);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, FromScan_SyncNewPskNetwork) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphrasePsk);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + FromScan_SyncNewPskNetworkWithOtherSettingChanges) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphrasePsk);
|
| +
|
| + base::DictionaryValue new_properties;
|
| + new_properties.SetBooleanWithoutPathExpansion(shill::kWifiHiddenSsid, true);
|
| + OnPropertiesSet(kServicePath, kServiceGuid, new_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| +
|
| + // Changing a non-passphrase property shouldn't wipe out the
|
| + // passphrase. So this network should still sync.
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, FromScan_SyncChangedPskPassphrase) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| +
|
| + std::string new_passphrase = base::StringPrintf("not-%s", kPassphrasePsk);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, new_passphrase);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + // OnConfigurationProfileChanged() omitted when updating an existing network.
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| + EXPECT_EQ(new_passphrase, syncable_service_last_passphrase());
|
| +}
|
| +
|
| +// Test of manually configured networks. These are created via the
|
| +// "Join other..." dialog. Users will generally only do this for
|
| +// hidden networks.
|
| +
|
| +// XXX should these continue using MakeNetworkState and
|
| +// NetworkConnectionStateChanged?
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, ManualConfig_SyncOpenNetwork) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakeOpenServiceProperties(kServiceGuid);
|
| + OnConfigurationCreated(
|
| + kServicePath, *service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, ManualConfig_SyncWepNetwork) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakeWepServiceProperties(kServiceGuid);
|
| + OnConfigurationCreated(
|
| + kServicePath, *service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, ManualConfig_SyncPskNetwork) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + OnConfigurationCreated(
|
| + kServicePath, *service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + ManualConfig_SyncLatestPassphraseWhenChangedAfterCreation) {
|
| + StartSyncing();
|
| +
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + OnConfigurationCreated(
|
| + kServicePath, *service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| +
|
| + const std::string new_passphrase =
|
| + base::StringPrintf("not-%s", kPassphrasePsk);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, new_passphrase);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| + EXPECT_EQ(new_passphrase, syncable_service_last_passphrase());
|
| +}
|
| +
|
| +// Tests of network connection state handling. "Normal" tests, such as
|
| +// SyncNewPskNetworkFromScan, exercise shill::kStateOnline. The tests
|
| +// in the group below check behavior for other network connection states.
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, ConnectionState_DoNotSyncAtAssociation) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphrasePsk);
|
| + UpdateConnectionState(kServicePath, shill::kStateAssociation);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, ConnectionState_SyncAtPortal) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphrasePsk);
|
| + UpdateConnectionState(kServicePath, shill::kStatePortal);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + // kStatePortal means that the network layer is up (we have an IP
|
| + // address), but we don't have Internet connectivity. We should still
|
| + // sync the network, because, if the network layer is up, then so is
|
| + // the link layer.
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, ConnectionState_SyncAtReady) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphrasePsk);
|
| + UpdateConnectionState(kServicePath, shill::kStateReady);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + // kStateReady means that the network layer is up (we have an IP
|
| + // address), but we haven't tested Internet connectivity. If the
|
| + // network layer is up, the link layer must be up. So go ahead and
|
| + // sync. (We could wait until reaching kStatePortal, or
|
| + // kStateOnline. But triggering on kStateReady lets us get started
|
| + // earlier, in some cases.)
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +// Tests for configurations which should not be synced. Note that
|
| +// "negative" tests related to NetworkConfigurationObserver::Source
|
| +// are grouped separately.
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + BadConfig_OpenNetworkWithoutUserActionIsNotSent) {
|
| + StartSyncing();
|
| +
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakeOpenServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + // OnConfigurationProfileChanged() not called for autoconnect.
|
| +
|
| + // While we have sufficient information to sync this network, we
|
| + // shouldn't do so. The reason is that the user hasn't explicitly
|
| + // indicated that they trust this network. (The user might, e.g., be
|
| + // using a friend's device. That friend may trust SketchyOpenWifi,
|
| + // but we don't want to assume the user does as well.)
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + BadConfig_PskNetworkWithoutPassphraseIsNotSent) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + service_properties->RemoveWithoutPathExpansion(
|
| + shill::kPassphraseProperty, nullptr);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + // Assume the upper layers forgot to call OnPropertiesSet().
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, BadConfig_8021XNetworkIsNotSent) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakeCommonServiceProperties(kServiceGuid);
|
| + service_properties->SetStringWithoutPathExpansion(
|
| + shill::kSecurityClassProperty, shill::kSecurity8021x);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, BadConfig_NonWifiNetworkIsNotSent) {
|
| + StartSyncing();
|
| + base::DictionaryValue service_properties;
|
| + service_properties.SetStringWithoutPathExpansion(
|
| + shill::kTypeProperty, shill::kTypeEthernet);
|
| + service_properties.SetStringWithoutPathExpansion(
|
| + shill::kGuidProperty, kServiceGuid);
|
| + RegisterNetwork(kServicePath, service_properties);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +// XXX group name
|
| +// XXX revisit this group
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, PolicyCreatedNetworkNotSent) {
|
| + StartSyncing();
|
| +
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + AddToDevicePolicyNetworks(kServiceGuid);
|
| + OnConfigurationCreated(
|
| + kServicePath, *service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_POLICY);
|
| + NetworkConnectionStateChanged(
|
| + MakeNetworkState(kServicePath, *service_properties).get(),
|
| + shill::kStateOnline);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + PolicyCreatedUserUpdatedNetworkNotSent) {
|
| + StartSyncing();
|
| +
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + OnConfigurationCreated(
|
| + kServicePath, *service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_POLICY);
|
| + AddToDevicePolicyNetworks(kServiceGuid);
|
| +
|
| + base::DictionaryValue new_properties;
|
| + new_properties.SetStringWithoutPathExpansion(
|
| + shill::kPassphraseProperty, "new-psk-passphrase-via-policy");
|
| + OnPropertiesSet(kServicePath, kServiceGuid, new_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + new_properties.MergeDictionary(service_properties.get());
|
| + NetworkConnectionStateChanged(
|
| + MakeNetworkState(kServicePath, new_properties).get(),
|
| + shill::kStateOnline);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, UserCreatedPolicyUpdatedNetworkNotSent) {
|
| + StartSyncing();
|
| +
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + OnConfigurationCreated(
|
| + kServicePath, *service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| +
|
| + base::DictionaryValue new_properties;
|
| + new_properties.SetStringWithoutPathExpansion(
|
| + shill::kPassphraseProperty, "new-psk-passphrase-via-policy");
|
| + OnPropertiesSet(kServicePath, kServiceGuid, new_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_POLICY);
|
| + new_properties.MergeDictionary(service_properties.get());
|
| + NetworkConnectionStateChanged(
|
| + MakeNetworkState(kServicePath, new_properties).get(),
|
| + shill::kStateOnline);
|
| + // We can't take the new passphrase, because it didn't come from the
|
| + // user. And we can't take the old passphrase, because we don't know
|
| + // if it works. (The successful connection may have been due to the
|
| + // new passphrase.) Hence, we should not sync this network at all.
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +// XXX test for bad source on ConfigurationProfileChange
|
| +// XXX test with extension source
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + DevicePolicyOwnedUserUpdatedNetworkNotSent) {
|
| + StartSyncing();
|
| + // No call to OnConfigurationCreated, because this network was
|
| + // loaded from persistent settings.
|
| + AddToDevicePolicyNetworks(kServiceGuid);
|
| +
|
| + base::DictionaryValue new_properties;
|
| + new_properties.SetStringWithoutPathExpansion(
|
| + shill::kPassphraseProperty, "new-psk-passphrase-by-user");
|
| + OnPropertiesSet(kServicePath, kServiceGuid, new_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + new_properties.MergeDictionary(MakePskServiceProperties(kServiceGuid).get());
|
| + NetworkConnectionStateChanged(
|
| + MakeNetworkState(kServicePath, new_properties).get(),
|
| + shill::kStateOnline);
|
| +
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + UserPolicyOwnedUserUpdatedNetworkNotSent) {
|
| + StartSyncing();
|
| + // No call to OnConfigurationCreated, because this network was
|
| + // loaded from persistent settings.
|
| + AddToUserPolicyNetworks(kServiceGuid);
|
| +
|
| + base::DictionaryValue new_properties;
|
| + new_properties.SetStringWithoutPathExpansion(
|
| + shill::kPassphraseProperty, "new-psk-passphrase-by-user");
|
| + OnPropertiesSet(kServicePath, kServiceGuid, new_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + new_properties.MergeDictionary(MakePskServiceProperties(kServiceGuid).get());
|
| + NetworkConnectionStateChanged(
|
| + MakeNetworkState(kServicePath, new_properties).get(),
|
| + shill::kStateOnline);
|
| +
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +// XXX create a group name?
|
| +// XXX maybe merge with next, using OnConfigurationCreated for policy,
|
| +// and OnPropertiesSet/OnConfigurationProfileChanged for user.
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + SyncOnNonConflictingUserAndPolicyConfigs) {
|
| + StartSyncing();
|
| +
|
| + scoped_ptr<base::DictionaryValue> user_service_properties =
|
| + MakeOpenServiceProperties(kServiceGuid);
|
| + OnConfigurationCreated(
|
| + kServicePath, *user_service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| +
|
| + scoped_ptr<base::DictionaryValue> policy_service_properties =
|
| + MakeOpenServiceProperties(kService2Guid);
|
| + AddToDevicePolicyNetworks(kService2Guid);
|
| + OnConfigurationCreated(
|
| + kService2Path, *policy_service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_POLICY);
|
| +
|
| + NetworkConnectionStateChanged(
|
| + MakeNetworkState(kServicePath, *user_service_properties).get(),
|
| + shill::kStateOnline);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + SyncOnNonConflictingUserAndPolicyChanges) {
|
| + StartSyncing();
|
| +
|
| + base::DictionaryValue new_user_service_properties;
|
| + new_user_service_properties.SetStringWithoutPathExpansion(
|
| + shill::kPassphraseProperty, kPassphrasePsk);
|
| + OnPropertiesSet(kServicePath, kServiceGuid, new_user_service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| +
|
| + base::DictionaryValue new_policy_service_properties;
|
| + new_policy_service_properties.SetStringWithoutPathExpansion(
|
| + shill::kPassphraseProperty, kPassphraseWep);
|
| + AddToDevicePolicyNetworks(kService2Guid);
|
| + OnPropertiesSet(kService2Path, kService2Guid, new_policy_service_properties,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_POLICY);
|
| +
|
| + NetworkConnectionStateChanged(
|
| + MakeNetworkState(kServicePath,
|
| + *MakePskServiceProperties(kServiceGuid)).get(),
|
| + shill::kStateOnline);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +// Tests of our Start/Stop behavior.
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, StartStop_StartSendsQueuedCredentials) {
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphrasePsk);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +
|
| + StartSyncing();
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, StartStop_StopPreventsSend) {
|
| + StartSyncing();
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphrasePsk);
|
| + StopSyncing();
|
| +
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest, StartStop_RestartDoesNotResend) {
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakeOpenServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + OnConfigurationProfileChanged(
|
| + kServicePath, kProfilePath,
|
| + chromeos::NetworkConfigurationObserver::SOURCE_USER_ACTION);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +
|
| + StartSyncing();
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +
|
| + StopSyncing();
|
| + StartSyncing();
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +// Tests related to the connection manager ("Shill") restarting.
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + ShillRestart_ServicePathReuseDoesNotCauseSpuriousSync) {
|
| + StartSyncing();
|
| +
|
| + scoped_ptr<base::DictionaryValue> service_a_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_a_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphrasePsk);
|
| +
|
| + // Due to Shill restarting, a later network gets assigned the same
|
| + // service path.
|
| + scoped_ptr<base::DictionaryValue> service_b_properties =
|
| + MakeWepServiceProperties(kService2Guid);
|
| + RegisterNetwork(kServicePath, *service_b_properties);
|
| + // Don't SetNetworkPassphrase(), as that might cause service B to be
|
| + // synced.
|
| +
|
| + // Since service A has not connected, and service B was already
|
| + // configured, there is nothing for us to sync.
|
| + UpdateConnectionState(kServicePath, shill::kStateOnline);
|
| + EXPECT_EQ(0U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +TEST_F(WifiConfigObserverChromeOsTest,
|
| + ShillRestart_SyncDespiteServicePathChange) {
|
| + StartSyncing();
|
| +
|
| + scoped_ptr<base::DictionaryValue> service_properties =
|
| + MakePskServiceProperties(kServiceGuid);
|
| + RegisterNetwork(kServicePath, *service_properties);
|
| + SetNetworkPassphrase(kServicePath, kServiceGuid, kPassphrasePsk);
|
| +
|
| + // Shill has restarted, and assigned our service a different service
|
| + // path. We shouldn't let that get in the way of syncing the
|
| + // network.
|
| + RegisterNetwork(kService2Path, *service_properties);
|
| + UpdateConnectionState(kService2Path, shill::kStateOnline);
|
| + EXPECT_EQ(1U, add_to_synced_networks_call_count());
|
| +}
|
| +
|
| +// XXX not tested: user changes passphrase while connection is in
|
| +// progress, and old connection attempt succeeds.
|
| +
|
| +// XXX No test for case where passphrase is supplied after
|
| +// connect. Behavior is undefined in that case.
|
| +
|
| +} // namespace wifi_sync
|
|
|