device_management_service_browsertest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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 "base/bind.h"
6#include "base/bind_helpers.h"
7#include "base/memory/scoped_ptr.h"
8#include "base/message_loop.h"
9#include "base/stl_util.h"
10#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
11#include "chrome/browser/policy/cloud/device_management_service.h"
12#include "chrome/browser/policy/cloud/test_request_interceptor.h"
13#include "chrome/browser/policy/test/local_policy_test_server.h"
14#include "chrome/test/base/in_process_browser_test.h"
15#include "net/base/upload_bytes_element_reader.h"
16#include "net/base/upload_data_stream.h"
17#include "net/url_request/url_fetcher.h"
18#include "net/url_request/url_request.h"
19#include "net/url_request/url_request_test_job.h"
20#include "testing/gmock/include/gmock/gmock.h"
21#include "testing/gtest/include/gtest/gtest.h"
22
23using testing::DoAll;
24using testing::Invoke;
25using testing::InvokeWithoutArgs;
26using testing::_;
27
28namespace em = enterprise_management;
29
30namespace policy {
31
32namespace {
33
34// Parses the DeviceManagementRequest in |request_data| and writes a serialized
35// DeviceManagementResponse to |response_data|.
36void ConstructResponse(const char* request_data,
37                       uint64 request_data_length,
38                       std::string* response_data) {
39  em::DeviceManagementRequest request;
40  ASSERT_TRUE(request.ParseFromArray(request_data, request_data_length));
41  em::DeviceManagementResponse response;
42  if (request.has_register_request()) {
43    response.mutable_register_response()->set_device_management_token(
44        "fake_token");
45  } else if (request.has_service_api_access_request()) {
46    response.mutable_service_api_access_response()->set_auth_code(
47        "fake_auth_code");
48  } else if (request.has_unregister_request()) {
49    response.mutable_unregister_response();
50  } else if (request.has_policy_request()) {
51    response.mutable_policy_response()->add_response();
52  } else if (request.has_auto_enrollment_request()) {
53    response.mutable_auto_enrollment_response();
54  } else {
55    FAIL() << "Failed to parse request.";
56  }
57  ASSERT_TRUE(response.SerializeToString(response_data));
58}
59
60// JobCallback for the interceptor.
61net::URLRequestJob* ResponseJob(
62    net::URLRequest* request,
63    net::NetworkDelegate* network_delegate) {
64  const net::UploadDataStream* upload = request->get_upload();
65  if (upload != NULL &&
66      upload->element_readers().size() == 1 &&
67      upload->element_readers()[0]->AsBytesReader()) {
68    std::string response_data;
69    const net::UploadBytesElementReader* bytes_reader =
70        upload->element_readers()[0]->AsBytesReader();
71    ConstructResponse(bytes_reader->bytes(),
72                      bytes_reader->length(),
73                      &response_data);
74    return new net::URLRequestTestJob(
75        request,
76        network_delegate,
77        net::URLRequestTestJob::test_headers(),
78        response_data,
79        true);
80  }
81
82  return NULL;
83}
84
85}  // namespace
86
87class DeviceManagementServiceIntegrationTest
88    : public InProcessBrowserTest,
89      public testing::WithParamInterface<
90          std::string (DeviceManagementServiceIntegrationTest::*)(void)> {
91 public:
92  MOCK_METHOD2(OnJobDone, void(DeviceManagementStatus,
93                               const em::DeviceManagementResponse&));
94
95  std::string InitCannedResponse() {
96    interceptor_.reset(new TestRequestInterceptor("localhost"));
97    return "http://localhost";
98  }
99
100  std::string InitTestServer() {
101    StartTestServer();
102    return test_server_->GetServiceURL().spec();
103  }
104
105  void RecordAuthCode(DeviceManagementStatus status,
106                      const em::DeviceManagementResponse& response) {
107    robot_auth_code_ = response.service_api_access_response().auth_code();
108  }
109
110 protected:
111  void ExpectRequest() {
112    if (interceptor_)
113      interceptor_->PushJobCallback(base::Bind(&ResponseJob));
114  }
115
116  void PerformRegistration() {
117    ExpectRequest();
118    EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _))
119        .WillOnce(
120            DoAll(Invoke(this,
121                         &DeviceManagementServiceIntegrationTest::RecordToken),
122                  InvokeWithoutArgs(MessageLoop::current(),
123                                    &MessageLoop::Quit)));
124    scoped_ptr<DeviceManagementRequestJob> job(
125        service_->CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION));
126    job->SetGaiaToken("gaia_auth_token");
127    job->SetOAuthToken("oauth_token");
128    job->SetClientID("testid");
129    job->GetRequest()->mutable_register_request();
130    job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
131                          base::Unretained(this)));
132    MessageLoop::current()->Run();
133  }
134
135  virtual void SetUpOnMainThread() OVERRIDE {
136    std::string service_url((this->*(GetParam()))());
137    service_.reset(new DeviceManagementService(service_url));
138    service_->ScheduleInitialization(0);
139  }
140
141  virtual void CleanUpOnMainThread() OVERRIDE {
142    service_.reset();
143    test_server_.reset();
144    interceptor_.reset();
145  }
146
147  void StartTestServer() {
148    test_server_.reset(
149        new LocalPolicyTestServer("device_management_service_browsertest"));
150    ASSERT_TRUE(test_server_->Start());
151  }
152
153  void RecordToken(DeviceManagementStatus status,
154                   const em::DeviceManagementResponse& response) {
155    token_ = response.register_response().device_management_token();
156  }
157
158  std::string token_;
159  std::string robot_auth_code_;
160  scoped_ptr<DeviceManagementService> service_;
161  scoped_ptr<LocalPolicyTestServer> test_server_;
162  scoped_ptr<TestRequestInterceptor> interceptor_;
163};
164
165IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, Registration) {
166  PerformRegistration();
167  EXPECT_FALSE(token_.empty());
168}
169
170IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest,
171                       ApiAuthCodeFetch) {
172  PerformRegistration();
173
174  ExpectRequest();
175  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _))
176      .WillOnce(
177          DoAll(Invoke(this,
178                       &DeviceManagementServiceIntegrationTest::RecordAuthCode),
179                InvokeWithoutArgs(MessageLoop::current(),
180                                  &MessageLoop::Quit)));
181  scoped_ptr<DeviceManagementRequestJob> job(service_->CreateJob(
182      DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH));
183  job->SetDMToken(token_);
184  job->SetClientID("testid");
185  em::DeviceServiceApiAccessRequest* request =
186      job->GetRequest()->mutable_service_api_access_request();
187  request->add_auth_scope("authScope4Test");
188  request->set_oauth2_client_id("oauth2ClientId4Test");
189  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
190                        base::Unretained(this)));
191  MessageLoop::current()->Run();
192  ASSERT_EQ("fake_auth_code", robot_auth_code_);
193}
194
195IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, PolicyFetch) {
196  PerformRegistration();
197
198  ExpectRequest();
199  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _))
200      .WillOnce(InvokeWithoutArgs(MessageLoop::current(), &MessageLoop::Quit));
201  scoped_ptr<DeviceManagementRequestJob> job(
202      service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH));
203  job->SetDMToken(token_);
204  job->SetUserAffiliation(USER_AFFILIATION_NONE);
205  job->SetClientID("testid");
206  em::DevicePolicyRequest* request =
207      job->GetRequest()->mutable_policy_request();
208  request->add_request()->set_policy_type(dm_protocol::kChromeUserPolicyType);
209  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
210                        base::Unretained(this)));
211  MessageLoop::current()->Run();
212}
213
214IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, Unregistration) {
215  PerformRegistration();
216
217  ExpectRequest();
218  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _))
219      .WillOnce(InvokeWithoutArgs(MessageLoop::current(), &MessageLoop::Quit));
220  scoped_ptr<DeviceManagementRequestJob> job(
221      service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION));
222  job->SetDMToken(token_);
223  job->SetClientID("testid");
224  job->GetRequest()->mutable_unregister_request();
225  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
226                        base::Unretained(this)));
227  MessageLoop::current()->Run();
228}
229
230IN_PROC_BROWSER_TEST_P(DeviceManagementServiceIntegrationTest, AutoEnrollment) {
231  ExpectRequest();
232  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _))
233      .WillOnce(InvokeWithoutArgs(MessageLoop::current(), &MessageLoop::Quit));
234  scoped_ptr<DeviceManagementRequestJob> job(
235      service_->CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT));
236  job->SetClientID("testid");
237  job->GetRequest()->mutable_auto_enrollment_request()->set_remainder(0);
238  job->GetRequest()->mutable_auto_enrollment_request()->set_modulus(1);
239  job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
240                        base::Unretained(this)));
241  MessageLoop::current()->Run();
242}
243
244INSTANTIATE_TEST_CASE_P(
245    DeviceManagementServiceIntegrationTestInstance,
246    DeviceManagementServiceIntegrationTest,
247    testing::Values(&DeviceManagementServiceIntegrationTest::InitCannedResponse,
248                    &DeviceManagementServiceIntegrationTest::InitTestServer));
249
250}  // namespace policy
251