Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Unified Diff: components/wifi_sync/wifi_config_observer_chromeos_unittest.cc

Issue 1426393003: NOT FOR REVIEW Base URL: https://chromium.googlesource.com/chromium/src.git@submit-4.5-split-wcss
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
« no previous file with comments | « components/wifi_sync/wifi_config_observer_chromeos.cc ('k') | components/wifi_sync/wifi_credential_syncable_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698