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