Home | History | Annotate | Download | only in cloud
      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
    703