• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
DeviceManagementServiceTestBase()52   DeviceManagementServiceTestBase() {
53     request_context_ =
54         new net::TestURLRequestContextGetter(loop_.message_loop_proxy());
55     ResetService();
56     InitializeService();
57   }
58 
~DeviceManagementServiceTestBase()59   ~DeviceManagementServiceTestBase() {
60     service_.reset();
61     base::RunLoop().RunUntilIdle();
62   }
63 
ResetService()64   void ResetService() {
65     scoped_ptr<DeviceManagementService::Configuration> configuration(
66         new MockDeviceManagementServiceConfiguration(kServiceUrl));
67     service_.reset(new DeviceManagementService(configuration.Pass()));
68   }
69 
InitializeService()70   void InitializeService() {
71     service_->ScheduleInitialization(0);
72     base::RunLoop().RunUntilIdle();
73   }
74 
GetFetcher()75   net::TestURLFetcher* GetFetcher() {
76     return factory_.GetFetcherByID(DeviceManagementService::kURLFetcherID);
77   }
78 
StartRegistrationJob()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 
StartApiAuthCodeFetchJob()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 
StartUnregistrationJob()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 
StartPolicyFetchJob()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 
StartAutoEnrollmentJob()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 
SendResponse(net::TestURLFetcher * fetcher,const net::URLRequestStatus request_status,int http_status,const std::string & response)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 
178 struct FailedRequestParams {
FailedRequestParamspolicy::FailedRequestParams179   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 
PrintTo(const FailedRequestParams & params,std::ostream * os)194 void 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.
202 class DeviceManagementServiceFailedRequestTest
203     : public DeviceManagementServiceTestBase,
204       public testing::WithParamInterface<FailedRequestParams> {
205 };
206 
TEST_P(DeviceManagementServiceFailedRequestTest,RegisterRequest)207 TEST_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 
TEST_P(DeviceManagementServiceFailedRequestTest,ApiAuthCodeFetchRequest)218 TEST_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 
TEST_P(DeviceManagementServiceFailedRequestTest,UnregisterRequest)230 TEST_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 
TEST_P(DeviceManagementServiceFailedRequestTest,PolicyRequest)241 TEST_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 
TEST_P(DeviceManagementServiceFailedRequestTest,AutoEnrollmentRequest)252 TEST_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 
263 INSTANTIATE_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.
329 class QueryParams {
330  public:
QueryParams(const std::string & query)331   explicit QueryParams(const std::string& query) {
332     base::SplitStringIntoKeyValuePairs(query, '=', '&', &params_);
333   }
334 
Check(const std::string & name,const std::string & expected_value)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 
368 class DeviceManagementServiceTest
369     : public DeviceManagementServiceTestBase {
370  protected:
CheckURLAndQueryParams(const GURL & request_url,const std::string & request_type,const std::string & device_id)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 
390 MATCHER_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 
TEST_F(DeviceManagementServiceTest,RegisterRequest)398 TEST_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 
TEST_F(DeviceManagementServiceTest,ApiAuthCodeFetchRequest)424 TEST_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 
TEST_F(DeviceManagementServiceTest,UnregisterRequest)451 TEST_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 
TEST_F(DeviceManagementServiceTest,CancelRegisterRequest)484 TEST_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 
TEST_F(DeviceManagementServiceTest,CancelApiAuthCodeFetch)495 TEST_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 
TEST_F(DeviceManagementServiceTest,CancelUnregisterRequest)507 TEST_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 
TEST_F(DeviceManagementServiceTest,CancelPolicyRequest)518 TEST_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 
TEST_F(DeviceManagementServiceTest,JobQueueing)529 TEST_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 
TEST_F(DeviceManagementServiceTest,CancelRequestAfterShutdown)558 TEST_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 
ACTION_P(ResetPointer,pointer)570 ACTION_P(ResetPointer, pointer) {
571   pointer->reset();
572 }
573 
TEST_F(DeviceManagementServiceTest,CancelDuringCallback)574 TEST_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 
TEST_F(DeviceManagementServiceTest,RetryOnProxyError)592 TEST_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 
TEST_F(DeviceManagementServiceTest,RetryOnBadResponseFromProxy)617 TEST_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 
TEST_F(DeviceManagementServiceTest,RetryOnNetworkChanges)647 TEST_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 
TEST_F(DeviceManagementServiceTest,RetryLimit)674 TEST_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