auto_enrollment_client_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/policy/auto_enrollment_client.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/prefs/pref_service.h"
10#include "base/prefs/testing_pref_service.h"
11#include "base/values.h"
12#include "chrome/browser/browser_process.h"
13#include "chrome/browser/policy/cloud/mock_device_management_service.h"
14#include "chrome/common/pref_names.h"
15#include "chrome/test/base/scoped_testing_local_state.h"
16#include "chrome/test/base/testing_browser_process.h"
17#include "crypto/sha2.h"
18#include "testing/gmock/include/gmock/gmock.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
21namespace em = enterprise_management;
22
23namespace policy {
24
25namespace {
26
27const char* kSerial = "serial";
28const char* kSerialHash =
29    "\x01\x44\xb1\xde\xfc\xf7\x56\x10\x87\x01\x5f\x8d\x83\x0d\x65\xb1"
30    "\x6f\x02\x4a\xd7\xeb\x92\x45\xfc\xd4\xe4\x37\xa1\x55\x2b\x13\x8a";
31
32using ::testing::InSequence;
33using ::testing::SaveArg;
34using ::testing::_;
35
36class AutoEnrollmentClientTest : public testing::Test {
37 protected:
38  AutoEnrollmentClientTest()
39      : scoped_testing_local_state_(
40            TestingBrowserProcess::GetGlobal()),
41        local_state_(scoped_testing_local_state_.Get()),
42        service_(NULL),
43        completion_callback_count_(0) {}
44
45  virtual void SetUp() OVERRIDE {
46    CreateClient(kSerial, 4, 8);
47    ASSERT_FALSE(local_state_->GetUserPref(prefs::kShouldAutoEnroll));
48    ASSERT_FALSE(local_state_->GetUserPref(prefs::kAutoEnrollmentPowerLimit));
49  }
50
51  void CreateClient(const std::string& serial,
52                    int power_initial,
53                    int power_limit) {
54    service_ = new MockDeviceManagementService();
55    EXPECT_CALL(*service_, StartJob(_, _, _, _, _, _, _))
56        .WillRepeatedly(SaveArg<6>(&last_request_));
57    base::Closure callback =
58        base::Bind(&AutoEnrollmentClientTest::CompletionCallback,
59                   base::Unretained(this));
60    client_.reset(new AutoEnrollmentClient(callback,
61                                           service_,
62                                           local_state_,
63                                           serial,
64                                           power_initial,
65                                           power_limit));
66  }
67
68  void CompletionCallback() {
69    completion_callback_count_++;
70  }
71
72  void ServerWillFail(DeviceManagementStatus error) {
73    em::DeviceManagementResponse dummy_response;
74    EXPECT_CALL(*service_,
75                CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT))
76        .WillOnce(service_->FailJob(error));
77  }
78
79  void ServerWillReply(int64 modulus, bool with_hashes, bool with_serial_hash) {
80    em::DeviceManagementResponse response;
81    em::DeviceAutoEnrollmentResponse* enrollment_response =
82        response.mutable_auto_enrollment_response();
83    if (modulus >= 0)
84      enrollment_response->set_expected_modulus(modulus);
85    if (with_hashes) {
86      for (size_t i = 0; i < 10; ++i) {
87        std::string serial = "serial X";
88        serial[7] = '0' + i;
89        std::string hash = crypto::SHA256HashString(serial);
90        enrollment_response->mutable_hash()->Add()->assign(hash);
91      }
92    }
93    if (with_serial_hash) {
94      enrollment_response->mutable_hash()->Add()->assign(kSerialHash,
95                                               crypto::kSHA256Length);
96    }
97    EXPECT_CALL(*service_,
98                CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT))
99        .WillOnce(service_->SucceedJob(response));
100  }
101
102  bool HasCachedDecision() {
103    return local_state_->GetUserPref(prefs::kShouldAutoEnroll);
104  }
105
106  void VerifyCachedResult(bool should_enroll, int power_limit) {
107    base::FundamentalValue value_should_enroll(should_enroll);
108    base::FundamentalValue value_power_limit(power_limit);
109    EXPECT_TRUE(Value::Equals(
110        &value_should_enroll,
111        local_state_->GetUserPref(prefs::kShouldAutoEnroll)));
112    EXPECT_TRUE(Value::Equals(
113        &value_power_limit,
114        local_state_->GetUserPref(prefs::kAutoEnrollmentPowerLimit)));
115  }
116
117  const em::DeviceAutoEnrollmentRequest& auto_enrollment_request() {
118    return last_request_.auto_enrollment_request();
119  }
120
121  ScopedTestingLocalState scoped_testing_local_state_;
122  TestingPrefServiceSimple* local_state_;
123  MockDeviceManagementService* service_;
124  scoped_ptr<AutoEnrollmentClient> client_;
125  em::DeviceManagementRequest last_request_;
126  int completion_callback_count_;
127
128 private:
129  DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentClientTest);
130};
131
132TEST_F(AutoEnrollmentClientTest, NetworkFailure) {
133  ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE);
134  client_->Start();
135  EXPECT_FALSE(client_->should_auto_enroll());
136  EXPECT_EQ(1, completion_callback_count_);
137  EXPECT_FALSE(HasCachedDecision());
138}
139
140TEST_F(AutoEnrollmentClientTest, EmptyReply) {
141  ServerWillReply(-1, false, false);
142  client_->Start();
143  EXPECT_FALSE(client_->should_auto_enroll());
144  EXPECT_EQ(1, completion_callback_count_);
145  VerifyCachedResult(false, 8);
146}
147
148TEST_F(AutoEnrollmentClientTest, ClientUploadsRightBits) {
149  ServerWillReply(-1, false, false);
150  client_->Start();
151  EXPECT_FALSE(client_->should_auto_enroll());
152  EXPECT_EQ(1, completion_callback_count_);
153
154  EXPECT_TRUE(auto_enrollment_request().has_remainder());
155  EXPECT_TRUE(auto_enrollment_request().has_modulus());
156  EXPECT_EQ(16, auto_enrollment_request().modulus());
157  EXPECT_EQ(kSerialHash[31] & 0xf, auto_enrollment_request().remainder());
158  VerifyCachedResult(false, 8);
159}
160
161TEST_F(AutoEnrollmentClientTest, AskForMoreThenFail) {
162  InSequence sequence;
163  ServerWillReply(32, false, false);
164  ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE);
165  client_->Start();
166  EXPECT_FALSE(client_->should_auto_enroll());
167  EXPECT_EQ(1, completion_callback_count_);
168  EXPECT_FALSE(HasCachedDecision());
169}
170
171TEST_F(AutoEnrollmentClientTest, AskForMoreThenEvenMore) {
172  InSequence sequence;
173  ServerWillReply(32, false, false);
174  ServerWillReply(64, false, false);
175  client_->Start();
176  EXPECT_FALSE(client_->should_auto_enroll());
177  EXPECT_EQ(1, completion_callback_count_);
178  EXPECT_FALSE(HasCachedDecision());
179}
180
181TEST_F(AutoEnrollmentClientTest, AskForLess) {
182  InSequence sequence;
183  ServerWillReply(8, false, false);
184  ServerWillReply(-1, true, true);
185  client_->Start();
186  EXPECT_TRUE(client_->should_auto_enroll());
187  EXPECT_EQ(1, completion_callback_count_);
188  VerifyCachedResult(true, 8);
189}
190
191TEST_F(AutoEnrollmentClientTest, AskForSame) {
192  InSequence sequence;
193  ServerWillReply(16, false, false);
194  ServerWillReply(-1, true, true);
195  client_->Start();
196  EXPECT_TRUE(client_->should_auto_enroll());
197  EXPECT_EQ(1, completion_callback_count_);
198  VerifyCachedResult(true, 8);
199}
200
201TEST_F(AutoEnrollmentClientTest, AskForSameTwice) {
202  InSequence sequence;
203  ServerWillReply(16, false, false);
204  ServerWillReply(16, false, false);
205  client_->Start();
206  EXPECT_FALSE(client_->should_auto_enroll());
207  EXPECT_EQ(1, completion_callback_count_);
208  EXPECT_FALSE(HasCachedDecision());
209}
210
211TEST_F(AutoEnrollmentClientTest, AskForTooMuch) {
212  ServerWillReply(512, false, false);
213  client_->Start();
214  EXPECT_FALSE(client_->should_auto_enroll());
215  EXPECT_EQ(1, completion_callback_count_);
216  EXPECT_FALSE(HasCachedDecision());
217}
218
219TEST_F(AutoEnrollmentClientTest, AskNonPowerOf2) {
220  InSequence sequence;
221  ServerWillReply(100, false, false);
222  ServerWillReply(-1, false, false);
223  client_->Start();
224  EXPECT_FALSE(client_->should_auto_enroll());
225  EXPECT_EQ(1, completion_callback_count_);
226  EXPECT_TRUE(auto_enrollment_request().has_remainder());
227  EXPECT_TRUE(auto_enrollment_request().has_modulus());
228  EXPECT_EQ(128, auto_enrollment_request().modulus());
229  EXPECT_EQ(kSerialHash[31] & 0x7f, auto_enrollment_request().remainder());
230  VerifyCachedResult(false, 8);
231}
232
233TEST_F(AutoEnrollmentClientTest, ConsumerDevice) {
234  ServerWillReply(-1, true, false);
235  client_->Start();
236  EXPECT_FALSE(client_->should_auto_enroll());
237  EXPECT_EQ(1, completion_callback_count_);
238  VerifyCachedResult(false, 8);
239}
240
241TEST_F(AutoEnrollmentClientTest, EnterpriseDevice) {
242  ServerWillReply(-1, true, true);
243  client_->Start();
244  EXPECT_TRUE(client_->should_auto_enroll());
245  EXPECT_EQ(1, completion_callback_count_);
246  VerifyCachedResult(true, 8);
247}
248
249TEST_F(AutoEnrollmentClientTest, NoSerial) {
250  CreateClient("", 4, 8);
251  client_->Start();
252  EXPECT_FALSE(client_->should_auto_enroll());
253  EXPECT_EQ(1, completion_callback_count_);
254  EXPECT_FALSE(HasCachedDecision());
255}
256
257TEST_F(AutoEnrollmentClientTest, NoBitsUploaded) {
258  CreateClient(kSerial, 0, 0);
259  ServerWillReply(-1, false, false);
260  client_->Start();
261  EXPECT_FALSE(client_->should_auto_enroll());
262  EXPECT_EQ(1, completion_callback_count_);
263  EXPECT_TRUE(auto_enrollment_request().has_remainder());
264  EXPECT_TRUE(auto_enrollment_request().has_modulus());
265  EXPECT_EQ(1, auto_enrollment_request().modulus());
266  EXPECT_EQ(0, auto_enrollment_request().remainder());
267  VerifyCachedResult(false, 0);
268}
269
270TEST_F(AutoEnrollmentClientTest, ManyBitsUploaded) {
271  int64 bottom62 = GG_INT64_C(0x14e437a1552b138a);
272  for (int i = 0; i <= 62; ++i) {
273    completion_callback_count_ = 0;
274    CreateClient(kSerial, i, i);
275    ServerWillReply(-1, false, false);
276    client_->Start();
277    EXPECT_FALSE(client_->should_auto_enroll());
278    EXPECT_EQ(1, completion_callback_count_);
279    EXPECT_TRUE(auto_enrollment_request().has_remainder());
280    EXPECT_TRUE(auto_enrollment_request().has_modulus());
281    EXPECT_EQ(GG_INT64_C(1) << i, auto_enrollment_request().modulus());
282    EXPECT_EQ(bottom62 % (GG_INT64_C(1) << i),
283              auto_enrollment_request().remainder());
284    VerifyCachedResult(false, i);
285  }
286}
287
288TEST_F(AutoEnrollmentClientTest, MoreThan32BitsUploaded) {
289  CreateClient(kSerial, 10, 37);
290  InSequence sequence;
291  ServerWillReply(GG_INT64_C(1) << 37, false, false);
292  ServerWillReply(-1, true, true);
293  client_->Start();
294  EXPECT_TRUE(client_->should_auto_enroll());
295  EXPECT_EQ(1, completion_callback_count_);
296  VerifyCachedResult(true, 37);
297}
298
299TEST_F(AutoEnrollmentClientTest, ReuseCachedDecision) {
300  EXPECT_CALL(*service_, CreateJob(_)).Times(0);
301  local_state_->SetUserPref(prefs::kShouldAutoEnroll,
302                            Value::CreateBooleanValue(true));
303  local_state_->SetUserPref(prefs::kAutoEnrollmentPowerLimit,
304                            Value::CreateIntegerValue(8));
305  client_->Start();
306  EXPECT_TRUE(client_->should_auto_enroll());
307  EXPECT_EQ(1, completion_callback_count_);
308  AutoEnrollmentClient::CancelAutoEnrollment();
309  client_->Start();
310  EXPECT_FALSE(client_->should_auto_enroll());
311  EXPECT_EQ(2, completion_callback_count_);
312}
313
314TEST_F(AutoEnrollmentClientTest, RetryIfPowerLargerThanCached) {
315  local_state_->SetUserPref(prefs::kShouldAutoEnroll,
316                            Value::CreateBooleanValue(false));
317  local_state_->SetUserPref(prefs::kAutoEnrollmentPowerLimit,
318                            Value::CreateIntegerValue(8));
319  CreateClient(kSerial, 5, 10);
320  ServerWillReply(-1, true, true);
321  client_->Start();
322  EXPECT_TRUE(client_->should_auto_enroll());
323  EXPECT_EQ(1, completion_callback_count_);
324}
325
326}  // namespace
327
328}  // namespace policy
329