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

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

Issue 11271024: Fix DeviceStatusCollectorTest.MaxStoredPeriods. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 1 month 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 | « chrome/browser/policy/device_status_collector_browsertest.cc ('k') | chrome/chrome_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/policy/device_status_collector.h"
6
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop.h"
10 #include "base/threading/sequenced_worker_pool.h"
11 #include "chrome/browser/chromeos/settings/cros_settings.h"
12 #include "chrome/browser/chromeos/settings/cros_settings_names.h"
13 #include "chrome/browser/chromeos/settings/cros_settings_provider.h"
14 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
15 #include "chrome/browser/chromeos/system/mock_statistics_provider.h"
16 #include "chrome/browser/chromeos/system/statistics_provider.h"
17 #include "chrome/browser/policy/proto/device_management_backend.pb.h"
18 #include "chrome/browser/prefs/pref_service.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/testing_pref_service.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/test/test_browser_thread.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 using ::testing::_;
27 using ::testing::DoAll;
28 using ::testing::NotNull;
29 using ::testing::Return;
30 using ::testing::SetArgPointee;
31 using base::TimeDelta;
32 using base::Time;
33
34 namespace em = enterprise_management;
35
36 namespace {
37
38 const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
39
40 scoped_ptr<content::Geoposition> mock_position_to_return_next;
41
42 void SetMockPositionToReturnNext(const content::Geoposition &position) {
43 mock_position_to_return_next.reset(new content::Geoposition(position));
44 }
45
46 void MockPositionUpdateRequester(
47 const content::GeolocationUpdateCallback& callback) {
48 if (!mock_position_to_return_next.get())
49 return;
50
51 // If the fix is invalid, the DeviceStatusCollector will immediately request
52 // another update when it receives the callback. This is desirable and safe in
53 // real life where geolocation updates arrive asynchronously. In this testing
54 // harness, the callback is invoked synchronously upon request, leading to a
55 // request-callback loop. The loop is broken by returning the mock position
56 // only once.
57 scoped_ptr<content::Geoposition> position(
58 mock_position_to_return_next.release());
59 callback.Run(*position);
60 }
61
62 class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
63 public:
64 TestingDeviceStatusCollector(
65 PrefService* local_state,
66 chromeos::system::StatisticsProvider* provider)
67 : policy::DeviceStatusCollector(local_state,
68 provider,
69 &MockPositionUpdateRequester) {
70 // Set the baseline time to a fixed value (1 AM) to prevent test flakiness
71 // due to a single activity period spanning two days.
72 SetBaselineTime(Time::Now().LocalMidnight() + TimeDelta::FromHours(1));
73 }
74
75 void Simulate(IdleState* states, int len) {
76 for (int i = 0; i < len; i++)
77 IdleStateCallback(states[i]);
78 }
79
80 void set_max_stored_past_activity_days(unsigned int value) {
81 max_stored_past_activity_days_ = value;
82 }
83
84 void set_max_stored_future_activity_days(unsigned int value) {
85 max_stored_future_activity_days_ = value;
86 }
87
88 // Reset the baseline time.
89 void SetBaselineTime(Time time) {
90 baseline_time_ = time;
91 baseline_offset_periods_ = 0;
92 }
93
94 protected:
95 virtual void CheckIdleState() OVERRIDE {
96 // This should never be called in testing, as it results in a dbus call.
97 NOTREACHED();
98 }
99
100 // Each time this is called, returns a time that is a fixed increment
101 // later than the previous time.
102 virtual Time GetCurrentTime() OVERRIDE {
103 int poll_interval = policy::DeviceStatusCollector::kIdlePollIntervalSeconds;
104 return baseline_time_ +
105 TimeDelta::FromSeconds(poll_interval * baseline_offset_periods_++);
106 }
107
108 private:
109 // Baseline time for the fake times returned from GetCurrentTime().
110 Time baseline_time_;
111
112 // The number of simulated periods since the baseline time.
113 int baseline_offset_periods_;
114 };
115
116 // Return the total number of active milliseconds contained in a device
117 // status report.
118 int64 GetActiveMilliseconds(em::DeviceStatusReportRequest& status) {
119 int64 active_milliseconds = 0;
120 for (int i = 0; i < status.active_period_size(); i++) {
121 active_milliseconds += status.active_period(i).active_duration();
122 }
123 return active_milliseconds;
124 }
125
126 } // namespace
127
128 namespace policy {
129
130 class DeviceStatusCollectorTest : public testing::Test {
131 public:
132 DeviceStatusCollectorTest()
133 : message_loop_(MessageLoop::TYPE_UI),
134 ui_thread_(content::BrowserThread::UI, &message_loop_),
135 file_thread_(content::BrowserThread::FILE, &message_loop_),
136 io_thread_(content::BrowserThread::IO, &message_loop_) {
137 TestingDeviceStatusCollector::RegisterPrefs(&prefs_);
138
139 EXPECT_CALL(statistics_provider_, GetMachineStatistic(_, NotNull()))
140 .WillRepeatedly(Return(false));
141
142 // Remove the real DeviceSettingsProvider and replace it with a stub.
143 cros_settings_ = chromeos::CrosSettings::Get();
144 device_settings_provider_ =
145 cros_settings_->GetProvider(chromeos::kReportDeviceVersionInfo);
146 EXPECT_TRUE(device_settings_provider_ != NULL);
147 EXPECT_TRUE(
148 cros_settings_->RemoveSettingsProvider(device_settings_provider_));
149 cros_settings_->AddSettingsProvider(&stub_settings_provider_);
150
151 RestartStatusCollector();
152 }
153
154 ~DeviceStatusCollectorTest() {
155 // Finish pending tasks.
156 content::BrowserThread::GetBlockingPool()->FlushForTesting();
157 message_loop_.RunUntilIdle();
158
159 // Restore the real DeviceSettingsProvider.
160 EXPECT_TRUE(
161 cros_settings_->RemoveSettingsProvider(&stub_settings_provider_));
162 cros_settings_->AddSettingsProvider(device_settings_provider_);
163 }
164
165 void RestartStatusCollector() {
166 status_collector_.reset(
167 new TestingDeviceStatusCollector(&prefs_, &statistics_provider_));
168 }
169
170 void GetStatus() {
171 status_.Clear();
172 status_collector_->GetStatus(&status_);
173 }
174
175 void CheckThatNoLocationIsReported() {
176 GetStatus();
177 EXPECT_FALSE(status_.has_device_location());
178 }
179
180 void CheckThatAValidLocationIsReported() {
181 // Checks that a location is being reported which matches the valid fix
182 // set using SetMockPositionToReturnNext().
183 GetStatus();
184 EXPECT_TRUE(status_.has_device_location());
185 em::DeviceLocation location = status_.device_location();
186 if (location.has_error_code())
187 EXPECT_EQ(em::DeviceLocation::ERROR_CODE_NONE, location.error_code());
188 EXPECT_TRUE(location.has_latitude());
189 EXPECT_TRUE(location.has_longitude());
190 EXPECT_TRUE(location.has_accuracy());
191 EXPECT_TRUE(location.has_timestamp());
192 EXPECT_FALSE(location.has_altitude());
193 EXPECT_FALSE(location.has_altitude_accuracy());
194 EXPECT_FALSE(location.has_heading());
195 EXPECT_FALSE(location.has_speed());
196 EXPECT_FALSE(location.has_error_message());
197 EXPECT_DOUBLE_EQ(4.3, location.latitude());
198 EXPECT_DOUBLE_EQ(-7.8, location.longitude());
199 EXPECT_DOUBLE_EQ(3., location.accuracy());
200 // Check that the timestamp is not older than ten minutes.
201 EXPECT_TRUE(Time::Now() - Time::FromDoubleT(location.timestamp() / 1000.) <
202 TimeDelta::FromMinutes(10));
203 }
204
205 void CheckThatALocationErrorIsReported() {
206 GetStatus();
207 EXPECT_TRUE(status_.has_device_location());
208 em::DeviceLocation location = status_.device_location();
209 EXPECT_TRUE(location.has_error_code());
210 EXPECT_EQ(em::DeviceLocation::ERROR_CODE_POSITION_UNAVAILABLE,
211 location.error_code());
212 }
213
214 protected:
215 // Convenience method.
216 int64 ActivePeriodMilliseconds() {
217 return policy::DeviceStatusCollector::kIdlePollIntervalSeconds * 1000;
218 }
219
220 MessageLoop message_loop_;
221 content::TestBrowserThread ui_thread_;
222 content::TestBrowserThread file_thread_;
223 content::TestBrowserThread io_thread_;
224
225 TestingPrefService prefs_;
226 chromeos::system::MockStatisticsProvider statistics_provider_;
227 scoped_ptr<TestingDeviceStatusCollector> status_collector_;
228 em::DeviceStatusReportRequest status_;
229 chromeos::CrosSettings* cros_settings_;
230 chromeos::CrosSettingsProvider* device_settings_provider_;
231 chromeos::StubCrosSettingsProvider stub_settings_provider_;
232 };
233
234 TEST_F(DeviceStatusCollectorTest, AllIdle) {
235 IdleState test_states[] = {
236 IDLE_STATE_IDLE,
237 IDLE_STATE_IDLE,
238 IDLE_STATE_IDLE
239 };
240 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
241
242 // Test reporting with no data.
243 GetStatus();
244 EXPECT_EQ(0, status_.active_period_size());
245 EXPECT_EQ(0, GetActiveMilliseconds(status_));
246
247 // Test reporting with a single idle sample.
248 status_collector_->Simulate(test_states, 1);
249 GetStatus();
250 EXPECT_EQ(0, status_.active_period_size());
251 EXPECT_EQ(0, GetActiveMilliseconds(status_));
252
253 // Test reporting with multiple consecutive idle samples.
254 status_collector_->Simulate(test_states,
255 sizeof(test_states) / sizeof(IdleState));
256 GetStatus();
257 EXPECT_EQ(0, status_.active_period_size());
258 EXPECT_EQ(0, GetActiveMilliseconds(status_));
259 }
260
261 TEST_F(DeviceStatusCollectorTest, AllActive) {
262 IdleState test_states[] = {
263 IDLE_STATE_ACTIVE,
264 IDLE_STATE_ACTIVE,
265 IDLE_STATE_ACTIVE
266 };
267 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
268
269 // Test a single active sample.
270 status_collector_->Simulate(test_states, 1);
271 GetStatus();
272 EXPECT_EQ(1, status_.active_period_size());
273 EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
274 status_.clear_active_period(); // Clear the result protobuf.
275
276 // Test multiple consecutive active samples.
277 status_collector_->Simulate(test_states,
278 sizeof(test_states) / sizeof(IdleState));
279 GetStatus();
280 EXPECT_EQ(1, status_.active_period_size());
281 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
282 }
283
284 TEST_F(DeviceStatusCollectorTest, MixedStates) {
285 IdleState test_states[] = {
286 IDLE_STATE_ACTIVE,
287 IDLE_STATE_IDLE,
288 IDLE_STATE_ACTIVE,
289 IDLE_STATE_ACTIVE,
290 IDLE_STATE_IDLE,
291 IDLE_STATE_IDLE,
292 IDLE_STATE_ACTIVE
293 };
294 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
295 status_collector_->Simulate(test_states,
296 sizeof(test_states) / sizeof(IdleState));
297 GetStatus();
298 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
299 }
300
301 TEST_F(DeviceStatusCollectorTest, StateKeptInPref) {
302 IdleState test_states[] = {
303 IDLE_STATE_ACTIVE,
304 IDLE_STATE_IDLE,
305 IDLE_STATE_ACTIVE,
306 IDLE_STATE_ACTIVE,
307 IDLE_STATE_IDLE,
308 IDLE_STATE_IDLE
309 };
310 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
311 status_collector_->Simulate(test_states,
312 sizeof(test_states) / sizeof(IdleState));
313
314 // Process the list a second time after restarting the collector. It should be
315 // able to count the active periods found by the original collector, because
316 // the results are stored in a pref.
317 RestartStatusCollector();
318 status_collector_->Simulate(test_states,
319 sizeof(test_states) / sizeof(IdleState));
320
321 GetStatus();
322 EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
323 }
324
325 TEST_F(DeviceStatusCollectorTest, Times) {
326 IdleState test_states[] = {
327 IDLE_STATE_ACTIVE,
328 IDLE_STATE_IDLE,
329 IDLE_STATE_ACTIVE,
330 IDLE_STATE_ACTIVE,
331 IDLE_STATE_IDLE,
332 IDLE_STATE_IDLE
333 };
334 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
335 status_collector_->Simulate(test_states,
336 sizeof(test_states) / sizeof(IdleState));
337 GetStatus();
338 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
339 }
340
341 // Fails after after WebKit roll [132375:132450]
342 // http://crbug.com/157848
343 TEST_F(DeviceStatusCollectorTest, DISABLED_MaxStoredPeriods) {
344 IdleState test_states[] = {
345 IDLE_STATE_ACTIVE,
346 IDLE_STATE_IDLE
347 };
348 unsigned int max_days = 10;
349
350 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
351 status_collector_->set_max_stored_past_activity_days(max_days - 1);
352 status_collector_->set_max_stored_future_activity_days(1);
353 Time baseline = Time::Now().LocalMidnight();
354
355 // Simulate 12 active periods.
356 for (int i = 0; i < static_cast<int>(max_days) + 2; i++) {
357 status_collector_->Simulate(test_states,
358 sizeof(test_states) / sizeof(IdleState));
359 // Advance the simulated clock by a day.
360 baseline += TimeDelta::FromDays(1);
361 status_collector_->SetBaselineTime(baseline);
362 }
363
364 // Check that we don't exceed the max number of periods.
365 GetStatus();
366 EXPECT_EQ(static_cast<int>(max_days), status_.active_period_size());
367
368 // Simulate some future times.
369 for (int i = 0; i < static_cast<int>(max_days) + 2; i++) {
370 status_collector_->Simulate(test_states,
371 sizeof(test_states) / sizeof(IdleState));
372 // Advance the simulated clock by a day.
373 baseline += TimeDelta::FromDays(1);
374 status_collector_->SetBaselineTime(baseline);
375 }
376 // Set the clock back so the previous simulated times are in the future.
377 baseline -= TimeDelta::FromDays(20);
378 status_collector_->SetBaselineTime(baseline);
379
380 // Collect one more data point to trigger pruning.
381 status_collector_->Simulate(test_states, 1);
382
383 // Check that we don't exceed the max number of periods.
384 status_.clear_active_period();
385 GetStatus();
386 EXPECT_LT(status_.active_period_size(), static_cast<int>(max_days));
387 }
388
389 TEST_F(DeviceStatusCollectorTest, ActivityTimesDisabledByDefault) {
390 // If the pref for collecting device activity times isn't explicitly turned
391 // on, no data on activity times should be reported.
392
393 IdleState test_states[] = {
394 IDLE_STATE_ACTIVE,
395 IDLE_STATE_ACTIVE,
396 IDLE_STATE_ACTIVE
397 };
398 status_collector_->Simulate(test_states,
399 sizeof(test_states) / sizeof(IdleState));
400 GetStatus();
401 EXPECT_EQ(0, status_.active_period_size());
402 EXPECT_EQ(0, GetActiveMilliseconds(status_));
403 }
404
405 TEST_F(DeviceStatusCollectorTest, ActivityCrossingMidnight) {
406 IdleState test_states[] = {
407 IDLE_STATE_ACTIVE
408 };
409 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
410
411 // Set the baseline time to 10 seconds after midnight.
412 status_collector_->SetBaselineTime(
413 Time::Now().LocalMidnight() + TimeDelta::FromSeconds(10));
414
415 status_collector_->Simulate(test_states, 1);
416 GetStatus();
417 ASSERT_EQ(2, status_.active_period_size());
418
419 em::ActiveTimePeriod period0 = status_.active_period(0);
420 em::ActiveTimePeriod period1 = status_.active_period(1);
421 EXPECT_EQ(ActivePeriodMilliseconds() - 10000, period0.active_duration());
422 EXPECT_EQ(10000, period1.active_duration());
423
424 em::TimePeriod time_period0 = period0.time_period();
425 em::TimePeriod time_period1 = period1.time_period();
426
427 EXPECT_EQ(time_period0.end_timestamp(), time_period1.start_timestamp());
428
429 // Ensure that the start and end times for the period are a day apart.
430 EXPECT_EQ(time_period0.end_timestamp() - time_period0.start_timestamp(),
431 kMillisecondsPerDay);
432 EXPECT_EQ(time_period1.end_timestamp() - time_period1.start_timestamp(),
433 kMillisecondsPerDay);
434 }
435
436 TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) {
437 // Test that boot mode data is not reported if the pref is not turned on.
438 EXPECT_CALL(statistics_provider_,
439 GetMachineStatistic("devsw_boot", NotNull()))
440 .WillRepeatedly(DoAll(SetArgPointee<1>("0"), Return(true)));
441 GetStatus();
442 EXPECT_FALSE(status_.has_boot_mode());
443
444 // Turn the pref on, and check that the status is reported iff the
445 // statistics provider returns valid data.
446 cros_settings_->SetBoolean(chromeos::kReportDeviceBootMode, true);
447
448 EXPECT_CALL(statistics_provider_,
449 GetMachineStatistic("devsw_boot", NotNull()))
450 .WillOnce(DoAll(SetArgPointee<1>("(error)"), Return(true)));
451 GetStatus();
452 EXPECT_FALSE(status_.has_boot_mode());
453
454 EXPECT_CALL(statistics_provider_,
455 GetMachineStatistic("devsw_boot", NotNull()))
456 .WillOnce(DoAll(SetArgPointee<1>(" "), Return(true)));
457 GetStatus();
458 EXPECT_FALSE(status_.has_boot_mode());
459
460 EXPECT_CALL(statistics_provider_,
461 GetMachineStatistic("devsw_boot", NotNull()))
462 .WillOnce(DoAll(SetArgPointee<1>("0"), Return(true)));
463 GetStatus();
464 EXPECT_EQ("Verified", status_.boot_mode());
465
466 EXPECT_CALL(statistics_provider_,
467 GetMachineStatistic("devsw_boot", NotNull()))
468 .WillOnce(DoAll(SetArgPointee<1>("1"), Return(true)));
469 GetStatus();
470 EXPECT_EQ("Dev", status_.boot_mode());
471 }
472
473 TEST_F(DeviceStatusCollectorTest, VersionInfo) {
474 // When the pref to collect this data is not enabled, expect that none of
475 // the fields are present in the protobuf.
476 GetStatus();
477 EXPECT_FALSE(status_.has_browser_version());
478 EXPECT_FALSE(status_.has_os_version());
479 EXPECT_FALSE(status_.has_firmware_version());
480
481 cros_settings_->SetBoolean(chromeos::kReportDeviceVersionInfo, true);
482 GetStatus();
483 EXPECT_TRUE(status_.has_browser_version());
484 EXPECT_TRUE(status_.has_os_version());
485 EXPECT_TRUE(status_.has_firmware_version());
486
487 // Check that the browser version is not empty. OS version & firmware
488 // don't have any reasonable values inside the unit test, so those
489 // aren't checked.
490 EXPECT_NE("", status_.browser_version());
491 }
492
493 TEST_F(DeviceStatusCollectorTest, Location) {
494 content::Geoposition valid_fix;
495 valid_fix.latitude = 4.3;
496 valid_fix.longitude = -7.8;
497 valid_fix.accuracy = 3.;
498 valid_fix.timestamp = Time::Now();
499
500 content::Geoposition invalid_fix;
501 invalid_fix.error_code =
502 content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
503 invalid_fix.timestamp = Time::Now();
504
505 // Check that when device location reporting is disabled, no location is
506 // reported.
507 SetMockPositionToReturnNext(valid_fix);
508 CheckThatNoLocationIsReported();
509
510 // Check that when device location reporting is enabled and a valid fix is
511 // available, the location is reported and is stored in local state.
512 SetMockPositionToReturnNext(valid_fix);
513 cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
514 EXPECT_FALSE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
515 CheckThatAValidLocationIsReported();
516
517 // Restart the status collector. Check that the last known location has been
518 // retrieved from local state without requesting a geolocation update.
519 SetMockPositionToReturnNext(valid_fix);
520 RestartStatusCollector();
521 CheckThatAValidLocationIsReported();
522 EXPECT_TRUE(mock_position_to_return_next.get());
523
524 // Check that after disabling location reporting again, the last known
525 // location has been cleared from local state and is no longer reported.
526 SetMockPositionToReturnNext(valid_fix);
527 cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, false);
528 // Allow the new pref to propagate to the status collector.
529 message_loop_.RunUntilIdle();
530 EXPECT_TRUE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
531 CheckThatNoLocationIsReported();
532
533 // Check that after enabling location reporting again, an error is reported
534 // if no valid fix is available.
535 SetMockPositionToReturnNext(invalid_fix);
536 cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
537 // Allow the new pref to propagate to the status collector.
538 message_loop_.RunUntilIdle();
539 CheckThatALocationErrorIsReported();
540 }
541
542 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/device_status_collector_browsertest.cc ('k') | chrome/chrome_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698