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.
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"
29 namespace em = enterprise_management;
33 const char kServiceUrl[] = "https://example.com/management_service";
35 // Encoded empty response messages for testing the error code paths.
36 const char kResponseEmpty[] = "\x08\x00";
38 #define PROTO_STRING(name) (std::string(name, arraysize(name) - 1))
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";
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 {
52 DeviceManagementServiceTestBase() {
54 new net::TestURLRequestContextGetter(loop_.message_loop_proxy());
59 ~DeviceManagementServiceTestBase() {
61 base::RunLoop().RunUntilIdle();
65 scoped_ptr<DeviceManagementService::Configuration> configuration(
66 new MockDeviceManagementServiceConfiguration(kServiceUrl));
67 service_.reset(new DeviceManagementService(configuration.Pass()));
70 void InitializeService() {
71 service_->ScheduleInitialization(0);
72 base::RunLoop().RunUntilIdle();
75 net::TestURLFetcher* GetFetcher() {
76 return factory_.GetFetcherByID(DeviceManagementService::kURLFetcherID);
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)));
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)));
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)));
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)));
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)));
154 void SendResponse(net::TestURLFetcher* fetcher,
155 const net::URLRequestStatus request_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);
165 MOCK_METHOD3(OnJobDone, void(DeviceManagementStatus, int,
166 const em::DeviceManagementResponse&));
168 MOCK_METHOD1(OnJobRetry, void(DeviceManagementRequestJob*));
170 base::MessageLoop loop_;
171 scoped_refptr<net::TestURLRequestContextGetter> request_context_;
172 net::TestURLFetcherFactory factory_;
173 scoped_ptr<DeviceManagementService> service_;
176 struct FailedRequestParams {
177 FailedRequestParams(DeviceManagementStatus expected_status,
178 net::URLRequestStatus::Status request_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) {}
186 DeviceManagementStatus expected_status_;
187 net::URLRequestStatus request_status_;
189 std::string response_;
192 void PrintTo(const FailedRequestParams& params, std::ostream* os) {
193 *os << "FailedRequestParams " << params.expected_status_
194 << " " << params.request_status_.status()
195 << " " << params.http_status_;
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> {
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);
212 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
213 GetParam().response_);
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);
224 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
225 GetParam().response_);
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);
235 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
236 GetParam().response_);
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);
246 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
247 GetParam().response_);
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);
257 SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
258 GetParam().response_);
261 INSTANTIATE_TEST_CASE_P(
262 DeviceManagementServiceFailedRequestTestInstance,
263 DeviceManagementServiceFailedRequestTest,
266 DM_STATUS_REQUEST_FAILED,
267 net::URLRequestStatus::FAILED,
269 PROTO_STRING(kResponseEmpty)),
271 DM_STATUS_HTTP_STATUS_ERROR,
272 net::URLRequestStatus::SUCCESS,
274 PROTO_STRING(kResponseEmpty)),
276 DM_STATUS_RESPONSE_DECODING_ERROR,
277 net::URLRequestStatus::SUCCESS,
279 PROTO_STRING("Not a protobuf.")),
281 DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED,
282 net::URLRequestStatus::SUCCESS,
284 PROTO_STRING(kResponseEmpty)),
286 DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER,
287 net::URLRequestStatus::SUCCESS,
289 PROTO_STRING(kResponseEmpty)),
291 DM_STATUS_SERVICE_DEVICE_ID_CONFLICT,
292 net::URLRequestStatus::SUCCESS,
294 PROTO_STRING(kResponseEmpty)),
296 DM_STATUS_SERVICE_DEVICE_NOT_FOUND,
297 net::URLRequestStatus::SUCCESS,
299 PROTO_STRING(kResponseEmpty)),
301 DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID,
302 net::URLRequestStatus::SUCCESS,
304 PROTO_STRING(kResponseEmpty)),
306 DM_STATUS_REQUEST_INVALID,
307 net::URLRequestStatus::SUCCESS,
309 PROTO_STRING(kResponseEmpty)),
311 DM_STATUS_TEMPORARY_UNAVAILABLE,
312 net::URLRequestStatus::SUCCESS,
314 PROTO_STRING(kResponseEmpty)),
316 DM_STATUS_SERVICE_ACTIVATION_PENDING,
317 net::URLRequestStatus::SUCCESS,
319 PROTO_STRING(kResponseEmpty)),
321 DM_STATUS_SERVICE_MISSING_LICENSES,
322 net::URLRequestStatus::SUCCESS,
324 PROTO_STRING(kResponseEmpty))));
326 // Simple query parameter parser for testing.
329 explicit QueryParams(const std::string& query) {
330 base::SplitStringIntoKeyValuePairs(query, '=', '&', ¶ms_);
333 bool Check(const std::string& name, const std::string& expected_value) {
335 for (ParamMap::const_iterator i(params_.begin()); i != params_.end(); ++i) {
336 std::string unescaped_name(net::UnescapeURLComponent(
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) {
347 std::string unescaped_value(net::UnescapeURLComponent(
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)
362 typedef std::vector<std::pair<std::string, std::string> > ParamMap;
366 class DeviceManagementServiceTest
367 : public DeviceManagementServiceTestBase {
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());
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));
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;
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);
407 CheckURLAndQueryParams(fetcher->GetOriginalURL(),
408 dm_protocol::kValueRequestRegister,
411 std::string expected_data;
412 ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data));
413 EXPECT_EQ(expected_data, fetcher->upload_data());
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);
422 TEST_F(DeviceManagementServiceTest, ApiAuthCodeFetchRequest) {
423 em::DeviceManagementResponse expected_response;
424 expected_response.mutable_service_api_access_response()->set_auth_code(
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);
434 CheckURLAndQueryParams(fetcher->GetOriginalURL(),
435 dm_protocol::kValueRequestApiAuthorization,
438 std::string expected_data;
439 ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data));
440 EXPECT_EQ(expected_data, fetcher->upload_data());
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);
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);
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());
467 CheckURLAndQueryParams(fetcher->GetOriginalURL(),
468 dm_protocol::kValueRequestUnregister,
471 std::string expected_data;
472 ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data));
473 EXPECT_EQ(expected_data, fetcher->upload_data());
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);
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);
489 // There shouldn't be any callbacks.
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);
501 // There shouldn't be any callbacks.
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);
512 // There shouldn't be any callbacks.
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);
523 // There shouldn't be any callbacks.
527 TEST_F(DeviceManagementServiceTest, JobQueueing) {
528 // Start with a non-initialized service.
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);
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);
543 // Now initialize the service. That should start the job.
545 fetcher = GetFetcher();
546 ASSERT_TRUE(fetcher);
547 factory_.RemoveFetcherFromMap(DeviceManagementService::kURLFetcherID);
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);
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);
563 // Shutdown the service and cancel the job afterwards.
564 service_->Shutdown();
568 ACTION_P(ResetPointer, pointer) {
572 TEST_F(DeviceManagementServiceTest, CancelDuringCallback) {
574 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
575 net::TestURLFetcher* fetcher = GetFetcher();
576 ASSERT_TRUE(fetcher);
578 EXPECT_CALL(*this, OnJobDone(_, _, _))
579 .WillOnce(ResetPointer(&request_job));
580 EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
582 // Generate a callback.
583 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
584 SendResponse(fetcher, status, 500, std::string());
586 // Job should have been reset.
587 EXPECT_FALSE(request_job.get());
590 TEST_F(DeviceManagementServiceTest, RetryOnProxyError) {
592 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
593 EXPECT_CALL(*this, OnJobRetry(_));
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());
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());
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());
615 TEST_F(DeviceManagementServiceTest, RetryOnBadResponseFromProxy) {
617 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
618 EXPECT_CALL(*this, OnJobRetry(_));
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);
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());
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());
645 TEST_F(DeviceManagementServiceTest, RetryOnNetworkChanges) {
647 EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
648 EXPECT_CALL(*this, OnJobRetry(_));
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());
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);
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());
672 TEST_F(DeviceManagementServiceTest, RetryLimit) {
673 scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
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);
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);
702 } // namespace policy