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