Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / auto_enrollment_client_unittest.cc
blob3e703bc36afcc39ce9901a6630329f9a46712216
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.
5 #include "chrome/browser/chromeos/policy/auto_enrollment_client.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/prefs/testing_pref_service.h"
12 #include "base/values.h"
13 #include "chrome/browser/browser_process.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 "components/policy/core/common/cloud/mock_device_management_service.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "crypto/sha2.h"
20 #include "net/url_request/url_request_context_getter.h"
21 #include "net/url_request/url_request_test_util.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace em = enterprise_management;
27 namespace policy {
29 namespace {
31 const char* kSerial = "serial";
32 const char* kSerialHash =
33 "\x01\x44\xb1\xde\xfc\xf7\x56\x10\x87\x01\x5f\x8d\x83\x0d\x65\xb1"
34 "\x6f\x02\x4a\xd7\xeb\x92\x45\xfc\xd4\xe4\x37\xa1\x55\x2b\x13\x8a";
36 using ::testing::InSequence;
37 using ::testing::SaveArg;
38 using ::testing::_;
40 class AutoEnrollmentClientTest : public testing::Test {
41 protected:
42 AutoEnrollmentClientTest()
43 : scoped_testing_local_state_(
44 TestingBrowserProcess::GetGlobal()),
45 local_state_(scoped_testing_local_state_.Get()),
46 completion_callback_count_(0) {}
48 virtual void SetUp() OVERRIDE {
49 CreateClient(kSerial, 4, 8);
50 ASSERT_FALSE(local_state_->GetUserPref(prefs::kShouldAutoEnroll));
51 ASSERT_FALSE(local_state_->GetUserPref(prefs::kAutoEnrollmentPowerLimit));
54 void CreateClient(const std::string& serial,
55 int power_initial,
56 int power_limit) {
57 service_.reset(new MockDeviceManagementService());
58 EXPECT_CALL(*service_, StartJob(_, _, _, _, _, _, _))
59 .WillRepeatedly(SaveArg<6>(&last_request_));
60 base::Closure callback =
61 base::Bind(&AutoEnrollmentClientTest::CompletionCallback,
62 base::Unretained(this));
63 client_.reset(new AutoEnrollmentClient(
64 callback,
65 service_.get(),
66 local_state_,
67 new net::TestURLRequestContextGetter(
68 base::MessageLoop::current()->message_loop_proxy()),
69 serial,
70 power_initial,
71 power_limit));
74 void CompletionCallback() {
75 completion_callback_count_++;
78 void ServerWillFail(DeviceManagementStatus error) {
79 em::DeviceManagementResponse dummy_response;
80 EXPECT_CALL(*service_,
81 CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT, _))
82 .WillOnce(service_->FailJob(error));
85 void ServerWillReply(int64 modulus, bool with_hashes, bool with_serial_hash) {
86 em::DeviceManagementResponse response;
87 em::DeviceAutoEnrollmentResponse* enrollment_response =
88 response.mutable_auto_enrollment_response();
89 if (modulus >= 0)
90 enrollment_response->set_expected_modulus(modulus);
91 if (with_hashes) {
92 for (size_t i = 0; i < 10; ++i) {
93 std::string serial = "serial X";
94 serial[7] = '0' + i;
95 std::string hash = crypto::SHA256HashString(serial);
96 enrollment_response->mutable_hash()->Add()->assign(hash);
99 if (with_serial_hash) {
100 enrollment_response->mutable_hash()->Add()->assign(kSerialHash,
101 crypto::kSHA256Length);
103 EXPECT_CALL(*service_,
104 CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT, _))
105 .WillOnce(service_->SucceedJob(response));
108 void ServerWillReplyAsync(MockDeviceManagementJob** job) {
109 EXPECT_CALL(*service_,
110 CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT, _))
111 .WillOnce(service_->CreateAsyncJob(job));
114 bool HasCachedDecision() {
115 return local_state_->GetUserPref(prefs::kShouldAutoEnroll);
118 void VerifyCachedResult(bool should_enroll, int power_limit) {
119 base::FundamentalValue value_should_enroll(should_enroll);
120 base::FundamentalValue value_power_limit(power_limit);
121 EXPECT_TRUE(base::Value::Equals(
122 &value_should_enroll,
123 local_state_->GetUserPref(prefs::kShouldAutoEnroll)));
124 EXPECT_TRUE(base::Value::Equals(
125 &value_power_limit,
126 local_state_->GetUserPref(prefs::kAutoEnrollmentPowerLimit)));
129 const em::DeviceAutoEnrollmentRequest& auto_enrollment_request() {
130 return last_request_.auto_enrollment_request();
133 content::TestBrowserThreadBundle browser_threads_;
134 ScopedTestingLocalState scoped_testing_local_state_;
135 TestingPrefServiceSimple* local_state_;
136 scoped_ptr<MockDeviceManagementService> service_;
137 scoped_ptr<AutoEnrollmentClient> client_;
138 em::DeviceManagementRequest last_request_;
139 int completion_callback_count_;
141 private:
142 DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentClientTest);
145 TEST_F(AutoEnrollmentClientTest, NetworkFailure) {
146 ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE);
147 client_->Start();
148 EXPECT_FALSE(client_->should_auto_enroll());
149 EXPECT_EQ(0, completion_callback_count_);
150 EXPECT_FALSE(HasCachedDecision());
153 TEST_F(AutoEnrollmentClientTest, EmptyReply) {
154 ServerWillReply(-1, false, false);
155 client_->Start();
156 EXPECT_FALSE(client_->should_auto_enroll());
157 EXPECT_EQ(1, completion_callback_count_);
158 VerifyCachedResult(false, 8);
161 TEST_F(AutoEnrollmentClientTest, ClientUploadsRightBits) {
162 ServerWillReply(-1, false, false);
163 client_->Start();
164 EXPECT_FALSE(client_->should_auto_enroll());
165 EXPECT_EQ(1, completion_callback_count_);
167 EXPECT_TRUE(auto_enrollment_request().has_remainder());
168 EXPECT_TRUE(auto_enrollment_request().has_modulus());
169 EXPECT_EQ(16, auto_enrollment_request().modulus());
170 EXPECT_EQ(kSerialHash[31] & 0xf, auto_enrollment_request().remainder());
171 VerifyCachedResult(false, 8);
174 TEST_F(AutoEnrollmentClientTest, AskForMoreThenFail) {
175 InSequence sequence;
176 ServerWillReply(32, false, false);
177 ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE);
178 client_->Start();
179 EXPECT_FALSE(client_->should_auto_enroll());
180 EXPECT_EQ(0, completion_callback_count_);
181 EXPECT_FALSE(HasCachedDecision());
184 TEST_F(AutoEnrollmentClientTest, AskForMoreThenEvenMore) {
185 InSequence sequence;
186 ServerWillReply(32, false, false);
187 ServerWillReply(64, false, false);
188 client_->Start();
189 EXPECT_FALSE(client_->should_auto_enroll());
190 EXPECT_EQ(1, completion_callback_count_);
191 EXPECT_FALSE(HasCachedDecision());
194 TEST_F(AutoEnrollmentClientTest, AskForLess) {
195 InSequence sequence;
196 ServerWillReply(8, false, false);
197 ServerWillReply(-1, true, true);
198 client_->Start();
199 EXPECT_TRUE(client_->should_auto_enroll());
200 EXPECT_EQ(1, completion_callback_count_);
201 VerifyCachedResult(true, 8);
204 TEST_F(AutoEnrollmentClientTest, AskForSame) {
205 InSequence sequence;
206 ServerWillReply(16, false, false);
207 ServerWillReply(-1, true, true);
208 client_->Start();
209 EXPECT_TRUE(client_->should_auto_enroll());
210 EXPECT_EQ(1, completion_callback_count_);
211 VerifyCachedResult(true, 8);
214 TEST_F(AutoEnrollmentClientTest, AskForSameTwice) {
215 InSequence sequence;
216 ServerWillReply(16, false, false);
217 ServerWillReply(16, false, false);
218 client_->Start();
219 EXPECT_FALSE(client_->should_auto_enroll());
220 EXPECT_EQ(1, completion_callback_count_);
221 EXPECT_FALSE(HasCachedDecision());
224 TEST_F(AutoEnrollmentClientTest, AskForTooMuch) {
225 ServerWillReply(512, false, false);
226 client_->Start();
227 EXPECT_FALSE(client_->should_auto_enroll());
228 EXPECT_EQ(1, completion_callback_count_);
229 EXPECT_FALSE(HasCachedDecision());
232 TEST_F(AutoEnrollmentClientTest, AskNonPowerOf2) {
233 InSequence sequence;
234 ServerWillReply(100, false, false);
235 ServerWillReply(-1, false, false);
236 client_->Start();
237 EXPECT_FALSE(client_->should_auto_enroll());
238 EXPECT_EQ(1, completion_callback_count_);
239 EXPECT_TRUE(auto_enrollment_request().has_remainder());
240 EXPECT_TRUE(auto_enrollment_request().has_modulus());
241 EXPECT_EQ(128, auto_enrollment_request().modulus());
242 EXPECT_EQ(kSerialHash[31] & 0x7f, auto_enrollment_request().remainder());
243 VerifyCachedResult(false, 8);
246 TEST_F(AutoEnrollmentClientTest, ConsumerDevice) {
247 ServerWillReply(-1, true, false);
248 client_->Start();
249 EXPECT_FALSE(client_->should_auto_enroll());
250 EXPECT_EQ(1, completion_callback_count_);
251 VerifyCachedResult(false, 8);
253 // Network changes don't trigger retries after obtaining a response from
254 // the server.
255 client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
256 EXPECT_EQ(1, completion_callback_count_);
259 TEST_F(AutoEnrollmentClientTest, EnterpriseDevice) {
260 ServerWillReply(-1, true, true);
261 client_->Start();
262 EXPECT_TRUE(client_->should_auto_enroll());
263 EXPECT_EQ(1, completion_callback_count_);
264 VerifyCachedResult(true, 8);
266 // Network changes don't trigger retries after obtaining a response from
267 // the server.
268 client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
269 EXPECT_EQ(1, completion_callback_count_);
272 TEST_F(AutoEnrollmentClientTest, NoSerial) {
273 CreateClient("", 4, 8);
274 client_->Start();
275 EXPECT_FALSE(client_->should_auto_enroll());
276 EXPECT_EQ(1, completion_callback_count_);
277 EXPECT_FALSE(HasCachedDecision());
280 TEST_F(AutoEnrollmentClientTest, NoBitsUploaded) {
281 CreateClient(kSerial, 0, 0);
282 ServerWillReply(-1, false, false);
283 client_->Start();
284 EXPECT_FALSE(client_->should_auto_enroll());
285 EXPECT_EQ(1, completion_callback_count_);
286 EXPECT_TRUE(auto_enrollment_request().has_remainder());
287 EXPECT_TRUE(auto_enrollment_request().has_modulus());
288 EXPECT_EQ(1, auto_enrollment_request().modulus());
289 EXPECT_EQ(0, auto_enrollment_request().remainder());
290 VerifyCachedResult(false, 0);
293 TEST_F(AutoEnrollmentClientTest, ManyBitsUploaded) {
294 int64 bottom62 = GG_INT64_C(0x14e437a1552b138a);
295 for (int i = 0; i <= 62; ++i) {
296 completion_callback_count_ = 0;
297 CreateClient(kSerial, i, i);
298 ServerWillReply(-1, false, false);
299 client_->Start();
300 EXPECT_FALSE(client_->should_auto_enroll());
301 EXPECT_EQ(1, completion_callback_count_);
302 EXPECT_TRUE(auto_enrollment_request().has_remainder());
303 EXPECT_TRUE(auto_enrollment_request().has_modulus());
304 EXPECT_EQ(GG_INT64_C(1) << i, auto_enrollment_request().modulus());
305 EXPECT_EQ(bottom62 % (GG_INT64_C(1) << i),
306 auto_enrollment_request().remainder());
307 VerifyCachedResult(false, i);
311 TEST_F(AutoEnrollmentClientTest, MoreThan32BitsUploaded) {
312 CreateClient(kSerial, 10, 37);
313 InSequence sequence;
314 ServerWillReply(GG_INT64_C(1) << 37, false, false);
315 ServerWillReply(-1, true, true);
316 client_->Start();
317 EXPECT_TRUE(client_->should_auto_enroll());
318 EXPECT_EQ(1, completion_callback_count_);
319 VerifyCachedResult(true, 37);
322 TEST_F(AutoEnrollmentClientTest, ReuseCachedDecision) {
323 EXPECT_CALL(*service_, CreateJob(_, _)).Times(0);
324 local_state_->SetUserPref(prefs::kShouldAutoEnroll,
325 base::Value::CreateBooleanValue(true));
326 local_state_->SetUserPref(prefs::kAutoEnrollmentPowerLimit,
327 base::Value::CreateIntegerValue(8));
328 client_->Start();
329 EXPECT_TRUE(client_->should_auto_enroll());
330 EXPECT_EQ(1, completion_callback_count_);
331 AutoEnrollmentClient::CancelAutoEnrollment();
332 client_->Start();
333 EXPECT_FALSE(client_->should_auto_enroll());
334 EXPECT_EQ(2, completion_callback_count_);
337 TEST_F(AutoEnrollmentClientTest, RetryIfPowerLargerThanCached) {
338 local_state_->SetUserPref(prefs::kShouldAutoEnroll,
339 base::Value::CreateBooleanValue(false));
340 local_state_->SetUserPref(prefs::kAutoEnrollmentPowerLimit,
341 base::Value::CreateIntegerValue(8));
342 CreateClient(kSerial, 5, 10);
343 ServerWillReply(-1, true, true);
344 client_->Start();
345 EXPECT_TRUE(client_->should_auto_enroll());
346 EXPECT_EQ(1, completion_callback_count_);
349 TEST_F(AutoEnrollmentClientTest, NetworkChangeRetryAfterErrors) {
350 ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE);
351 client_->Start();
352 EXPECT_FALSE(client_->should_auto_enroll());
353 // Don't invoke the callback if there was a network failure.
354 EXPECT_EQ(0, completion_callback_count_);
355 EXPECT_FALSE(HasCachedDecision());
357 // The client doesn't retry if no new connection became available.
358 client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
359 EXPECT_FALSE(client_->should_auto_enroll());
360 EXPECT_EQ(0, completion_callback_count_);
361 EXPECT_FALSE(HasCachedDecision());
363 // Retry once the network is back.
364 ServerWillReply(-1, true, true);
365 client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
366 EXPECT_TRUE(client_->should_auto_enroll());
367 EXPECT_EQ(1, completion_callback_count_);
368 EXPECT_TRUE(HasCachedDecision());
370 // Subsequent network changes don't trigger retries.
371 client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
372 client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
373 EXPECT_TRUE(client_->should_auto_enroll());
374 EXPECT_EQ(1, completion_callback_count_);
375 EXPECT_TRUE(HasCachedDecision());
378 TEST_F(AutoEnrollmentClientTest, CancelAndDeleteSoonWithPendingRequest) {
379 MockDeviceManagementJob* job = NULL;
380 ServerWillReplyAsync(&job);
381 EXPECT_FALSE(job);
382 client_->Start();
383 ASSERT_TRUE(job);
384 EXPECT_EQ(0, completion_callback_count_);
386 // Cancel while a request is in flight.
387 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
388 client_.release()->CancelAndDeleteSoon();
389 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
391 // The client cleans itself up once a reply is received.
392 job->SendResponse(DM_STATUS_TEMPORARY_UNAVAILABLE,
393 em::DeviceManagementResponse());
394 // The DeleteSoon task has been posted:
395 EXPECT_FALSE(base::MessageLoop::current()->IsIdleForTesting());
396 EXPECT_EQ(0, completion_callback_count_);
399 TEST_F(AutoEnrollmentClientTest, NetworkChangedAfterCancelAndDeleteSoon) {
400 MockDeviceManagementJob* job = NULL;
401 ServerWillReplyAsync(&job);
402 EXPECT_FALSE(job);
403 client_->Start();
404 ASSERT_TRUE(job);
405 EXPECT_EQ(0, completion_callback_count_);
407 // Cancel while a request is in flight.
408 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
409 AutoEnrollmentClient* client = client_.release();
410 client->CancelAndDeleteSoon();
411 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
413 // Network change events are ignored while a request is pending.
414 client->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
415 EXPECT_EQ(0, completion_callback_count_);
417 // The client cleans itself up once a reply is received.
418 job->SendResponse(DM_STATUS_TEMPORARY_UNAVAILABLE,
419 em::DeviceManagementResponse());
420 // The DeleteSoon task has been posted:
421 EXPECT_FALSE(base::MessageLoop::current()->IsIdleForTesting());
422 EXPECT_EQ(0, completion_callback_count_);
424 // Network changes that have been posted before are also ignored:
425 client->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
426 EXPECT_EQ(0, completion_callback_count_);
429 TEST_F(AutoEnrollmentClientTest, CancelAndDeleteSoonAfterCompletion) {
430 ServerWillReply(-1, true, true);
431 client_->Start();
432 EXPECT_EQ(1, completion_callback_count_);
433 EXPECT_TRUE(client_->should_auto_enroll());
435 // The client will delete itself immediately if there are no pending
436 // requests.
437 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
438 client_.release()->CancelAndDeleteSoon();
439 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
442 TEST_F(AutoEnrollmentClientTest, CancelAndDeleteSoonAfterNetworkFailure) {
443 ServerWillFail(DM_STATUS_TEMPORARY_UNAVAILABLE);
444 client_->Start();
445 EXPECT_EQ(0, completion_callback_count_);
446 EXPECT_FALSE(client_->should_auto_enroll());
448 // The client will delete itself immediately if there are no pending
449 // requests.
450 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
451 client_.release()->CancelAndDeleteSoon();
452 EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
455 } // namespace
457 } // namespace policy