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