Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: chrome/browser/policy/cloud_policy_subsystem_unittest.cc

Issue 7216012: Test cases for the cloud policy subsystem (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address commens Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <vector> 5 #include <vector>
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/scoped_temp_dir.h" 8 #include "base/scoped_temp_dir.h"
9 #include "base/values.h" 9 #include "base/values.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 device_token_ = token; 98 device_token_ = token;
99 NotifyDeviceTokenChanged(); 99 NotifyDeviceTokenChanged();
100 } 100 }
101 101
102 private: 102 private:
103 std::string device_token_; 103 std::string device_token_;
104 104
105 DISALLOW_COPY_AND_ASSIGN(TestingIdentityStrategy); 105 DISALLOW_COPY_AND_ASSIGN(TestingIdentityStrategy);
106 }; 106 };
107 107
108 // An action that returns an URLRequestJob with an HTTP error code.
109 ACTION_P(CreateFailedResponse, http_error_code) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
111 em::DeviceManagementResponse response_data;
112
113 arg2->response_data = response_data.SerializeAsString();
114 arg2->response_code = http_error_code;
115 }
116
117 // An action that returns an URLRequestJob with a successful device
118 // registration response.
119 ACTION_P(CreateSuccessfulRegisterResponse, token) {
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
121 em::DeviceManagementResponse response_data;
122 response_data.mutable_register_response()->set_device_management_token(token);
123
124 arg2->response_data = response_data.SerializeAsString();
125 arg2->response_code = 200;
126 }
127
128 // An action that returns an URLRequestJob with a successful policy response.
129 ACTION_P(CreateSuccessfulPolicyResponse, homepage_location) {
130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
131 em::CloudPolicySettings settings;
132 settings.mutable_homepagelocation()->set_homepagelocation(homepage_location);
133 em::PolicyData policy_data;
134 policy_data.set_policy_type(kPolicyType);
135 policy_data.set_policy_value(settings.SerializeAsString());
136
137 em::DeviceManagementResponse response_data;
138 em::DevicePolicyResponse* policy_response =
139 response_data.mutable_policy_response();
140 em::PolicyFetchResponse* fetch_response = policy_response->add_response();
141 fetch_response->set_error_code(200);
142 fetch_response->set_policy_data(policy_data.SerializeAsString());
143
144 arg2->response_data = response_data.SerializeAsString();
145 arg2->response_code = 200;
146 }
147
108 // Tests CloudPolicySubsystem by intercepting its network requests. 148 // Tests CloudPolicySubsystem by intercepting its network requests.
109 // The requests are intercepted by PolicyRequestInterceptor and they are 149 // The requests are intercepted by PolicyRequestInterceptor and they are
110 // logged by LoggingWorkScheduler for further examination. 150 // logged by LoggingWorkScheduler for further examination.
111 class CloudPolicySubsystemTest : public testing::Test { 151 template<typename TESTBASE>
152 class CloudPolicySubsystemTestBase : public TESTBASE {
112 public: 153 public:
113 CloudPolicySubsystemTest() 154 CloudPolicySubsystemTestBase()
114 : ui_thread_(BrowserThread::UI, &loop_), 155 : ui_thread_(BrowserThread::UI, &loop_),
115 io_thread_(BrowserThread::IO, &loop_) { 156 io_thread_(BrowserThread::IO, &loop_) {
116 } 157 }
117 158
159 virtual ~CloudPolicySubsystemTestBase() {
160 }
161
118 protected: 162 protected:
119 void StopMessageLoop() { 163 void StopMessageLoop() {
120 loop_.QuitNow(); 164 loop_.QuitNow();
121 } 165 }
122 166
123 virtual void SetUp() { 167 virtual void SetUp() {
124 prefs_.reset(new TestingPrefService); 168 prefs_.reset(new TestingPrefService);
125 CloudPolicySubsystem::RegisterPrefs(prefs_.get()); 169 CloudPolicySubsystem::RegisterPrefs(prefs_.get());
126 ((TestingBrowserProcess*) g_browser_process)->SetLocalState(prefs_.get()); 170 ((TestingBrowserProcess*) g_browser_process)->SetLocalState(prefs_.get());
127 171
(...skipping 13 matching lines...) Expand all
141 185
142 virtual void TearDown() { 186 virtual void TearDown() {
143 ((TestingBrowserProcess*) g_browser_process)->SetLocalState(NULL); 187 ((TestingBrowserProcess*) g_browser_process)->SetLocalState(NULL);
144 cloud_policy_subsystem_->Shutdown(); 188 cloud_policy_subsystem_->Shutdown();
145 cloud_policy_subsystem_.reset(); 189 cloud_policy_subsystem_.reset();
146 factory_.reset(); 190 factory_.reset();
147 logger_.reset(); 191 logger_.reset();
148 prefs_.reset(); 192 prefs_.reset();
149 } 193 }
150 194
195 void ExecuteTest() {
196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
197 // The first unexpected request of the policy subsystem will stop the
198 // message loop.
199 // This code relies on the fact that an InSequence object is active.
200 EXPECT_CALL(*(factory_.get()), Intercept(_, _, _))
201 .Times(AtMost(1))
202 .WillOnce(InvokeWithoutArgs(
203 this,
204 &CloudPolicySubsystemTestBase::StopMessageLoop));
205 loop_.RunAllPending();
206 }
207
208 void VerifyTest(const std::string& homepage_location) {
209 // Test conditions.
210 EXPECT_EQ(CloudPolicySubsystem::SUCCESS, cloud_policy_subsystem_->state());
211 StringValue homepage_value(homepage_location);
212 VerifyPolicy(kPolicyHomepageLocation, &homepage_value);
213 VerifyServerLoad();
214 }
215
216 void VerifyState(CloudPolicySubsystem::PolicySubsystemState state) {
217 EXPECT_EQ(state, cloud_policy_subsystem_->state());
218 }
219
220 void ExpectSuccessfulRegistration() {
221 EXPECT_CALL(*(factory_.get()), Intercept(kGaiaAuthHeader, "register", _))
222 .WillOnce(CreateSuccessfulRegisterResponse(kDMToken));
223 }
224
225 void ExpectFailedRegistration(int n, int code) {
226 EXPECT_CALL(*(factory_.get()), Intercept(kGaiaAuthHeader, "register", _))
227 .Times(n)
228 .WillRepeatedly(CreateFailedResponse(code));
229 }
230
231 void ExpectFailedPolicy(int n, int code) {
232 EXPECT_CALL(*(factory_.get()), Intercept(kDMAuthHeader, "policy", _))
233 .Times(n)
234 .WillRepeatedly(CreateFailedResponse(code));
235 }
236
237 void ExpectSuccessfulPolicy(int n, const std::string& homepage) {
238 EXPECT_CALL(*(factory_.get()), Intercept(kDMAuthHeader, "policy", _))
239 .Times(n)
240 .WillRepeatedly(CreateSuccessfulPolicyResponse(homepage));
241 }
242
243 private:
151 // Verifies for a given policy that it is provided by the subsystem. 244 // Verifies for a given policy that it is provided by the subsystem.
152 void VerifyPolicy(enum ConfigurationPolicyType type, Value* expected) { 245 void VerifyPolicy(enum ConfigurationPolicyType type, Value* expected) {
153 MockConfigurationPolicyStore store; 246 MockConfigurationPolicyStore store;
154 EXPECT_CALL(store, Apply(_, _)).Times(AtLeast(1)); 247 EXPECT_CALL(store, Apply(_, _)).Times(AtLeast(1));
155 cache_->GetManagedPolicyProvider()->Provide(&store); 248 cache_->GetManagedPolicyProvider()->Provide(&store);
156 ASSERT_TRUE(Value::Equals(expected, store.Get(type))); 249 ASSERT_TRUE(Value::Equals(expected, store.Get(type)));
157 } 250 }
158 251
159 // Verifies that the last recorded run of the subsystem did not issue 252 // Verifies that the last recorded run of the subsystem did not issue
160 // too frequent requests: 253 // too frequent requests:
161 // - no more than 10 requests in the first 10 minutes 254 // - no more than 10 requests in the first 10 minutes
162 // - no more then 12 requests per hour in the next 10 hours 255 // - no more then 12 requests per hour in the next 10 hours
163 // TODO(gfeher): Thighten these conditions further. This will require 256 // TODO(gfeher): Thighten these conditions further. This will require
164 // fine-tuning of the subsystem. See: http://crosbug.com/15195 257 // fine-tuning of the subsystem. See: http://crosbug.com/16637
165 void VerifyServerLoad() { 258 void VerifyServerLoad() {
166 std::vector<int64> events; 259 std::vector<int64> events;
167 logger_->Swap(&events); 260 logger_->Swap(&events);
168 261
169 ASSERT_FALSE(events.empty()); 262 ASSERT_FALSE(events.empty());
170 263
171 int64 cur = 0; 264 int64 cur = 0;
172 int count = 0; 265 int count = 0;
173 266
174 // Length and max number of requests for the first interval. 267 // Length and max number of requests for the first interval.
175 int64 length = 10*60*1000; // 10 minutes 268 int64 length = 10*60*1000; // 10 minutes
176 int64 limit = 10; // maximum nr of requests in the first 10 minutes 269 int64 limit = 10; // maximum nr of requests in the first 10 minutes
177 270
178 while (cur <= events.back()) { 271 while (cur <= events.back()) {
179 EXPECT_LE(EventLogger::CountEvents(events, cur, length), limit); 272 EXPECT_LE(EventLogger::CountEvents(events, cur, length), limit);
180 count++; 273 count++;
181 274
182 cur += length; 275 cur += length;
183 276
184 // Length and max number of requests for the subsequent intervals. 277 // Length and max number of requests for the subsequent intervals.
185 length = 60*60*1000; // 60 minutes 278 length = 60*60*1000; // 60 minutes
186 limit = 12; // maxminum nr of requests in the next 60 minutes 279 limit = 12; // maxminum nr of requests in the next 60 minutes
187 } 280 }
188 281
189 EXPECT_GE(count, 11) 282 EXPECT_GE(count, 11)
190 << "No enough requests were fired during the test run."; 283 << "No enough requests were fired during the test run.";
191 } 284 }
192 285
193 void ExecuteTest(const std::string& homepage_location) {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 // The first unexptected request of the policy subsystem will stop the
196 // message loop.
197 // This code relies on the fact that an InSequence object is active.
198 EXPECT_CALL(*(factory_.get()), Intercept(_, _, _)).
199 Times(AtMost(1)).
200 WillOnce(InvokeWithoutArgs(
201 this,
202 &CloudPolicySubsystemTest::StopMessageLoop));
203 loop_.RunAllPending();
204
205 // Test conditions.
206 EXPECT_EQ(CloudPolicySubsystem::SUCCESS, cloud_policy_subsystem_->state());
207 StringValue homepage_value(homepage_location);
208 VerifyPolicy(kPolicyHomepageLocation, &homepage_value);
209 VerifyServerLoad();
210 }
211
212 scoped_ptr<TestingPolicyURLFetcherFactory> factory_;
213
214 private:
215 ScopedTempDir temp_user_data_dir_; 286 ScopedTempDir temp_user_data_dir_;
216 287
217 MessageLoop loop_; 288 MessageLoop loop_;
218 BrowserThread ui_thread_; 289 BrowserThread ui_thread_;
219 BrowserThread io_thread_; 290 BrowserThread io_thread_;
220 291
221 scoped_ptr<EventLogger> logger_; 292 scoped_ptr<EventLogger> logger_;
222 scoped_ptr<TestingIdentityStrategy> identity_strategy_; 293 scoped_ptr<TestingIdentityStrategy> identity_strategy_;
223 scoped_ptr<CloudPolicySubsystem> cloud_policy_subsystem_; 294 scoped_ptr<CloudPolicySubsystem> cloud_policy_subsystem_;
224 scoped_ptr<PrefService> prefs_; 295 scoped_ptr<PrefService> prefs_;
225 CloudPolicyCacheBase* cache_; 296 CloudPolicyCacheBase* cache_;
226 297
227 DISALLOW_COPY_AND_ASSIGN(CloudPolicySubsystemTest); 298 scoped_ptr<TestingPolicyURLFetcherFactory> factory_;
299
300 DISALLOW_COPY_AND_ASSIGN(CloudPolicySubsystemTestBase);
228 }; 301 };
229 302
230 // An action that returns an URLRequestJob with an HTTP error code. 303 // A parameterized test case that simulates 100 failed registration attempts,
231 ACTION_P(CreateFailedResponse, http_error_code) { 304 // then a successful one, then 100 failed policy fetch attempts and then 100
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 305 // successful policy fetches. The two parameters are the error codes for the
233 em::DeviceManagementResponse response_data; 306 // failed registration and policy responses.
234 307
235 arg2->response_data = response_data.SerializeAsString(); 308 class CombinedTestDesc {
236 arg2->response_code = http_error_code; 309 public:
310 CombinedTestDesc(int registration_error_code, int policy_error_code)
311 : registration_error_code_(registration_error_code),
312 policy_error_code_(policy_error_code) {
313 }
314
315 ~CombinedTestDesc() {}
316
317 int registration_error_code() const { return registration_error_code_; }
318 int policy_error_code() const { return policy_error_code_; }
319
320 private:
321 int registration_error_code_;
322 int policy_error_code_;
323 };
324
325 class CloudPolicySubsystemCombinedTest
326 : public CloudPolicySubsystemTestBase<
327 testing::TestWithParam<CombinedTestDesc> > {
328 };
329
330 TEST_P(CloudPolicySubsystemCombinedTest, Combined) {
331 InSequence s;
332 ExpectFailedRegistration(100, GetParam().registration_error_code());
333 ExpectSuccessfulRegistration();
334 ExpectFailedPolicy(100, GetParam().policy_error_code());
335 ExpectSuccessfulPolicy(100, "http://www.google.com");
336 ExpectSuccessfulPolicy(1, "http://www.chromium.org");
337 ExecuteTest();
338 VerifyTest("http://www.chromium.org");
237 } 339 }
238 340
239 // An action that returns an URLRequestJob with a successful device 341 // A random sample of error code pairs. Note that the following policy error
240 // registration response. 342 // codes (401, 403, 410) make the policy subsystem to try and reregister, and
241 ACTION_P(CreateSuccessfulRegisterResponse, token) { 343 // that is not expected in these tests.
242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 344 INSTANTIATE_TEST_CASE_P(
243 em::DeviceManagementResponse response_data; 345 CloudPolicySubsystemCombinedTestInstance,
244 response_data.mutable_register_response()->set_device_management_token(token); 346 CloudPolicySubsystemCombinedTest,
347 testing::Values(
348 CombinedTestDesc(403, 400),
349 CombinedTestDesc(403, 404),
350 CombinedTestDesc(403, 412),
351 CombinedTestDesc(403, 500),
352 CombinedTestDesc(403, 503),
353 CombinedTestDesc(403, 902),
354 CombinedTestDesc(902, 400),
355 CombinedTestDesc(503, 404),
356 CombinedTestDesc(500, 412),
357 CombinedTestDesc(412, 500),
358 CombinedTestDesc(404, 503),
359 CombinedTestDesc(400, 902)));
245 360
246 arg2->response_data = response_data.SerializeAsString(); 361 // A parameterized test case that simulates 100 failed registration attempts,
247 arg2->response_code = 200; 362 // then a successful one, and then a succesful policy fetch. The parameter is
363 // the error code returned for registration attempts.
364
365 class CloudPolicySubsystemRegistrationTest
366 : public CloudPolicySubsystemTestBase<testing::TestWithParam<int> > {
367 };
368
369 TEST_P(CloudPolicySubsystemRegistrationTest, Registration) {
370 InSequence s;
371 ExpectFailedRegistration(100, GetParam());
372 ExpectSuccessfulRegistration();
373 ExpectSuccessfulPolicy(1, "http://www.youtube.com");
374 ExecuteTest();
375 VerifyTest("http://www.youtube.com");
248 } 376 }
249 377
250 // An action that returns an URLRequestJob with a successful policy response. 378 INSTANTIATE_TEST_CASE_P(
251 ACTION_P(CreateSuccessfulPolicyResponse, homepage_location) { 379 CloudPolicySubsystemRegistrationTestInstance,
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 380 CloudPolicySubsystemRegistrationTest,
253 em::CloudPolicySettings settings; 381 // For the case of 401 see CloudPolicySubsystemRegistrationFailureTest
254 settings.mutable_homepagelocation()->set_homepagelocation(homepage_location); 382 testing::Values(400, 403, 404, 410, 412, 500, 503, 902));
255 em::PolicyData policy_data;
256 policy_data.set_policy_type(kPolicyType);
257 policy_data.set_policy_value(settings.SerializeAsString());
258 383
259 em::DeviceManagementResponse response_data; 384 // A test case that verifies that the subsystem understands the "not managed"
260 em::DevicePolicyResponse* policy_response = 385 // response from the server.
261 response_data.mutable_policy_response();
262 em::PolicyFetchResponse* fetch_response = policy_response->add_response();
263 fetch_response->set_error_code(200);
264 fetch_response->set_policy_data(policy_data.SerializeAsString());
265 386
266 arg2->response_data = response_data.SerializeAsString(); 387 class CloudPolicySubsystemRegistrationFailureTest
267 arg2->response_code = 200; 388 : public CloudPolicySubsystemTestBase<testing::Test> {
389 };
390
391 TEST_F(CloudPolicySubsystemRegistrationFailureTest, RegistrationFailure) {
392 InSequence s;
393 ExpectFailedRegistration(1, 401);
394 ExecuteTest();
395 VerifyState(CloudPolicySubsystem::BAD_GAIA_TOKEN);
268 } 396 }
269 397
270 TEST_F(CloudPolicySubsystemTest, SuccessAfterSingleErrors) { 398 // A parameterized test case that simulates a successful registration, then 100
271 InSequence c; 399 // failed policy fetch attempts and then a successful one. The parameter is
400 // the error code returned for failed policy attempts.
272 401
273 EXPECT_CALL(*(factory_.get()), Intercept(kGaiaAuthHeader, "register", _)). 402 class CloudPolicySubsystemPolicyTest
274 WillOnce(CreateFailedResponse(901)); 403 : public CloudPolicySubsystemTestBase<testing::TestWithParam<int> > {
275 EXPECT_CALL(*(factory_.get()), Intercept(kGaiaAuthHeader, "register", _)). 404 };
276 WillOnce(CreateSuccessfulRegisterResponse(kDMToken));
277 405
278 EXPECT_CALL(*(factory_.get()), Intercept(kDMAuthHeader, "policy", _)). 406 TEST_P(CloudPolicySubsystemPolicyTest, Policy) {
279 WillOnce(CreateFailedResponse(501)); 407 InSequence s;
280 EXPECT_CALL(*(factory_.get()), Intercept(kDMAuthHeader, "policy", _)). 408 ExpectSuccessfulRegistration();
281 Times(200). 409 ExpectFailedPolicy(100, GetParam());
282 WillRepeatedly(CreateSuccessfulPolicyResponse("http://www.google.com")); 410 ExpectSuccessfulPolicy(1, "http://www.youtube.com");
283 EXPECT_CALL(*(factory_.get()), Intercept(kDMAuthHeader, "policy", _)). 411 ExecuteTest();
284 WillOnce(CreateSuccessfulPolicyResponse("http://www.chromium.org")); 412 VerifyTest("http://www.youtube.com");
285
286 ExecuteTest("http://www.chromium.org");
287 } 413 }
288 414
289 TEST_F(CloudPolicySubsystemTest, SuccessAfterRegistrationErrors) { 415 INSTANTIATE_TEST_CASE_P(
290 InSequence c; 416 CloudPolicySubsystemPolicyTestInstance,
417 CloudPolicySubsystemPolicyTest,
418 testing::Values(400, 404, 412, 500, 503, 902));
291 419
292 EXPECT_CALL(*(factory_.get()), Intercept(kGaiaAuthHeader, "register", _)). 420 // A parameterized test case that simulates a successful registration, then 40
293 Times(200). 421 // failed policy fetch attempts and a successful registration after each of
294 WillRepeatedly(CreateFailedResponse(901)); 422 // them. The parameter is the error code returned for registration attempts.
295 EXPECT_CALL(*(factory_.get()), Intercept(kGaiaAuthHeader, "register", _)).
296 WillOnce(CreateSuccessfulRegisterResponse(kDMToken));
297 423
298 EXPECT_CALL(*(factory_.get()), Intercept(kDMAuthHeader, "policy", _)). 424 class CloudPolicySubsystemPolicyReregisterTest
299 WillOnce(CreateSuccessfulPolicyResponse("http://www.example.com")); 425 : public CloudPolicySubsystemTestBase<testing::TestWithParam<int> > {
426 };
300 427
301 ExecuteTest("http://www.example.com"); 428 TEST_P(CloudPolicySubsystemPolicyReregisterTest, Policy) {
429 InSequence s;
430 for (int i = 0; i < 40; i++) {
431 ExpectSuccessfulRegistration();
432 ExpectFailedPolicy(1, GetParam());
433 }
434 ExpectSuccessfulRegistration();
435 ExpectSuccessfulPolicy(1, "http://www.youtube.com");
436 ExecuteTest();
437 VerifyTest("http://www.youtube.com");
302 } 438 }
303 439
440 INSTANTIATE_TEST_CASE_P(
441 CloudPolicySubsystemPolicyReregisterTestInstance,
442 CloudPolicySubsystemPolicyReregisterTest,
443 testing::Values(401, 403, 410));
444
304 } // policy 445 } // policy
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698