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