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 <ostream> 6 #include <vector> 7 8 #include "base/bind.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop_proxy.h" 11 #include "base/run_loop.h" 12 #include "base/strings/string_split.h" 13 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 14 #include "components/policy/core/common/cloud/device_management_service.h" 15 #include "components/policy/core/common/cloud/mock_device_management_service.h" 16 #include "net/base/escape.h" 17 #include "net/base/load_flags.h" 18 #include "net/base/net_errors.h" 19 #include "net/http/http_response_headers.h" 20 #include "net/url_request/test_url_fetcher_factory.h" 21 #include "net/url_request/url_request_status.h" 22 #include "net/url_request/url_request_test_util.h" 23 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gtest/include/gtest/gtest.h" 25 26 using testing::Mock; 27 using testing::_; 28 29 namespace em = enterprise_management; 30 31 namespace policy { 32 33 const char kServiceUrl[] = "https://example.com/management_service"; 34 35 // Encoded empty response messages for testing the error code paths. 36 const char kResponseEmpty[] = "\x08\x00"; 37 38 #define PROTO_STRING(name) (std::string(name, arraysize(name) - 1)) 39 40 // Some helper constants. 41 const char kGaiaAuthToken[] = "gaia-auth-token"; 42 const char kOAuthToken[] = "oauth-token"; 43 const char kDMToken[] = "device-management-token"; 44 const char kClientID[] = "device-id"; 45 const char kRobotAuthCode[] = "robot-oauth-auth-code"; 46 47 // Unit tests for the device management policy service. The tests are run 48 // against a TestURLFetcherFactory that is used to short-circuit the request 49 // without calling into the actual network stack. 50 class DeviceManagementServiceTestBase : public testing::Test { 51 protected: 52 DeviceManagementServiceTestBase() { 53 request_context_ = 54 new net::TestURLRequestContextGetter(loop_.message_loop_proxy()); 55 ResetService(); 56 InitializeService(); 57 } 58 59 ~DeviceManagementServiceTestBase() { 60 service_.reset(); 61 base::RunLoop().RunUntilIdle(); 62 } 63 64 void ResetService() { 65 scoped_ptr<DeviceManagementService::Configuration> configuration( 66 new MockDeviceManagementServiceConfiguration(kServiceUrl)); 67 service_.reset(new DeviceManagementService(configuration.Pass())); 68 } 69 70 void InitializeService() { 71 service_->ScheduleInitialization(0); 72 base::RunLoop().RunUntilIdle(); 73 } 74 75 net::TestURLFetcher* GetFetcher() { 76 return factory_.GetFetcherByID(DeviceManagementService::kURLFetcherID); 77 } 78 79 DeviceManagementRequestJob* StartRegistrationJob() { 80 DeviceManagementRequestJob* job = service_->CreateJob( 81 DeviceManagementRequestJob::TYPE_REGISTRATION, request_context_.get()); 82 job->SetGaiaToken(kGaiaAuthToken); 83 job->SetOAuthToken(kOAuthToken); 84 job->SetClientID(kClientID); 85 job->GetRequest()->mutable_register_request(); 86 job->SetRetryCallback(base::Bind( 87 &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this))); 88 job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone, 89 base::Unretained(this))); 90 return job; 91 } 92 93 DeviceManagementRequestJob* StartApiAuthCodeFetchJob() { 94 DeviceManagementRequestJob* job = service_->CreateJob( 95 DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH, 96 request_context_.get()); 97 job->SetGaiaToken(kGaiaAuthToken); 98 job->SetOAuthToken(kOAuthToken); 99 job->SetClientID(kClientID); 100 job->GetRequest()->mutable_service_api_access_request(); 101 job->SetRetryCallback(base::Bind( 102 &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this))); 103 job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone, 104 base::Unretained(this))); 105 return job; 106 } 107 108 DeviceManagementRequestJob* StartUnregistrationJob() { 109 DeviceManagementRequestJob* job = 110 service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION, 111 request_context_.get()); 112 job->SetDMToken(kDMToken); 113 job->SetClientID(kClientID); 114 job->GetRequest()->mutable_unregister_request(); 115 job->SetRetryCallback(base::Bind( 116 &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this))); 117 job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone, 118 base::Unretained(this))); 119 return job; 120 } 121 122 DeviceManagementRequestJob* StartPolicyFetchJob() { 123 DeviceManagementRequestJob* job = service_->CreateJob( 124 DeviceManagementRequestJob::TYPE_POLICY_FETCH, request_context_.get()); 125 job->SetGaiaToken(kGaiaAuthToken); 126 job->SetOAuthToken(kOAuthToken); 127 job->SetClientID(kClientID); 128 em::PolicyFetchRequest* fetch_request = 129 job->GetRequest()->mutable_policy_request()->add_request(); 130 fetch_request->set_policy_type(dm_protocol::kChromeUserPolicyType); 131 job->SetRetryCallback(base::Bind( 132 &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this))); 133 job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone, 134 base::Unretained(this))); 135 return job; 136 } 137 138 DeviceManagementRequestJob* StartAutoEnrollmentJob() { 139 DeviceManagementRequestJob* job = 140 service_->CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT, 141 request_context_.get()); 142 job->SetClientID(kClientID); 143 em::DeviceAutoEnrollmentRequest* request = 144 job->GetRequest()->mutable_auto_enrollment_request(); 145 request->set_modulus(1); 146 request->set_remainder(0); 147 job->SetRetryCallback(base::Bind( 148 &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this))); 149 job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone, 150 base::Unretained(this))); 151 return job; 152 } 153 154 void SendResponse(net::TestURLFetcher* fetcher, 155 const net::URLRequestStatus request_status, 156 int http_status, 157 const std::string& response) { 158 fetcher->set_url(GURL(kServiceUrl)); 159 fetcher->set_status(request_status); 160 fetcher->set_response_code(http_status); 161 fetcher->SetResponseString(response); 162 fetcher->delegate()->OnURLFetchComplete(fetcher); 163 } 164 165 MOCK_METHOD3(OnJobDone, void(DeviceManagementStatus, int, 166 const em::DeviceManagementResponse&)); 167 168 MOCK_METHOD1(OnJobRetry, void(DeviceManagementRequestJob*)); 169 170 base::MessageLoop loop_; 171 scoped_refptr<net::TestURLRequestContextGetter> request_context_; 172 net::TestURLFetcherFactory factory_; 173 scoped_ptr<DeviceManagementService> service_; 174 }; 175 176 struct FailedRequestParams { 177 FailedRequestParams(DeviceManagementStatus expected_status, 178 net::URLRequestStatus::Status request_status, 179 int http_status, 180 const std::string& response) 181 : expected_status_(expected_status), 182 request_status_(request_status, 0), 183 http_status_(http_status), 184 response_(response) {} 185 186 DeviceManagementStatus expected_status_; 187 net::URLRequestStatus request_status_; 188 int http_status_; 189 std::string response_; 190 }; 191 192 void PrintTo(const FailedRequestParams& params, std::ostream* os) { 193 *os << "FailedRequestParams " << params.expected_status_ 194 << " " << params.request_status_.status() 195 << " " << params.http_status_; 196 } 197 198 // A parameterized test case for erroneous response situations, they're mostly 199 // the same for all kinds of requests. 200 class DeviceManagementServiceFailedRequestTest 201 : public DeviceManagementServiceTestBase, 202 public testing::WithParamInterface<FailedRequestParams> { 203 }; 204 205 TEST_P(DeviceManagementServiceFailedRequestTest, RegisterRequest) { 206 EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _)); 207 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 208 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob()); 209 net::TestURLFetcher* fetcher = GetFetcher(); 210 ASSERT_TRUE(fetcher); 211 212 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_, 213 GetParam().response_); 214 } 215 216 TEST_P(DeviceManagementServiceFailedRequestTest, ApiAuthCodeFetchRequest) { 217 EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _)); 218 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 219 scoped_ptr<DeviceManagementRequestJob> request_job( 220 StartApiAuthCodeFetchJob()); 221 net::TestURLFetcher* fetcher = GetFetcher(); 222 ASSERT_TRUE(fetcher); 223 224 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_, 225 GetParam().response_); 226 } 227 228 TEST_P(DeviceManagementServiceFailedRequestTest, UnregisterRequest) { 229 EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _)); 230 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 231 scoped_ptr<DeviceManagementRequestJob> request_job(StartUnregistrationJob()); 232 net::TestURLFetcher* fetcher = GetFetcher(); 233 ASSERT_TRUE(fetcher); 234 235 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_, 236 GetParam().response_); 237 } 238 239 TEST_P(DeviceManagementServiceFailedRequestTest, PolicyRequest) { 240 EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _)); 241 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 242 scoped_ptr<DeviceManagementRequestJob> request_job(StartPolicyFetchJob()); 243 net::TestURLFetcher* fetcher = GetFetcher(); 244 ASSERT_TRUE(fetcher); 245 246 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_, 247 GetParam().response_); 248 } 249 250 TEST_P(DeviceManagementServiceFailedRequestTest, AutoEnrollmentRequest) { 251 EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _)); 252 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 253 scoped_ptr<DeviceManagementRequestJob> request_job(StartAutoEnrollmentJob()); 254 net::TestURLFetcher* fetcher = GetFetcher(); 255 ASSERT_TRUE(fetcher); 256 257 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_, 258 GetParam().response_); 259 } 260 261 INSTANTIATE_TEST_CASE_P( 262 DeviceManagementServiceFailedRequestTestInstance, 263 DeviceManagementServiceFailedRequestTest, 264 testing::Values( 265 FailedRequestParams( 266 DM_STATUS_REQUEST_FAILED, 267 net::URLRequestStatus::FAILED, 268 200, 269 PROTO_STRING(kResponseEmpty)), 270 FailedRequestParams( 271 DM_STATUS_HTTP_STATUS_ERROR, 272 net::URLRequestStatus::SUCCESS, 273 666, 274 PROTO_STRING(kResponseEmpty)), 275 FailedRequestParams( 276 DM_STATUS_RESPONSE_DECODING_ERROR, 277 net::URLRequestStatus::SUCCESS, 278 200, 279 PROTO_STRING("Not a protobuf.")), 280 FailedRequestParams( 281 DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED, 282 net::URLRequestStatus::SUCCESS, 283 403, 284 PROTO_STRING(kResponseEmpty)), 285 FailedRequestParams( 286 DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER, 287 net::URLRequestStatus::SUCCESS, 288 405, 289 PROTO_STRING(kResponseEmpty)), 290 FailedRequestParams( 291 DM_STATUS_SERVICE_DEVICE_ID_CONFLICT, 292 net::URLRequestStatus::SUCCESS, 293 409, 294 PROTO_STRING(kResponseEmpty)), 295 FailedRequestParams( 296 DM_STATUS_SERVICE_DEVICE_NOT_FOUND, 297 net::URLRequestStatus::SUCCESS, 298 410, 299 PROTO_STRING(kResponseEmpty)), 300 FailedRequestParams( 301 DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID, 302 net::URLRequestStatus::SUCCESS, 303 401, 304 PROTO_STRING(kResponseEmpty)), 305 FailedRequestParams( 306 DM_STATUS_REQUEST_INVALID, 307 net::URLRequestStatus::SUCCESS, 308 400, 309 PROTO_STRING(kResponseEmpty)), 310 FailedRequestParams( 311 DM_STATUS_TEMPORARY_UNAVAILABLE, 312 net::URLRequestStatus::SUCCESS, 313 404, 314 PROTO_STRING(kResponseEmpty)), 315 FailedRequestParams( 316 DM_STATUS_SERVICE_ACTIVATION_PENDING, 317 net::URLRequestStatus::SUCCESS, 318 412, 319 PROTO_STRING(kResponseEmpty)), 320 FailedRequestParams( 321 DM_STATUS_SERVICE_MISSING_LICENSES, 322 net::URLRequestStatus::SUCCESS, 323 402, 324 PROTO_STRING(kResponseEmpty)))); 325 326 // Simple query parameter parser for testing. 327 class QueryParams { 328 public: 329 explicit QueryParams(const std::string& query) { 330 base::SplitStringIntoKeyValuePairs(query, '=', '&', ¶ms_); 331 } 332 333 bool Check(const std::string& name, const std::string& expected_value) { 334 bool found = false; 335 for (ParamMap::const_iterator i(params_.begin()); i != params_.end(); ++i) { 336 std::string unescaped_name(net::UnescapeURLComponent( 337 i->first, 338 net::UnescapeRule::NORMAL | 339 net::UnescapeRule::SPACES | 340 net::UnescapeRule::URL_SPECIAL_CHARS | 341 net::UnescapeRule::CONTROL_CHARS | 342 net::UnescapeRule::REPLACE_PLUS_WITH_SPACE)); 343 if (unescaped_name == name) { 344 if (found) 345 return false; 346 found = true; 347 std::string unescaped_value(net::UnescapeURLComponent( 348 i->second, 349 net::UnescapeRule::NORMAL | 350 net::UnescapeRule::SPACES | 351 net::UnescapeRule::URL_SPECIAL_CHARS | 352 net::UnescapeRule::CONTROL_CHARS | 353 net::UnescapeRule::REPLACE_PLUS_WITH_SPACE)); 354 if (unescaped_value != expected_value) 355 return false; 356 } 357 } 358 return found; 359 } 360 361 private: 362 typedef std::vector<std::pair<std::string, std::string> > ParamMap; 363 ParamMap params_; 364 }; 365 366 class DeviceManagementServiceTest 367 : public DeviceManagementServiceTestBase { 368 protected: 369 void CheckURLAndQueryParams(const GURL& request_url, 370 const std::string& request_type, 371 const std::string& device_id) { 372 const GURL service_url(kServiceUrl); 373 EXPECT_EQ(service_url.scheme(), request_url.scheme()); 374 EXPECT_EQ(service_url.host(), request_url.host()); 375 EXPECT_EQ(service_url.port(), request_url.port()); 376 EXPECT_EQ(service_url.path(), request_url.path()); 377 378 QueryParams query_params(request_url.query()); 379 EXPECT_TRUE(query_params.Check(dm_protocol::kParamRequest, request_type)); 380 EXPECT_TRUE(query_params.Check(dm_protocol::kParamDeviceID, device_id)); 381 EXPECT_TRUE(query_params.Check(dm_protocol::kParamDeviceType, 382 dm_protocol::kValueDeviceType)); 383 EXPECT_TRUE(query_params.Check(dm_protocol::kParamAppType, 384 dm_protocol::kValueAppType)); 385 } 386 }; 387 388 MATCHER_P(MessageEquals, reference, "") { 389 std::string reference_data; 390 std::string arg_data; 391 return arg.SerializeToString(&arg_data) && 392 reference.SerializeToString(&reference_data) && 393 arg_data == reference_data; 394 } 395 396 TEST_F(DeviceManagementServiceTest, RegisterRequest) { 397 em::DeviceManagementResponse expected_response; 398 expected_response.mutable_register_response()-> 399 set_device_management_token(kDMToken); 400 EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, 401 MessageEquals(expected_response))); 402 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 403 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob()); 404 net::TestURLFetcher* fetcher = GetFetcher(); 405 ASSERT_TRUE(fetcher); 406 407 CheckURLAndQueryParams(fetcher->GetOriginalURL(), 408 dm_protocol::kValueRequestRegister, 409 kClientID); 410 411 std::string expected_data; 412 ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data)); 413 EXPECT_EQ(expected_data, fetcher->upload_data()); 414 415 // Generate the response. 416 std::string response_data; 417 ASSERT_TRUE(expected_response.SerializeToString(&response_data)); 418 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 419 SendResponse(fetcher, status, 200, response_data); 420 } 421 422 TEST_F(DeviceManagementServiceTest, ApiAuthCodeFetchRequest) { 423 em::DeviceManagementResponse expected_response; 424 expected_response.mutable_service_api_access_response()->set_auth_code( 425 kRobotAuthCode); 426 EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, 427 MessageEquals(expected_response))); 428 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 429 scoped_ptr<DeviceManagementRequestJob> request_job( 430 StartApiAuthCodeFetchJob()); 431 net::TestURLFetcher* fetcher = GetFetcher(); 432 ASSERT_TRUE(fetcher); 433 434 CheckURLAndQueryParams(fetcher->GetOriginalURL(), 435 dm_protocol::kValueRequestApiAuthorization, 436 kClientID); 437 438 std::string expected_data; 439 ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data)); 440 EXPECT_EQ(expected_data, fetcher->upload_data()); 441 442 // Generate the response. 443 std::string response_data; 444 ASSERT_TRUE(expected_response.SerializeToString(&response_data)); 445 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 446 SendResponse(fetcher, status, 200, response_data); 447 } 448 449 TEST_F(DeviceManagementServiceTest, UnregisterRequest) { 450 em::DeviceManagementResponse expected_response; 451 expected_response.mutable_unregister_response(); 452 EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, 453 MessageEquals(expected_response))); 454 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 455 scoped_ptr<DeviceManagementRequestJob> request_job(StartUnregistrationJob()); 456 net::TestURLFetcher* fetcher = GetFetcher(); 457 ASSERT_TRUE(fetcher); 458 459 // Check the data the fetcher received. 460 const GURL& request_url(fetcher->GetOriginalURL()); 461 const GURL service_url(kServiceUrl); 462 EXPECT_EQ(service_url.scheme(), request_url.scheme()); 463 EXPECT_EQ(service_url.host(), request_url.host()); 464 EXPECT_EQ(service_url.port(), request_url.port()); 465 EXPECT_EQ(service_url.path(), request_url.path()); 466 467 CheckURLAndQueryParams(fetcher->GetOriginalURL(), 468 dm_protocol::kValueRequestUnregister, 469 kClientID); 470 471 std::string expected_data; 472 ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data)); 473 EXPECT_EQ(expected_data, fetcher->upload_data()); 474 475 // Generate the response. 476 std::string response_data; 477 ASSERT_TRUE(expected_response.SerializeToString(&response_data)); 478 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 479 SendResponse(fetcher, status, 200, response_data); 480 } 481 482 TEST_F(DeviceManagementServiceTest, CancelRegisterRequest) { 483 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0); 484 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 485 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob()); 486 net::TestURLFetcher* fetcher = GetFetcher(); 487 ASSERT_TRUE(fetcher); 488 489 // There shouldn't be any callbacks. 490 request_job.reset(); 491 } 492 493 TEST_F(DeviceManagementServiceTest, CancelApiAuthCodeFetch) { 494 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0); 495 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 496 scoped_ptr<DeviceManagementRequestJob> request_job( 497 StartApiAuthCodeFetchJob()); 498 net::TestURLFetcher* fetcher = GetFetcher(); 499 ASSERT_TRUE(fetcher); 500 501 // There shouldn't be any callbacks. 502 request_job.reset(); 503 } 504 505 TEST_F(DeviceManagementServiceTest, CancelUnregisterRequest) { 506 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0); 507 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 508 scoped_ptr<DeviceManagementRequestJob> request_job(StartUnregistrationJob()); 509 net::TestURLFetcher* fetcher = GetFetcher(); 510 ASSERT_TRUE(fetcher); 511 512 // There shouldn't be any callbacks. 513 request_job.reset(); 514 } 515 516 TEST_F(DeviceManagementServiceTest, CancelPolicyRequest) { 517 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0); 518 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 519 scoped_ptr<DeviceManagementRequestJob> request_job(StartPolicyFetchJob()); 520 net::TestURLFetcher* fetcher = GetFetcher(); 521 ASSERT_TRUE(fetcher); 522 523 // There shouldn't be any callbacks. 524 request_job.reset(); 525 } 526 527 TEST_F(DeviceManagementServiceTest, JobQueueing) { 528 // Start with a non-initialized service. 529 ResetService(); 530 531 em::DeviceManagementResponse expected_response; 532 expected_response.mutable_register_response()-> 533 set_device_management_token(kDMToken); 534 EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _, 535 MessageEquals(expected_response))); 536 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 537 538 // Make a request. We should not see any fetchers being created. 539 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob()); 540 net::TestURLFetcher* fetcher = GetFetcher(); 541 ASSERT_FALSE(fetcher); 542 543 // Now initialize the service. That should start the job. 544 InitializeService(); 545 fetcher = GetFetcher(); 546 ASSERT_TRUE(fetcher); 547 factory_.RemoveFetcherFromMap(DeviceManagementService::kURLFetcherID); 548 549 // Check that the request is processed as expected. 550 std::string response_data; 551 ASSERT_TRUE(expected_response.SerializeToString(&response_data)); 552 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 553 SendResponse(fetcher, status, 200, response_data); 554 } 555 556 TEST_F(DeviceManagementServiceTest, CancelRequestAfterShutdown) { 557 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0); 558 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 559 scoped_ptr<DeviceManagementRequestJob> request_job(StartPolicyFetchJob()); 560 net::TestURLFetcher* fetcher = GetFetcher(); 561 ASSERT_TRUE(fetcher); 562 563 // Shutdown the service and cancel the job afterwards. 564 service_->Shutdown(); 565 request_job.reset(); 566 } 567 568 ACTION_P(ResetPointer, pointer) { 569 pointer->reset(); 570 } 571 572 TEST_F(DeviceManagementServiceTest, CancelDuringCallback) { 573 // Make a request. 574 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob()); 575 net::TestURLFetcher* fetcher = GetFetcher(); 576 ASSERT_TRUE(fetcher); 577 578 EXPECT_CALL(*this, OnJobDone(_, _, _)) 579 .WillOnce(ResetPointer(&request_job)); 580 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 581 582 // Generate a callback. 583 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); 584 SendResponse(fetcher, status, 500, std::string()); 585 586 // Job should have been reset. 587 EXPECT_FALSE(request_job.get()); 588 } 589 590 TEST_F(DeviceManagementServiceTest, RetryOnProxyError) { 591 // Make a request. 592 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0); 593 EXPECT_CALL(*this, OnJobRetry(_)); 594 595 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob()); 596 net::TestURLFetcher* fetcher = GetFetcher(); 597 ASSERT_TRUE(fetcher); 598 EXPECT_TRUE((fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY) == 0); 599 const GURL original_url(fetcher->GetOriginalURL()); 600 const std::string upload_data(fetcher->upload_data()); 601 602 // Generate a callback with a proxy failure. 603 net::URLRequestStatus status(net::URLRequestStatus::FAILED, 604 net::ERR_PROXY_CONNECTION_FAILED); 605 SendResponse(fetcher, status, 200, std::string()); 606 607 // Verify that a new URLFetcher was started that bypasses the proxy. 608 fetcher = GetFetcher(); 609 ASSERT_TRUE(fetcher); 610 EXPECT_TRUE(fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY); 611 EXPECT_EQ(original_url, fetcher->GetOriginalURL()); 612 EXPECT_EQ(upload_data, fetcher->upload_data()); 613 } 614 615 TEST_F(DeviceManagementServiceTest, RetryOnBadResponseFromProxy) { 616 // Make a request. 617 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0); 618 EXPECT_CALL(*this, OnJobRetry(_)); 619 620 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob()); 621 net::TestURLFetcher* fetcher = GetFetcher(); 622 ASSERT_TRUE(fetcher); 623 EXPECT_TRUE((fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY) == 0); 624 const GURL original_url(fetcher->GetOriginalURL()); 625 const std::string upload_data(fetcher->upload_data()); 626 fetcher->set_was_fetched_via_proxy(true); 627 scoped_refptr<net::HttpResponseHeaders> headers; 628 headers = new net::HttpResponseHeaders( 629 "HTTP/1.1 200 OK\0Content-type: bad/type\0\0"); 630 fetcher->set_response_headers(headers); 631 632 // Generate a callback with a valid http response, that was generated by 633 // a bad/wrong proxy. 634 net::URLRequestStatus status; 635 SendResponse(fetcher, status, 200, std::string()); 636 637 // Verify that a new URLFetcher was started that bypasses the proxy. 638 fetcher = GetFetcher(); 639 ASSERT_TRUE(fetcher); 640 EXPECT_TRUE((fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY) != 0); 641 EXPECT_EQ(original_url, fetcher->GetOriginalURL()); 642 EXPECT_EQ(upload_data, fetcher->upload_data()); 643 } 644 645 TEST_F(DeviceManagementServiceTest, RetryOnNetworkChanges) { 646 // Make a request. 647 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0); 648 EXPECT_CALL(*this, OnJobRetry(_)); 649 650 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob()); 651 net::TestURLFetcher* fetcher = GetFetcher(); 652 ASSERT_TRUE(fetcher); 653 const GURL original_url(fetcher->GetOriginalURL()); 654 const std::string original_upload_data(fetcher->upload_data()); 655 656 // Make it fail with ERR_NETWORK_CHANGED. 657 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, 658 net::ERR_NETWORK_CHANGED)); 659 fetcher->set_url(GURL(kServiceUrl)); 660 fetcher->delegate()->OnURLFetchComplete(fetcher); 661 662 // Verify that a new URLFetcher was started that retries this job, after 663 // having called OnJobRetry. 664 Mock::VerifyAndClearExpectations(this); 665 fetcher = GetFetcher(); 666 ASSERT_TRUE(fetcher); 667 EXPECT_EQ(original_url, fetcher->GetOriginalURL()); 668 EXPECT_EQ(original_upload_data, fetcher->upload_data()); 669 EXPECT_EQ(net::URLRequestStatus::SUCCESS, fetcher->GetStatus().status()); 670 } 671 672 TEST_F(DeviceManagementServiceTest, RetryLimit) { 673 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob()); 674 675 // Simulate 3 failed network requests. 676 for (int i = 0; i < 3; ++i) { 677 // Make the current fetcher fail with ERR_NETWORK_CHANGED. 678 net::TestURLFetcher* fetcher = GetFetcher(); 679 ASSERT_TRUE(fetcher); 680 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0); 681 EXPECT_CALL(*this, OnJobRetry(_)); 682 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, 683 net::ERR_NETWORK_CHANGED)); 684 fetcher->set_url(GURL(kServiceUrl)); 685 fetcher->delegate()->OnURLFetchComplete(fetcher); 686 Mock::VerifyAndClearExpectations(this); 687 } 688 689 // At the next failure the DeviceManagementService should give up retrying and 690 // pass the error code to the job's owner. 691 net::TestURLFetcher* fetcher = GetFetcher(); 692 ASSERT_TRUE(fetcher); 693 EXPECT_CALL(*this, OnJobDone(DM_STATUS_REQUEST_FAILED, _, _)); 694 EXPECT_CALL(*this, OnJobRetry(_)).Times(0); 695 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, 696 net::ERR_NETWORK_CHANGED)); 697 fetcher->set_url(GURL(kServiceUrl)); 698 fetcher->delegate()->OnURLFetchComplete(fetcher); 699 Mock::VerifyAndClearExpectations(this); 700 } 701 702 } // namespace policy 703