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

Side by Side Diff: chrome/browser/chromeos/session_length_limiter_unittest.cc

Issue 11499012: Add policy for limiting the session length (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased. Not sure why the patch is not applying - bot source out of sync with ToT? Created 8 years 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
OLDNEW
(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 "chrome/browser/chromeos/session_length_limiter.h"
6
7 #include <deque>
8 #include <utility>
9
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/string_number_conversions.h"
18 #include "base/thread_task_runner_handle.h"
19 #include "base/time.h"
20 #include "chrome/browser/chromeos/login/mock_user_manager.h"
21 #include "chrome/browser/chromeos/login/user_manager.h"
22 #include "chrome/browser/chromeos/session_length_limiter_factory.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/test/base/testing_pref_service.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 using ::testing::_;
29 using ::testing::Eq;
30 using ::testing::Invoke;
31 using ::testing::Mock;
32 using ::testing::NiceMock;
33 using ::testing::Pointee;
34 using ::testing::Return;
35
36 namespace chromeos {
37
38 namespace {
39
40 // The interval at which the SessionLengthLimiter fires periodic callbacks.
41 const base::TimeDelta kSessionLengthLimitTimerInterval(
42 base::TimeDelta::FromSeconds(1));
43
44 const base::TimeDelta kZeroTimeDelta;
45 const base::TimeDelta kTenSeconds(base::TimeDelta::FromSeconds(10));
46
47 class MockSessionLengthLimiterObserver : public SessionLengthLimiter::Observer {
48 public:
49 MOCK_METHOD1(SessionTimeRemainingChanged, void(const base::TimeDelta*));
50 };
51
52 class MockSessionLengthLimiterDelegate : public SessionLengthLimiter::Delegate {
53 public:
54 MOCK_CONST_METHOD0(GetCurrentTime, const base::Time(void));
55 MOCK_METHOD0(Logout, void(void));
56 };
57
58 // A SingleThreadTaskRunner that allows the task queue to be inspected and
59 // delayed tasks to be run without waiting for the actual delays to expire.
60 class ImmediateSingleThreadTaskRunner : public base::SingleThreadTaskRunner {
61 public:
62 virtual bool RunsTasksOnCurrentThread() const {
63 return true;
64 }
65
66 virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
67 const base::Closure& task,
68 base::TimeDelta delay) OVERRIDE {
69 tasks_.push_back(std::pair<base::TimeDelta, base::Closure>(delay, task));
70 return true;
71 }
72
73 virtual bool PostNonNestableDelayedTask(
74 const tracked_objects::Location& from_here,
75 const base::Closure& task,
76 base::TimeDelta delay) OVERRIDE {
77 NOTREACHED();
78 return false;
79 }
80
81 void RunTasks() {
82 std::deque<std::pair<base::TimeDelta, base::Closure> > tasks;
83 tasks.swap(tasks_);
84 for (std::deque<std::pair<base::TimeDelta, base::Closure> >::iterator
85 it = tasks.begin(); it != tasks.end(); ++it) {
86 it->second.Run();
87 }
88 }
89
90 const std::deque<std::pair<base::TimeDelta, base::Closure> >& tasks() const {
91 return tasks_;
92 }
93
94 private:
95 std::deque<std::pair<base::TimeDelta, base::Closure> > tasks_;
96
97 virtual ~ImmediateSingleThreadTaskRunner() {}
98 };
99
100 } // namespace
101
102 class SessionLengthLimiterTest : public testing::Test {
103 protected:
104 SessionLengthLimiterTest() : delegate_(NULL) {
105 }
106
107 virtual void SetUp() {
108 old_user_manager_ = UserManager::Set(&mock_user_manager_);
109 runner_ = new ImmediateSingleThreadTaskRunner;
110
111 // Initialize the mock clock to a fixed value, ensuring that timezone
112 // differences or DST changes do not affect the test.
113 now_ = base::Time::UnixEpoch() + base::TimeDelta::FromDays(40 * 365);
114 session_start_time_ = now_;
115
116 SessionLengthLimiterFactory::GetInstance()->RegisterUserPrefs(&prefs_);
117 }
118
119 virtual void TearDown() {
120 session_length_limiter_->Shutdown();
121 UserManager::Set(old_user_manager_);
122 }
123
124 void CreateSessionLengthLimiter() {
125 delegate_ = new NiceMock<MockSessionLengthLimiterDelegate>;
126 ON_CALL(*delegate_, GetCurrentTime())
127 .WillByDefault(Invoke(this, &SessionLengthLimiterTest::GetCurrentTime));
128 EXPECT_CALL(*delegate_, Logout()).Times(0);
129
130 session_length_limiter_.reset(new SessionLengthLimiter(delegate_, &prefs_));
131 }
132
133 void SetHasBrowserRestarted(bool has_browser_restarted) {
134 EXPECT_CALL(mock_user_manager_, HasBrowserRestarted())
135 .WillRepeatedly((Return(has_browser_restarted)));
136 }
137
138 void SetSessionStartTimePref(int64 session_start_time) {
139 prefs_.SetUserPref(prefs::kSessionStartTime,
140 base::Value::CreateStringValue(
141 base::Int64ToString(session_start_time)));
142 }
143
144 void VerifySessionStartTimePref() {
145 base::Time session_start_time(base::Time::FromInternalValue(
146 prefs_.GetInt64(prefs::kSessionStartTime)));
147 EXPECT_EQ(session_start_time_, session_start_time);
148 }
149
150 void SetSessionLengthLimitPref(int64 session_length_limit) {
151 prefs_.SetUserPref(prefs::kSessionLengthLimit,
152 base::Value::CreateIntegerValue(session_length_limit));
153 }
154
155 void UpdateRemainingTime(int64 session_length_limit) {
156 if (!session_length_limit) {
157 remaining_.reset();
158 return;
159 }
160 base::TimeDelta remaining(
161 base::TimeDelta::FromMilliseconds(session_length_limit) -
162 (now_ - session_start_time_));
163 if (remaining < kZeroTimeDelta)
164 remaining = kZeroTimeDelta;
165 remaining_.reset(new base::TimeDelta(remaining));
166 }
167
168 void ExpectSessionTimeRemainingChangedCallback() {
169 EXPECT_CALL(observer_, SessionTimeRemainingChanged(_)).Times(0);
170 if (remaining_) {
171 EXPECT_CALL(observer_, SessionTimeRemainingChanged(
172 Pointee(Eq(*remaining_)))).Times(1);
173 } else {
174 EXPECT_CALL(observer_, SessionTimeRemainingChanged(NULL)).Times(1);
175 }
176 }
177
178 void ExpectLogout() {
179 Mock::VerifyAndClearExpectations(delegate_);
180 EXPECT_CALL(*delegate_, Logout()).Times(1);
181 }
182
183 void VerifyTimerTickIsEnqueued() {
184 ASSERT_EQ(1U, runner_->tasks().size());
185 EXPECT_EQ(kSessionLengthLimitTimerInterval,
186 runner_->tasks().front().first);
187 }
188
189 void VerifyTimerTick() {
190 ExpectSessionTimeRemainingChangedCallback();
191 runner_->RunTasks();
192 Mock::VerifyAndClearExpectations(&observer_);
193 VerifyTimerTickIsEnqueued();
194
195 now_ += kSessionLengthLimitTimerInterval;
196 *remaining_ -= kSessionLengthLimitTimerInterval;
197 if (*remaining_ < kZeroTimeDelta)
198 remaining_.reset(new base::TimeDelta(kZeroTimeDelta));
199 }
200
201 base::Time GetCurrentTime() const {
202 return now_;
203 }
204
205 UserManager* old_user_manager_;
206 MockUserManager mock_user_manager_;
207 scoped_refptr<ImmediateSingleThreadTaskRunner> runner_;
208 TestingPrefService prefs_;
209
210 MockSessionLengthLimiterObserver observer_;
211 MockSessionLengthLimiterDelegate* delegate_; // Owned by
212 // session_length_limiter_.
213
214 base::Time now_;
215 base::Time session_start_time_;
216
217 scoped_ptr<SessionLengthLimiter> session_length_limiter_;
218
219 base::TimeDelta session_length_limit_;
220 scoped_ptr<base::TimeDelta> remaining_;
221 };
222
223 // Verifies that during login, the session start time is written to prefs if no
224 // session start time is present in prefs yet.
225 TEST_F(SessionLengthLimiterTest, StartWithSessionStartTimeUnset) {
226 SetHasBrowserRestarted(false);
227
228 CreateSessionLengthLimiter();
229 VerifySessionStartTimePref();
230 }
231
232 // Verifies that during login, the session start time is written to prefs if an
233 // invalid value is currently present in prefs.
234 TEST_F(SessionLengthLimiterTest, StartWithSessionStartTimeInvalid) {
235 SetHasBrowserRestarted(false);
236
237 SetSessionStartTimePref(0);
238 CreateSessionLengthLimiter();
239 VerifySessionStartTimePref();
240 }
241
242 // Verifies that during login, the session start time is written to prefs if a
243 // value lying in the future is currently present in prefs.
244 TEST_F(SessionLengthLimiterTest, StartWithSessionStartTimeFuture) {
245 SetHasBrowserRestarted(false);
246
247 SetSessionStartTimePref(
248 (now_ + base::TimeDelta::FromHours(2)).ToInternalValue());
249 CreateSessionLengthLimiter();
250 VerifySessionStartTimePref();
251 }
252
253 // Verifies that during login, the session start time is written to prefs if a
254 // previously stored valid value is currently present in prefs.
255 TEST_F(SessionLengthLimiterTest, StartWithSessionStartTimeValid) {
256 SetHasBrowserRestarted(false);
257
258 const base::Time previous_start_time = now_ - base::TimeDelta::FromHours(2);
259 SetSessionStartTimePref(previous_start_time.ToInternalValue());
260 CreateSessionLengthLimiter();
261 VerifySessionStartTimePref();
262 }
263
264 // Verifies that during restart after a crash, the current time is written to
265 // prefs as the session start time if no session start time is present in prefs
266 // yet.
267 TEST_F(SessionLengthLimiterTest, RestartWithSessionStartTimeUnset) {
268 SetHasBrowserRestarted(true);
269
270 CreateSessionLengthLimiter();
271 VerifySessionStartTimePref();
272 }
273
274 // Verifies that during restart after a crash, the current time is written to
275 // prefs as the session start time if an invalid value is currently present in
276 // prefs.
277 TEST_F(SessionLengthLimiterTest, RestartWithSessionStartTimeInvalid) {
278 SetHasBrowserRestarted(true);
279
280 SetSessionStartTimePref(0);
281 CreateSessionLengthLimiter();
282 VerifySessionStartTimePref();
283 }
284
285 // Verifies that during restart after a crash, the current time is written to
286 // prefs as the session start time if a value lying in the future is currently
287 // present in prefs.
288 TEST_F(SessionLengthLimiterTest, RestartWithSessionStartTimeFuture) {
289 SetHasBrowserRestarted(true);
290
291 SetSessionStartTimePref(
292 (now_ + base::TimeDelta::FromHours(2)).ToInternalValue());
293 CreateSessionLengthLimiter();
294 VerifySessionStartTimePref();
295 }
296
297 // Verifies that during restart after a crash, the current time is *not* written
298 // to prefs as the session start time if a previously stored valid value is
299 // currently present in prefs.
300 TEST_F(SessionLengthLimiterTest, RestartWithSessionStartTimeValid) {
301 SetHasBrowserRestarted(true);
302
303 session_start_time_ -= base::TimeDelta::FromHours(2);
304 SetSessionStartTimePref(session_start_time_.ToInternalValue());
305 CreateSessionLengthLimiter();
306 VerifySessionStartTimePref();
307 }
308
309 // Creates a SessionLengthLimiter without setting a limit. Verifies that the
310 // limiter does not start a timer and notifies an observer that there is no
311 // limit.
312 TEST_F(SessionLengthLimiterTest, RunWithoutSessionLengthLimit) {
313 SetHasBrowserRestarted(false);
314
315 base::ThreadTaskRunnerHandle runner_handler(runner_);
316
317 // Do not set any session time limit.
318 UpdateRemainingTime(0);
319
320 // Create a SessionLengthLimiter and check that no timer tick has been
321 // enqueued.
322 CreateSessionLengthLimiter();
323 EXPECT_TRUE(runner_->tasks().empty());
324
325 // Add an observer and check that a callback is immediately received.
326 ExpectSessionTimeRemainingChangedCallback();
327 session_length_limiter_->AddObserver(&observer_);
328
329 session_length_limiter_->RemoveObserver(&observer_);
330 }
331
332 // Creates a SessionLengthLimiter after setting a limit. Verifies that the
333 // limiter starts a timer and notifies an observer about the remaining time as
334 // session time passes. Verifies that when the session time reaches the limit,
335 // a logout occurs.
336 TEST_F(SessionLengthLimiterTest, RunWithSessionLengthLimit) {
337 SetHasBrowserRestarted(false);
338
339 base::ThreadTaskRunnerHandle runner_handler(runner_);
340
341 // Set a 60 second session time limit.
342 const int session_length_limit = 60 * 1000; // 60 seconds.
343 UpdateRemainingTime(session_length_limit);
344 SetSessionLengthLimitPref(session_length_limit);
345
346 // Create a SessionLengthLimiter and check that a first timer tick has been
347 // enqueued.
348 CreateSessionLengthLimiter();
349 VerifyTimerTickIsEnqueued();
350
351 // Add an observer and check that a first callback is immediately received.
352 ExpectSessionTimeRemainingChangedCallback();
353 session_length_limiter_->AddObserver(&observer_);
354 Mock::VerifyAndClearExpectations(&observer_);
355
356 // Check timer ticks until the remaining session time reaches zero.
357 while (*remaining_ > kZeroTimeDelta)
358 VerifyTimerTick();
359
360 // Check that the next timer tick leads to a logout.
361 ExpectLogout();
362 VerifyTimerTick();
363
364 session_length_limiter_->RemoveObserver(&observer_);
365 }
366
367 // Creates a SessionLengthLimiter after setting a 60 second limit, allows 50
368 // seconds of session time to pass, then increases the limit to 90 seconds.
369 // Verifies that the limiter starts a timer and notifies an observer about the
370 // remaining time as session time passes and the limit changes. Verifies that
371 // when the session time reaches the 90 second limit, a logout occurs.
372 TEST_F(SessionLengthLimiterTest, RunAndIncreaseSessionLengthLimit) {
373 SetHasBrowserRestarted(false);
374
375 base::ThreadTaskRunnerHandle runner_handler(runner_);
376
377 // Set a 60 second session time limit.
378 int session_length_limit = 60 * 1000; // 60 seconds.
379 UpdateRemainingTime(session_length_limit);
380 SetSessionLengthLimitPref(session_length_limit);
381
382 // Create a SessionLengthLimiter and check that a first timer tick has been
383 // enqueued.
384 CreateSessionLengthLimiter();
385 VerifyTimerTickIsEnqueued();
386
387 // Add an observer and check that a first callback is immediately received.
388 ExpectSessionTimeRemainingChangedCallback();
389 session_length_limiter_->AddObserver(&observer_);
390 Mock::VerifyAndClearExpectations(&observer_);
391
392 // Check timer ticks for 50 seconds of session time.
393 while (*remaining_ > kTenSeconds)
394 VerifyTimerTick();
395
396 // Check that increasing the session length limit to 90 seconds leads to an
397 // immediate callback.
398 session_length_limit = 90 * 1000; // 90 seconds.
399 UpdateRemainingTime(session_length_limit);
400 ExpectSessionTimeRemainingChangedCallback();
401 SetSessionLengthLimitPref(session_length_limit);
402 Mock::VerifyAndClearExpectations(&observer_);
403
404 // Check that a timer tick is still enqueued.
405 VerifyTimerTickIsEnqueued();
406
407 // Check timer ticks until the remaining session time reaches zero.
408 while (*remaining_ > kZeroTimeDelta)
409 VerifyTimerTick();
410
411 // Check that the next timer tick leads to a logout.
412 ExpectLogout();
413 VerifyTimerTick();
414
415 session_length_limiter_->RemoveObserver(&observer_);
416 }
417
418 // Creates a SessionLengthLimiter after setting a 60 second limit, allows 50
419 // seconds of session time to pass, then decreases the limit to 40 seconds.
420 // Verifies that the limiter starts a timer and notifies an observer about the
421 // remaining time as session time passes and the limit changes. Verifies that
422 // when the limit is decreased to 40 seconds after 50 seconds of session time
423 // has passed, an immediate logout occurs.
424 TEST_F(SessionLengthLimiterTest, RunAndDecreaseSessionLengthLimit) {
425 SetHasBrowserRestarted(false);
426
427 base::ThreadTaskRunnerHandle runner_handler(runner_);
428
429 // Set a 60 second session time limit.
430 int session_length_limit = 60 * 1000; // 60 seconds.
431 UpdateRemainingTime(session_length_limit);
432 SetSessionLengthLimitPref(session_length_limit);
433
434 // Create a SessionLengthLimiter and check that a first timer tick has been
435 // enqueued.
436 CreateSessionLengthLimiter();
437 VerifyTimerTickIsEnqueued();
438
439 // Add an observer and check that a first callback is immediately received.
440 ExpectSessionTimeRemainingChangedCallback();
441 session_length_limiter_->AddObserver(&observer_);
442 Mock::VerifyAndClearExpectations(&observer_);
443
444 // Check timer ticks for 50 seconds of session time.
445 while (*remaining_ > kTenSeconds)
446 VerifyTimerTick();
447
448 // Check that reducing the session length limit below the 50 seconds that
449 // have already elapsed leads to an immediate logout.
450 session_length_limit = 40 * 1000; // 40 seconds.
451 UpdateRemainingTime(session_length_limit);
452 ExpectSessionTimeRemainingChangedCallback();
453 ExpectLogout();
454 SetSessionLengthLimitPref(session_length_limit);
455
456 session_length_limiter_->RemoveObserver(&observer_);
457 }
458
459 // Creates a SessionLengthLimiter after setting a 60 second limit, allows 50
460 // seconds of session time to pass, then removes the limit. Verifies that the
461 // limiter starts a timer and notifies an observer about the remaining time as
462 // session time passes and the limit changes. Verifies that when the limit is
463 // removed, no further notifications and no logout occur.
464 TEST_F(SessionLengthLimiterTest, RunAndRemoveSessionLengthLimit) {
465 SetHasBrowserRestarted(false);
466
467 base::ThreadTaskRunnerHandle runner_handler(runner_);
468
469 // Set a 60 second session time limit.
470 int session_length_limit = 60 * 1000; // 60 seconds.
471 UpdateRemainingTime(session_length_limit);
472 SetSessionLengthLimitPref(session_length_limit);
473
474 // Create a SessionLengthLimiter and check that a first timer tick has been
475 // enqueued.
476 CreateSessionLengthLimiter();
477 VerifyTimerTickIsEnqueued();
478
479 // Add an observer and check that a first callback is immediately received.
480 ExpectSessionTimeRemainingChangedCallback();
481 session_length_limiter_->AddObserver(&observer_);
482 Mock::VerifyAndClearExpectations(&observer_);
483
484 // Check timer ticks for 50 seconds of session time.
485 while (*remaining_ > kTenSeconds)
486 VerifyTimerTick();
487
488 // Check that removing the session length limit leads to an immediate
489 // callback.
490 UpdateRemainingTime(0);
491 ExpectSessionTimeRemainingChangedCallback();
492 prefs_.RemoveUserPref(prefs::kSessionLengthLimit);
493 Mock::VerifyAndClearExpectations(&observer_);
494
495 // Check that the next timer tick does not lead to a callback or logout.
496 EXPECT_CALL(observer_, SessionTimeRemainingChanged(_)).Times(0);
497 now_ += kSessionLengthLimitTimerInterval;
498 runner_->RunTasks();
499
500 session_length_limiter_->RemoveObserver(&observer_);
501 }
502
503 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698