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