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