Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / components / policy / core / common / cloud / device_management_service_unittest.cc
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, '=', '&', &params_);
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