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.
5 #include "chrome/browser/chromeos/policy/device_status_collector.h"
7 #include "base/environment.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/prefs/testing_pref_service.h"
13 #include "base/run_loop.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "chrome/browser/chromeos/login/mock_user_manager.h"
16 #include "chrome/browser/chromeos/login/user_manager.h"
17 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
18 #include "chrome/browser/chromeos/settings/cros_settings.h"
19 #include "chrome/browser/chromeos/settings/device_settings_service.h"
20 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
21 #include "chrome/browser/policy/browser_policy_connector.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/testing_browser_process.h"
24 #include "chromeos/dbus/dbus_thread_manager.h"
25 #include "chromeos/dbus/shill_device_client.h"
26 #include "chromeos/network/network_handler.h"
27 #include "chromeos/settings/cros_settings_names.h"
28 #include "chromeos/settings/cros_settings_provider.h"
29 #include "chromeos/system/mock_statistics_provider.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/geolocation_provider.h"
32 #include "content/public/test/test_browser_thread.h"
33 #include "content/public/test/test_utils.h"
34 #include "policy/proto/device_management_backend.pb.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "third_party/cros_system_api/dbus/service_constants.h"
39 using ::testing::DoAll
;
40 using ::testing::NotNull
;
41 using ::testing::Return
;
42 using ::testing::SetArgPointee
;
45 using base::TimeDelta
;
47 namespace em
= enterprise_management
;
51 const int64 kMillisecondsPerDay
= Time::kMicrosecondsPerDay
/ 1000;
53 scoped_ptr
<content::Geoposition
> mock_position_to_return_next
;
55 void SetMockPositionToReturnNext(const content::Geoposition
&position
) {
56 mock_position_to_return_next
.reset(new content::Geoposition(position
));
59 void MockPositionUpdateRequester(
60 const content::GeolocationProvider::LocationUpdateCallback
& callback
) {
61 if (!mock_position_to_return_next
.get())
64 // If the fix is invalid, the DeviceStatusCollector will immediately request
65 // another update when it receives the callback. This is desirable and safe in
66 // real life where geolocation updates arrive asynchronously. In this testing
67 // harness, the callback is invoked synchronously upon request, leading to a
68 // request-callback loop. The loop is broken by returning the mock position
70 scoped_ptr
<content::Geoposition
> position(
71 mock_position_to_return_next
.release());
72 callback
.Run(*position
);
75 class TestingDeviceStatusCollector
: public policy::DeviceStatusCollector
{
77 TestingDeviceStatusCollector(
78 PrefService
* local_state
,
79 chromeos::system::StatisticsProvider
* provider
,
80 policy::DeviceStatusCollector::LocationUpdateRequester
*
81 location_update_requester
)
82 : policy::DeviceStatusCollector(
85 location_update_requester
) {
86 // Set the baseline time to a fixed value (1 AM) to prevent test flakiness
87 // due to a single activity period spanning two days.
88 SetBaselineTime(Time::Now().LocalMidnight() + TimeDelta::FromHours(1));
91 void Simulate(IdleState
* states
, int len
) {
92 for (int i
= 0; i
< len
; i
++)
93 IdleStateCallback(states
[i
]);
96 void set_max_stored_past_activity_days(unsigned int value
) {
97 max_stored_past_activity_days_
= value
;
100 void set_max_stored_future_activity_days(unsigned int value
) {
101 max_stored_future_activity_days_
= value
;
104 // Reset the baseline time.
105 void SetBaselineTime(Time time
) {
106 baseline_time_
= time
;
107 baseline_offset_periods_
= 0;
111 virtual void CheckIdleState() OVERRIDE
{
112 // This should never be called in testing, as it results in a dbus call.
116 // Each time this is called, returns a time that is a fixed increment
117 // later than the previous time.
118 virtual Time
GetCurrentTime() OVERRIDE
{
119 int poll_interval
= policy::DeviceStatusCollector::kIdlePollIntervalSeconds
;
120 return baseline_time_
+
121 TimeDelta::FromSeconds(poll_interval
* baseline_offset_periods_
++);
125 // Baseline time for the fake times returned from GetCurrentTime().
128 // The number of simulated periods since the baseline time.
129 int baseline_offset_periods_
;
132 // Return the total number of active milliseconds contained in a device
134 int64
GetActiveMilliseconds(em::DeviceStatusReportRequest
& status
) {
135 int64 active_milliseconds
= 0;
136 for (int i
= 0; i
< status
.active_period_size(); i
++) {
137 active_milliseconds
+= status
.active_period(i
).active_duration();
139 return active_milliseconds
;
146 // Though it is a unit test, this test is linked with browser_tests so that it
147 // runs in a separate process. The intention is to avoid overriding the timezone
148 // environment variable for other tests.
149 class DeviceStatusCollectorTest
: public testing::Test
{
151 DeviceStatusCollectorTest()
152 : ui_thread_(content::BrowserThread::UI
, &message_loop_
),
153 file_thread_(content::BrowserThread::FILE, &message_loop_
),
154 io_thread_(content::BrowserThread::IO
, &message_loop_
),
155 user_manager_(new chromeos::MockUserManager()),
156 user_manager_enabler_(user_manager_
) {
157 // Run this test with a well-known timezone so that Time::LocalMidnight()
158 // returns the same values on all machines.
159 scoped_ptr
<base::Environment
> env(base::Environment::Create());
160 env
->SetVar("TZ", "UTC");
162 TestingDeviceStatusCollector::RegisterPrefs(prefs_
.registry());
164 EXPECT_CALL(statistics_provider_
, GetMachineStatistic(_
, NotNull()))
165 .WillRepeatedly(Return(false));
167 // Remove the real DeviceSettingsProvider and replace it with a stub.
168 cros_settings_
= chromeos::CrosSettings::Get();
169 device_settings_provider_
=
170 cros_settings_
->GetProvider(chromeos::kReportDeviceVersionInfo
);
171 EXPECT_TRUE(device_settings_provider_
!= NULL
);
173 cros_settings_
->RemoveSettingsProvider(device_settings_provider_
));
174 cros_settings_
->AddSettingsProvider(&stub_settings_provider_
);
176 // Set up fake install attributes.
177 StubEnterpriseInstallAttributes
* attributes
=
178 new StubEnterpriseInstallAttributes();
179 attributes
->SetDomain("managed.com");
180 attributes
->SetRegistrationUser("user@managed.com");
181 BrowserPolicyConnector::SetInstallAttributesForTesting(attributes
);
183 RestartStatusCollector();
186 virtual ~DeviceStatusCollectorTest() {
187 // Finish pending tasks.
188 content::BrowserThread::GetBlockingPool()->FlushForTesting();
189 message_loop_
.RunUntilIdle();
191 // Restore the real DeviceSettingsProvider.
193 cros_settings_
->RemoveSettingsProvider(&stub_settings_provider_
));
194 cros_settings_
->AddSettingsProvider(device_settings_provider_
);
197 void RestartStatusCollector() {
198 policy::DeviceStatusCollector::LocationUpdateRequester callback
=
199 base::Bind(&MockPositionUpdateRequester
);
200 status_collector_
.reset(
201 new TestingDeviceStatusCollector(&prefs_
,
202 &statistics_provider_
,
208 status_collector_
->GetDeviceStatus(&status_
);
211 void CheckThatNoLocationIsReported() {
213 EXPECT_FALSE(status_
.has_device_location());
216 void CheckThatAValidLocationIsReported() {
217 // Checks that a location is being reported which matches the valid fix
218 // set using SetMockPositionToReturnNext().
220 EXPECT_TRUE(status_
.has_device_location());
221 em::DeviceLocation location
= status_
.device_location();
222 if (location
.has_error_code())
223 EXPECT_EQ(em::DeviceLocation::ERROR_CODE_NONE
, location
.error_code());
224 EXPECT_TRUE(location
.has_latitude());
225 EXPECT_TRUE(location
.has_longitude());
226 EXPECT_TRUE(location
.has_accuracy());
227 EXPECT_TRUE(location
.has_timestamp());
228 EXPECT_FALSE(location
.has_altitude());
229 EXPECT_FALSE(location
.has_altitude_accuracy());
230 EXPECT_FALSE(location
.has_heading());
231 EXPECT_FALSE(location
.has_speed());
232 EXPECT_FALSE(location
.has_error_message());
233 EXPECT_DOUBLE_EQ(4.3, location
.latitude());
234 EXPECT_DOUBLE_EQ(-7.8, location
.longitude());
235 EXPECT_DOUBLE_EQ(3., location
.accuracy());
236 // Check that the timestamp is not older than ten minutes.
237 EXPECT_TRUE(Time::Now() - Time::FromDoubleT(location
.timestamp() / 1000.) <
238 TimeDelta::FromMinutes(10));
241 void CheckThatALocationErrorIsReported() {
243 EXPECT_TRUE(status_
.has_device_location());
244 em::DeviceLocation location
= status_
.device_location();
245 EXPECT_TRUE(location
.has_error_code());
246 EXPECT_EQ(em::DeviceLocation::ERROR_CODE_POSITION_UNAVAILABLE
,
247 location
.error_code());
251 // Convenience method.
252 int64
ActivePeriodMilliseconds() {
253 return policy::DeviceStatusCollector::kIdlePollIntervalSeconds
* 1000;
256 // Since this is a unit test running in browser_tests we must do additional
257 // unit test setup and make a TestingBrowserProcess. Must be first member.
258 TestingBrowserProcessInitializer initializer_
;
259 base::MessageLoopForUI message_loop_
;
260 content::TestBrowserThread ui_thread_
;
261 content::TestBrowserThread file_thread_
;
262 content::TestBrowserThread io_thread_
;
264 TestingPrefServiceSimple prefs_
;
265 chromeos::system::MockStatisticsProvider statistics_provider_
;
266 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
267 chromeos::ScopedTestCrosSettings test_cros_settings_
;
268 chromeos::CrosSettings
* cros_settings_
;
269 chromeos::CrosSettingsProvider
* device_settings_provider_
;
270 chromeos::StubCrosSettingsProvider stub_settings_provider_
;
271 chromeos::MockUserManager
* user_manager_
;
272 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
273 em::DeviceStatusReportRequest status_
;
274 scoped_ptr
<TestingDeviceStatusCollector
> status_collector_
;
277 TEST_F(DeviceStatusCollectorTest
, AllIdle
) {
278 IdleState test_states
[] = {
283 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
285 // Test reporting with no data.
287 EXPECT_EQ(0, status_
.active_period_size());
288 EXPECT_EQ(0, GetActiveMilliseconds(status_
));
290 // Test reporting with a single idle sample.
291 status_collector_
->Simulate(test_states
, 1);
293 EXPECT_EQ(0, status_
.active_period_size());
294 EXPECT_EQ(0, GetActiveMilliseconds(status_
));
296 // Test reporting with multiple consecutive idle samples.
297 status_collector_
->Simulate(test_states
,
298 sizeof(test_states
) / sizeof(IdleState
));
300 EXPECT_EQ(0, status_
.active_period_size());
301 EXPECT_EQ(0, GetActiveMilliseconds(status_
));
304 TEST_F(DeviceStatusCollectorTest
, AllActive
) {
305 IdleState test_states
[] = {
310 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
312 // Test a single active sample.
313 status_collector_
->Simulate(test_states
, 1);
315 EXPECT_EQ(1, status_
.active_period_size());
316 EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
317 status_
.clear_active_period(); // Clear the result protobuf.
319 // Test multiple consecutive active samples.
320 status_collector_
->Simulate(test_states
,
321 sizeof(test_states
) / sizeof(IdleState
));
323 EXPECT_EQ(1, status_
.active_period_size());
324 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
327 TEST_F(DeviceStatusCollectorTest
, MixedStates
) {
328 IdleState test_states
[] = {
337 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
338 status_collector_
->Simulate(test_states
,
339 sizeof(test_states
) / sizeof(IdleState
));
341 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
344 TEST_F(DeviceStatusCollectorTest
, StateKeptInPref
) {
345 IdleState test_states
[] = {
353 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
354 status_collector_
->Simulate(test_states
,
355 sizeof(test_states
) / sizeof(IdleState
));
357 // Process the list a second time after restarting the collector. It should be
358 // able to count the active periods found by the original collector, because
359 // the results are stored in a pref.
360 RestartStatusCollector();
361 status_collector_
->Simulate(test_states
,
362 sizeof(test_states
) / sizeof(IdleState
));
365 EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
368 TEST_F(DeviceStatusCollectorTest
, Times
) {
369 IdleState test_states
[] = {
377 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
378 status_collector_
->Simulate(test_states
,
379 sizeof(test_states
) / sizeof(IdleState
));
381 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
384 TEST_F(DeviceStatusCollectorTest
, MaxStoredPeriods
) {
385 IdleState test_states
[] = {
389 const int kMaxDays
= 10;
391 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
392 status_collector_
->set_max_stored_past_activity_days(kMaxDays
- 1);
393 status_collector_
->set_max_stored_future_activity_days(1);
394 Time baseline
= Time::Now().LocalMidnight();
396 // Simulate 12 active periods.
397 for (int i
= 0; i
< kMaxDays
+ 2; i
++) {
398 status_collector_
->Simulate(test_states
,
399 sizeof(test_states
) / sizeof(IdleState
));
400 // Advance the simulated clock by a day.
401 baseline
+= TimeDelta::FromDays(1);
402 status_collector_
->SetBaselineTime(baseline
);
405 // Check that we don't exceed the max number of periods.
407 EXPECT_EQ(kMaxDays
- 1, status_
.active_period_size());
409 // Simulate some future times.
410 for (int i
= 0; i
< kMaxDays
+ 2; i
++) {
411 status_collector_
->Simulate(test_states
,
412 sizeof(test_states
) / sizeof(IdleState
));
413 // Advance the simulated clock by a day.
414 baseline
+= TimeDelta::FromDays(1);
415 status_collector_
->SetBaselineTime(baseline
);
417 // Set the clock back so the previous simulated times are in the future.
418 baseline
-= TimeDelta::FromDays(20);
419 status_collector_
->SetBaselineTime(baseline
);
421 // Collect one more data point to trigger pruning.
422 status_collector_
->Simulate(test_states
, 1);
424 // Check that we don't exceed the max number of periods.
425 status_
.clear_active_period();
427 EXPECT_LT(status_
.active_period_size(), kMaxDays
);
430 TEST_F(DeviceStatusCollectorTest
, ActivityTimesDisabledByDefault
) {
431 // If the pref for collecting device activity times isn't explicitly turned
432 // on, no data on activity times should be reported.
434 IdleState test_states
[] = {
439 status_collector_
->Simulate(test_states
,
440 sizeof(test_states
) / sizeof(IdleState
));
442 EXPECT_EQ(0, status_
.active_period_size());
443 EXPECT_EQ(0, GetActiveMilliseconds(status_
));
446 TEST_F(DeviceStatusCollectorTest
, ActivityCrossingMidnight
) {
447 IdleState test_states
[] = {
450 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
452 // Set the baseline time to 10 seconds after midnight.
453 status_collector_
->SetBaselineTime(
454 Time::Now().LocalMidnight() + TimeDelta::FromSeconds(10));
456 status_collector_
->Simulate(test_states
, 1);
458 ASSERT_EQ(2, status_
.active_period_size());
460 em::ActiveTimePeriod period0
= status_
.active_period(0);
461 em::ActiveTimePeriod period1
= status_
.active_period(1);
462 EXPECT_EQ(ActivePeriodMilliseconds() - 10000, period0
.active_duration());
463 EXPECT_EQ(10000, period1
.active_duration());
465 em::TimePeriod time_period0
= period0
.time_period();
466 em::TimePeriod time_period1
= period1
.time_period();
468 EXPECT_EQ(time_period0
.end_timestamp(), time_period1
.start_timestamp());
470 // Ensure that the start and end times for the period are a day apart.
471 EXPECT_EQ(time_period0
.end_timestamp() - time_period0
.start_timestamp(),
472 kMillisecondsPerDay
);
473 EXPECT_EQ(time_period1
.end_timestamp() - time_period1
.start_timestamp(),
474 kMillisecondsPerDay
);
477 TEST_F(DeviceStatusCollectorTest
, ActivityTimesKeptUntilSubmittedSuccessfully
) {
478 IdleState test_states
[] = {
482 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
484 status_collector_
->Simulate(test_states
, 2);
486 EXPECT_EQ(2 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
487 em::DeviceStatusReportRequest
first_status(status_
);
489 // The collector returns the same status again.
491 EXPECT_EQ(first_status
.SerializeAsString(), status_
.SerializeAsString());
493 // After indicating a successful submit, the submitted status gets cleared,
494 // but what got collected meanwhile sticks around.
495 status_collector_
->Simulate(test_states
, 1);
496 status_collector_
->OnSubmittedSuccessfully();
498 EXPECT_EQ(ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
501 TEST_F(DeviceStatusCollectorTest
, DevSwitchBootMode
) {
502 // Test that boot mode data is not reported if the pref is not turned on.
503 EXPECT_CALL(statistics_provider_
,
504 GetMachineStatistic("devsw_boot", NotNull()))
505 .WillRepeatedly(DoAll(SetArgPointee
<1>("0"), Return(true)));
507 EXPECT_FALSE(status_
.has_boot_mode());
509 // Turn the pref on, and check that the status is reported iff the
510 // statistics provider returns valid data.
511 cros_settings_
->SetBoolean(chromeos::kReportDeviceBootMode
, true);
513 EXPECT_CALL(statistics_provider_
,
514 GetMachineStatistic("devsw_boot", NotNull()))
515 .WillOnce(DoAll(SetArgPointee
<1>("(error)"), Return(true)));
517 EXPECT_FALSE(status_
.has_boot_mode());
519 EXPECT_CALL(statistics_provider_
,
520 GetMachineStatistic("devsw_boot", NotNull()))
521 .WillOnce(DoAll(SetArgPointee
<1>(" "), Return(true)));
523 EXPECT_FALSE(status_
.has_boot_mode());
525 EXPECT_CALL(statistics_provider_
,
526 GetMachineStatistic("devsw_boot", NotNull()))
527 .WillOnce(DoAll(SetArgPointee
<1>("0"), Return(true)));
529 EXPECT_EQ("Verified", status_
.boot_mode());
531 EXPECT_CALL(statistics_provider_
,
532 GetMachineStatistic("devsw_boot", NotNull()))
533 .WillOnce(DoAll(SetArgPointee
<1>("1"), Return(true)));
535 EXPECT_EQ("Dev", status_
.boot_mode());
538 TEST_F(DeviceStatusCollectorTest
, VersionInfo
) {
539 // When the pref to collect this data is not enabled, expect that none of
540 // the fields are present in the protobuf.
542 EXPECT_FALSE(status_
.has_browser_version());
543 EXPECT_FALSE(status_
.has_os_version());
544 EXPECT_FALSE(status_
.has_firmware_version());
546 cros_settings_
->SetBoolean(chromeos::kReportDeviceVersionInfo
, true);
548 EXPECT_TRUE(status_
.has_browser_version());
549 EXPECT_TRUE(status_
.has_os_version());
550 EXPECT_TRUE(status_
.has_firmware_version());
552 // Check that the browser version is not empty. OS version & firmware
553 // don't have any reasonable values inside the unit test, so those
555 EXPECT_NE("", status_
.browser_version());
558 TEST_F(DeviceStatusCollectorTest
, Location
) {
559 content::Geoposition valid_fix
;
560 valid_fix
.latitude
= 4.3;
561 valid_fix
.longitude
= -7.8;
562 valid_fix
.accuracy
= 3.;
563 valid_fix
.timestamp
= Time::Now();
565 content::Geoposition invalid_fix
;
566 invalid_fix
.error_code
=
567 content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE
;
568 invalid_fix
.timestamp
= Time::Now();
570 // Check that when device location reporting is disabled, no location is
572 SetMockPositionToReturnNext(valid_fix
);
573 CheckThatNoLocationIsReported();
575 // Check that when device location reporting is enabled and a valid fix is
576 // available, the location is reported and is stored in local state.
577 SetMockPositionToReturnNext(valid_fix
);
578 cros_settings_
->SetBoolean(chromeos::kReportDeviceLocation
, true);
579 EXPECT_FALSE(prefs_
.GetDictionary(prefs::kDeviceLocation
)->empty());
580 CheckThatAValidLocationIsReported();
582 // Restart the status collector. Check that the last known location has been
583 // retrieved from local state without requesting a geolocation update.
584 SetMockPositionToReturnNext(valid_fix
);
585 RestartStatusCollector();
586 CheckThatAValidLocationIsReported();
587 EXPECT_TRUE(mock_position_to_return_next
.get());
589 // Check that after disabling location reporting again, the last known
590 // location has been cleared from local state and is no longer reported.
591 SetMockPositionToReturnNext(valid_fix
);
592 cros_settings_
->SetBoolean(chromeos::kReportDeviceLocation
, false);
593 // Allow the new pref to propagate to the status collector.
594 message_loop_
.RunUntilIdle();
595 EXPECT_TRUE(prefs_
.GetDictionary(prefs::kDeviceLocation
)->empty());
596 CheckThatNoLocationIsReported();
598 // Check that after enabling location reporting again, an error is reported
599 // if no valid fix is available.
600 SetMockPositionToReturnNext(invalid_fix
);
601 cros_settings_
->SetBoolean(chromeos::kReportDeviceLocation
, true);
602 // Allow the new pref to propagate to the status collector.
603 message_loop_
.RunUntilIdle();
604 CheckThatALocationErrorIsReported();
607 TEST_F(DeviceStatusCollectorTest
, ReportUsers
) {
608 user_manager_
->CreatePublicAccountUser("public@localhost");
609 user_manager_
->AddUser("user0@managed.com");
610 user_manager_
->AddUser("user1@managed.com");
611 user_manager_
->AddUser("user2@managed.com");
612 user_manager_
->AddUser("user3@unmanaged.com");
613 user_manager_
->AddUser("user4@managed.com");
614 user_manager_
->AddUser("user5@managed.com");
616 // Verify that users are not reported by default.
618 EXPECT_EQ(0, status_
.user_size());
620 // Verify that users are reported after enabling the setting.
621 cros_settings_
->SetBoolean(chromeos::kReportDeviceUsers
, true);
623 EXPECT_EQ(5, status_
.user_size());
624 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(0).type());
625 EXPECT_EQ("user0@managed.com", status_
.user(0).email());
626 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(1).type());
627 EXPECT_EQ("user1@managed.com", status_
.user(1).email());
628 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(2).type());
629 EXPECT_EQ("user2@managed.com", status_
.user(2).email());
630 EXPECT_EQ(em::DeviceUser::USER_TYPE_UNMANAGED
, status_
.user(3).type());
631 EXPECT_FALSE(status_
.user(3).has_email());
632 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(4).type());
633 EXPECT_EQ("user4@managed.com", status_
.user(4).email());
635 // Verify that users are no longer reported if setting is disabled.
636 cros_settings_
->SetBoolean(chromeos::kReportDeviceUsers
, false);
638 EXPECT_EQ(0, status_
.user_size());
641 TEST_F(DeviceStatusCollectorTest
, ReportManagedUser
) {
642 // Verify that at least one managed user is reported regardless of list size.
643 user_manager_
->AddUser("user0@unmanaged.com");
644 user_manager_
->AddUser("user1@unmanaged.com");
645 user_manager_
->AddUser("user2@unmanaged.com");
646 user_manager_
->AddUser("user3@unmanaged.com");
647 user_manager_
->AddUser("user4@unmanaged.com");
648 user_manager_
->AddUser("user5@unmanaged.com");
649 user_manager_
->AddUser("user6@managed.com");
650 user_manager_
->AddUser("user7@managed.com");
652 cros_settings_
->SetBoolean(chromeos::kReportDeviceUsers
, true);
654 EXPECT_EQ(7, status_
.user_size());
655 for (int i
= 0; i
< 6; ++i
)
656 EXPECT_EQ(em::DeviceUser::USER_TYPE_UNMANAGED
, status_
.user(i
).type());
657 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(6).type());
658 EXPECT_EQ("user6@managed.com", status_
.user(6).email());
661 // Fake device state.
662 struct FakeDeviceData
{
663 const char* device_path
;
665 const char* object_path
;
666 const char* mac_address
;
669 int expected_type
; // proto enum type value, -1 for not present.
672 static const FakeDeviceData kFakeDevices
[] = {
673 { "/device/ethernet", shill::kTypeEthernet
, "ethernet",
674 "112233445566", "", "",
675 em::NetworkInterface::TYPE_ETHERNET
},
676 { "/device/cellular1", shill::kTypeCellular
, "cellular1",
677 "abcdefabcdef", "A10000009296F2", "",
678 em::NetworkInterface::TYPE_CELLULAR
},
679 { "/device/cellular2", shill::kTypeCellular
, "cellular2",
680 "abcdefabcdef", "", "352099001761481",
681 em::NetworkInterface::TYPE_CELLULAR
},
682 { "/device/wifi", shill::kTypeWifi
, "wifi",
683 "aabbccddeeff", "", "",
684 em::NetworkInterface::TYPE_WIFI
},
685 { "/device/bluetooth", shill::kTypeBluetooth
, "bluetooth",
687 em::NetworkInterface::TYPE_BLUETOOTH
},
688 { "/device/vpn", shill::kTypeVPN
, "vpn",
693 class DeviceStatusCollectorNetworkInterfacesTest
694 : public DeviceStatusCollectorTest
{
696 virtual void SetUp() OVERRIDE
{
697 chromeos::DBusThreadManager::InitializeWithStub();
698 chromeos::NetworkHandler::Initialize();
699 chromeos::ShillDeviceClient::TestInterface
* test_device_client
=
700 chromeos::DBusThreadManager::Get()->GetShillDeviceClient()->
702 test_device_client
->ClearDevices();
703 for (size_t i
= 0; i
< arraysize(kFakeDevices
); ++i
) {
704 const FakeDeviceData
& dev
= kFakeDevices
[i
];
705 test_device_client
->AddDevice(dev
.device_path
, dev
.type
,
707 if (*dev
.mac_address
) {
708 test_device_client
->SetDeviceProperty(
709 dev
.device_path
, shill::kAddressProperty
,
710 base::StringValue(dev
.mac_address
));
713 test_device_client
->SetDeviceProperty(
714 dev
.device_path
, shill::kMeidProperty
,
715 base::StringValue(dev
.meid
));
718 test_device_client
->SetDeviceProperty(
719 dev
.device_path
, shill::kImeiProperty
,
720 base::StringValue(dev
.imei
));
724 // Flush out pending state updates.
725 base::RunLoop().RunUntilIdle();
728 virtual void TearDown() OVERRIDE
{
729 chromeos::NetworkHandler::Shutdown();
730 chromeos::DBusThreadManager::Shutdown();
734 TEST_F(DeviceStatusCollectorNetworkInterfacesTest
, NetworkInterfaces
) {
735 // No interfaces should be reported if the policy is off.
737 EXPECT_EQ(0, status_
.network_interface_size());
739 // Switch the policy on and verify the interface list is present.
740 cros_settings_
->SetBoolean(chromeos::kReportDeviceNetworkInterfaces
, true);
744 for (size_t i
= 0; i
< arraysize(kFakeDevices
); ++i
) {
745 const FakeDeviceData
& dev
= kFakeDevices
[i
];
746 if (dev
.expected_type
== -1)
749 // Find the corresponding entry in reporting data.
750 bool found_match
= false;
751 google::protobuf::RepeatedPtrField
<em::NetworkInterface
>::const_iterator
753 for (iface
= status_
.network_interface().begin();
754 iface
!= status_
.network_interface().end();
756 // Check whether type, field presence and field values match.
757 if (dev
.expected_type
== iface
->type() &&
758 iface
->has_mac_address() == !!*dev
.mac_address
&&
759 iface
->has_meid() == !!*dev
.meid
&&
760 iface
->has_imei() == !!*dev
.imei
&&
761 iface
->mac_address() == dev
.mac_address
&&
762 iface
->meid() == dev
.meid
&&
763 iface
->imei() == dev
.imei
) {
769 EXPECT_TRUE(found_match
) << "No matching interface for fake device " << i
;
773 EXPECT_EQ(count
, status_
.network_interface_size());
776 } // namespace policy