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