device_settings_provider_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/settings/device_settings_provider.h" 6 7#include <string> 8 9#include "base/bind.h" 10#include "base/callback.h" 11#include "base/file_util.h" 12#include "base/path_service.h" 13#include "base/test/scoped_path_override.h" 14#include "base/values.h" 15#include "chrome/browser/chromeos/cros/cros_library.h" 16#include "chrome/browser/chromeos/policy/device_local_account.h" 17#include "chrome/browser/chromeos/settings/cros_settings_names.h" 18#include "chrome/browser/chromeos/settings/device_settings_test_helper.h" 19#include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" 20#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" 21#include "chrome/common/chrome_paths.h" 22#include "chrome/test/base/scoped_testing_local_state.h" 23#include "chrome/test/base/testing_browser_process.h" 24#include "testing/gmock/include/gmock/gmock.h" 25#include "testing/gtest/include/gtest/gtest.h" 26 27namespace em = enterprise_management; 28 29namespace chromeos { 30 31using ::testing::AnyNumber; 32using ::testing::Mock; 33using ::testing::_; 34 35class DeviceSettingsProviderTest : public DeviceSettingsTestBase { 36 public: 37 MOCK_METHOD1(SettingChanged, void(const std::string&)); 38 MOCK_METHOD0(GetTrustedCallback, void(void)); 39 40 protected: 41 DeviceSettingsProviderTest() 42 : local_state_(TestingBrowserProcess::GetGlobal()), 43 user_data_dir_override_(chrome::DIR_USER_DATA) {} 44 45 virtual void SetUp() OVERRIDE { 46 DeviceSettingsTestBase::SetUp(); 47 48 EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber()); 49 provider_.reset( 50 new DeviceSettingsProvider( 51 base::Bind(&DeviceSettingsProviderTest::SettingChanged, 52 base::Unretained(this)), 53 &device_settings_service_)); 54 Mock::VerifyAndClearExpectations(this); 55 } 56 57 virtual void TearDown() OVERRIDE { 58 DeviceSettingsTestBase::TearDown(); 59 } 60 61 ScopedStubCrosEnabler stub_cros_enabler_; 62 63 ScopedTestingLocalState local_state_; 64 65 scoped_ptr<DeviceSettingsProvider> provider_; 66 67 base::ScopedPathOverride user_data_dir_override_; 68 69 private: 70 DISALLOW_COPY_AND_ASSIGN(DeviceSettingsProviderTest); 71}; 72 73TEST_F(DeviceSettingsProviderTest, InitializationTest) { 74 // Have the service load a settings blob. 75 EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber()); 76 ReloadDeviceSettings(); 77 Mock::VerifyAndClearExpectations(this); 78 79 // Verify that the policy blob has been correctly parsed and trusted. 80 // The trusted flag should be set before the call to PrepareTrustedValues. 81 EXPECT_EQ(CrosSettingsProvider::TRUSTED, 82 provider_->PrepareTrustedValues(base::Closure())); 83 const base::Value* value = provider_->Get(kStatsReportingPref); 84 ASSERT_TRUE(value); 85 bool bool_value; 86 EXPECT_TRUE(value->GetAsBoolean(&bool_value)); 87 EXPECT_FALSE(bool_value); 88} 89 90TEST_F(DeviceSettingsProviderTest, InitializationTestUnowned) { 91 // Have the service check the key. 92 owner_key_util_->Clear(); 93 ReloadDeviceSettings(); 94 95 // The trusted flag should be set before the call to PrepareTrustedValues. 96 EXPECT_EQ(CrosSettingsProvider::TRUSTED, 97 provider_->PrepareTrustedValues(base::Closure())); 98 const base::Value* value = provider_->Get(kReleaseChannel); 99 ASSERT_TRUE(value); 100 std::string string_value; 101 EXPECT_TRUE(value->GetAsString(&string_value)); 102 EXPECT_TRUE(string_value.empty()); 103 104 // Sets should succeed though and be readable from the cache. 105 EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber()); 106 EXPECT_CALL(*this, SettingChanged(kReleaseChannel)).Times(1); 107 base::StringValue new_value("stable-channel"); 108 provider_->Set(kReleaseChannel, new_value); 109 Mock::VerifyAndClearExpectations(this); 110 111 // This shouldn't trigger a write. 112 device_settings_test_helper_.set_policy_blob(std::string()); 113 FlushDeviceSettings(); 114 EXPECT_EQ(std::string(), device_settings_test_helper_.policy_blob()); 115 116 // Verify the change has been applied. 117 const base::Value* saved_value = provider_->Get(kReleaseChannel); 118 ASSERT_TRUE(saved_value); 119 EXPECT_TRUE(saved_value->GetAsString(&string_value)); 120 ASSERT_EQ("stable-channel", string_value); 121} 122 123TEST_F(DeviceSettingsProviderTest, SetPrefFailed) { 124 // If we are not the owner no sets should work. 125 base::FundamentalValue value(true); 126 EXPECT_CALL(*this, SettingChanged(kStatsReportingPref)).Times(1); 127 provider_->Set(kStatsReportingPref, value); 128 Mock::VerifyAndClearExpectations(this); 129 130 // This shouldn't trigger a write. 131 device_settings_test_helper_.set_policy_blob(std::string()); 132 FlushDeviceSettings(); 133 EXPECT_EQ(std::string(), device_settings_test_helper_.policy_blob()); 134 135 // Verify the change has not been applied. 136 const base::Value* saved_value = provider_->Get(kStatsReportingPref); 137 ASSERT_TRUE(saved_value); 138 bool bool_value; 139 EXPECT_TRUE(saved_value->GetAsBoolean(&bool_value)); 140 EXPECT_FALSE(bool_value); 141} 142 143TEST_F(DeviceSettingsProviderTest, SetPrefSucceed) { 144 owner_key_util_->SetPrivateKey(device_policy_.signing_key()); 145 device_settings_service_.SetUsername(device_policy_.policy_data().username()); 146 FlushDeviceSettings(); 147 148 base::FundamentalValue value(true); 149 EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber()); 150 EXPECT_CALL(*this, SettingChanged(kStatsReportingPref)).Times(1); 151 provider_->Set(kStatsReportingPref, value); 152 Mock::VerifyAndClearExpectations(this); 153 154 // Process the store. 155 device_settings_test_helper_.set_policy_blob(std::string()); 156 FlushDeviceSettings(); 157 158 // Verify that the device policy has been adjusted. 159 ASSERT_TRUE(device_settings_service_.device_settings()); 160 EXPECT_TRUE(device_settings_service_.device_settings()-> 161 metrics_enabled().metrics_enabled()); 162 163 // Verify the change has been applied. 164 const base::Value* saved_value = provider_->Get(kStatsReportingPref); 165 ASSERT_TRUE(saved_value); 166 bool bool_value; 167 EXPECT_TRUE(saved_value->GetAsBoolean(&bool_value)); 168 EXPECT_TRUE(bool_value); 169} 170 171TEST_F(DeviceSettingsProviderTest, SetPrefTwice) { 172 owner_key_util_->SetPrivateKey(device_policy_.signing_key()); 173 device_settings_service_.SetUsername(device_policy_.policy_data().username()); 174 FlushDeviceSettings(); 175 176 EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber()); 177 178 base::StringValue value1("beta"); 179 provider_->Set(kReleaseChannel, value1); 180 base::StringValue value2("dev"); 181 provider_->Set(kReleaseChannel, value2); 182 183 // Let the changes propagate through the system. 184 device_settings_test_helper_.set_policy_blob(std::string()); 185 FlushDeviceSettings(); 186 187 // Verify the second change has been applied. 188 const base::Value* saved_value = provider_->Get(kReleaseChannel); 189 EXPECT_TRUE(value2.Equals(saved_value)); 190 191 Mock::VerifyAndClearExpectations(this); 192} 193 194TEST_F(DeviceSettingsProviderTest, PolicyRetrievalFailedBadSignature) { 195 owner_key_util_->SetPublicKeyFromPrivateKey(device_policy_.signing_key()); 196 device_policy_.policy().set_policy_data_signature("bad signature"); 197 device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); 198 ReloadDeviceSettings(); 199 200 // Verify that the cached settings blob is not "trusted". 201 EXPECT_EQ(DeviceSettingsService::STORE_VALIDATION_ERROR, 202 device_settings_service_.status()); 203 EXPECT_EQ(CrosSettingsProvider::PERMANENTLY_UNTRUSTED, 204 provider_->PrepareTrustedValues(base::Closure())); 205} 206 207TEST_F(DeviceSettingsProviderTest, PolicyRetrievalNoPolicy) { 208 owner_key_util_->SetPublicKeyFromPrivateKey(device_policy_.signing_key()); 209 device_settings_test_helper_.set_policy_blob(std::string()); 210 ReloadDeviceSettings(); 211 212 // Verify that the cached settings blob is not "trusted". 213 EXPECT_EQ(DeviceSettingsService::STORE_NO_POLICY, 214 device_settings_service_.status()); 215 EXPECT_EQ(CrosSettingsProvider::PERMANENTLY_UNTRUSTED, 216 provider_->PrepareTrustedValues(base::Closure())); 217} 218 219TEST_F(DeviceSettingsProviderTest, PolicyFailedPermanentlyNotification) { 220 device_settings_test_helper_.set_policy_blob(std::string()); 221 222 EXPECT_CALL(*this, GetTrustedCallback()); 223 EXPECT_EQ(CrosSettingsProvider::TEMPORARILY_UNTRUSTED, 224 provider_->PrepareTrustedValues( 225 base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback, 226 base::Unretained(this)))); 227 228 ReloadDeviceSettings(); 229 Mock::VerifyAndClearExpectations(this); 230 231 EXPECT_EQ(CrosSettingsProvider::PERMANENTLY_UNTRUSTED, 232 provider_->PrepareTrustedValues(base::Closure())); 233} 234 235TEST_F(DeviceSettingsProviderTest, PolicyLoadNotification) { 236 EXPECT_CALL(*this, GetTrustedCallback()); 237 238 EXPECT_EQ(CrosSettingsProvider::TEMPORARILY_UNTRUSTED, 239 provider_->PrepareTrustedValues( 240 base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback, 241 base::Unretained(this)))); 242 243 ReloadDeviceSettings(); 244 Mock::VerifyAndClearExpectations(this); 245} 246 247TEST_F(DeviceSettingsProviderTest, StatsReportingMigration) { 248 // Create the legacy consent file. 249 base::FilePath consent_file; 250 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &consent_file)); 251 consent_file = consent_file.AppendASCII("Consent To Send Stats"); 252 ASSERT_EQ(1, file_util::WriteFile(consent_file, "0", 1)); 253 254 // This should trigger migration because the metrics policy isn't in the blob. 255 device_settings_test_helper_.set_policy_blob(std::string()); 256 FlushDeviceSettings(); 257 EXPECT_EQ(std::string(), device_settings_test_helper_.policy_blob()); 258 259 // Verify that migration has kicked in. 260 const base::Value* saved_value = provider_->Get(kStatsReportingPref); 261 ASSERT_TRUE(saved_value); 262 bool bool_value; 263 EXPECT_TRUE(saved_value->GetAsBoolean(&bool_value)); 264 EXPECT_FALSE(bool_value); 265} 266 267TEST_F(DeviceSettingsProviderTest, LegacyDeviceLocalAccounts) { 268 EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber()); 269 em::DeviceLocalAccountInfoProto* account = 270 device_policy_.payload().mutable_device_local_accounts()->add_account(); 271 account->set_deprecated_public_session_id( 272 policy::PolicyBuilder::kFakeUsername); 273 device_policy_.Build(); 274 device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); 275 ReloadDeviceSettings(); 276 Mock::VerifyAndClearExpectations(this); 277 278 // On load, the deprecated spec should have been converted to the new format. 279 base::ListValue expected_accounts; 280 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue()); 281 entry_dict->SetString(kAccountsPrefDeviceLocalAccountsKeyId, 282 policy::PolicyBuilder::kFakeUsername); 283 entry_dict->SetInteger(kAccountsPrefDeviceLocalAccountsKeyType, 284 policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION); 285 expected_accounts.Append(entry_dict.release()); 286 const base::Value* actual_accounts = 287 provider_->Get(kAccountsPrefDeviceLocalAccounts); 288 EXPECT_TRUE(base::Value::Equals(&expected_accounts, actual_accounts)); 289} 290 291} // namespace chromeos 292