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"
10 #include "base/bind.h"
11 #include "base/environment.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/prefs/testing_pref_service.h"
17 #include "base/run_loop.h"
18 #include "base/threading/sequenced_worker_pool.h"
19 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
20 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
21 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
22 #include "chrome/browser/chromeos/policy/device_local_account.h"
23 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
24 #include "chrome/browser/chromeos/settings/cros_settings.h"
25 #include "chrome/browser/chromeos/settings/device_settings_service.h"
26 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
27 #include "chrome/common/pref_names.h"
28 #include "chrome/test/base/testing_browser_process.h"
29 #include "chromeos/dbus/cros_disks_client.h"
30 #include "chromeos/dbus/dbus_thread_manager.h"
31 #include "chromeos/dbus/shill_device_client.h"
32 #include "chromeos/dbus/shill_ipconfig_client.h"
33 #include "chromeos/dbus/shill_service_client.h"
34 #include "chromeos/disks/disk_mount_manager.h"
35 #include "chromeos/disks/mock_disk_mount_manager.h"
36 #include "chromeos/network/network_handler.h"
37 #include "chromeos/network/network_state.h"
38 #include "chromeos/network/network_state_handler.h"
39 #include "chromeos/settings/cros_settings_names.h"
40 #include "chromeos/settings/cros_settings_provider.h"
41 #include "chromeos/system/fake_statistics_provider.h"
42 #include "content/public/browser/browser_thread.h"
43 #include "content/public/browser/geolocation_provider.h"
44 #include "content/public/test/test_browser_thread.h"
45 #include "content/public/test/test_utils.h"
46 #include "policy/proto/device_management_backend.pb.h"
47 #include "testing/gmock/include/gmock/gmock.h"
48 #include "testing/gtest/include/gtest/gtest.h"
49 #include "third_party/cros_system_api/dbus/service_constants.h"
51 using ::testing::Return
;
52 using ::testing::ReturnRef
;
54 using base::TimeDelta
;
55 using chromeos::disks::DiskMountManager
;
57 namespace em
= enterprise_management
;
61 const int64 kMillisecondsPerDay
= Time::kMicrosecondsPerDay
/ 1000;
62 const char kKioskAccountId
[] = "kiosk_user@localhost";
63 const char kKioskAppId
[] = "kiosk_app_id";
65 scoped_ptr
<content::Geoposition
> mock_position_to_return_next
;
67 void SetMockPositionToReturnNext(const content::Geoposition
&position
) {
68 mock_position_to_return_next
.reset(new content::Geoposition(position
));
71 void MockPositionUpdateRequester(
72 const content::GeolocationProvider::LocationUpdateCallback
& callback
) {
73 if (!mock_position_to_return_next
.get())
76 // If the fix is invalid, the DeviceStatusCollector will immediately request
77 // another update when it receives the callback. This is desirable and safe in
78 // real life where geolocation updates arrive asynchronously. In this testing
79 // harness, the callback is invoked synchronously upon request, leading to a
80 // request-callback loop. The loop is broken by returning the mock position
82 scoped_ptr
<content::Geoposition
> position(
83 mock_position_to_return_next
.release());
84 callback
.Run(*position
);
87 class TestingDeviceStatusCollector
: public policy::DeviceStatusCollector
{
89 TestingDeviceStatusCollector(
90 PrefService
* local_state
,
91 chromeos::system::StatisticsProvider
* provider
,
92 const policy::DeviceStatusCollector::LocationUpdateRequester
&
93 location_update_requester
,
94 const policy::DeviceStatusCollector::VolumeInfoFetcher
&
96 : policy::DeviceStatusCollector(
99 location_update_requester
,
100 volume_info_fetcher
) {
102 // Set the baseline time to a fixed value (1 AM) to prevent test flakiness
103 // due to a single activity period spanning two days.
104 SetBaselineTime(Time::Now().LocalMidnight() + TimeDelta::FromHours(1));
107 void Simulate(ui::IdleState
* states
, int len
) {
108 for (int i
= 0; i
< len
; i
++)
109 IdleStateCallback(states
[i
]);
112 void set_max_stored_past_activity_days(unsigned int value
) {
113 max_stored_past_activity_days_
= value
;
116 void set_max_stored_future_activity_days(unsigned int value
) {
117 max_stored_future_activity_days_
= value
;
120 // Reset the baseline time.
121 void SetBaselineTime(Time time
) {
122 baseline_time_
= time
;
123 baseline_offset_periods_
= 0;
126 void set_mock_cpu_usage(double total_cpu_usage
, int num_processors
) {
127 std::vector
<double> usage
;
128 for (int i
= 0; i
< num_processors
; ++i
)
129 usage
.push_back(total_cpu_usage
/ num_processors
);
131 mock_cpu_usage_
= usage
;
133 RefreshSampleResourceUsage();
136 void set_kiosk_account(scoped_ptr
<policy::DeviceLocalAccount
> account
) {
137 kiosk_account_
= account
.Pass();
140 scoped_ptr
<policy::DeviceLocalAccount
>
141 GetAutoLaunchedKioskSessionInfo() override
{
143 return make_scoped_ptr(new policy::DeviceLocalAccount(*kiosk_account_
));
144 return scoped_ptr
<policy::DeviceLocalAccount
>();
147 std::string
GetAppVersion(const std::string
& app_id
) override
{
148 // Just return the app_id as the version - this makes it easy for tests
149 // to confirm that the correct app's version was requested.
153 void RefreshSampleResourceUsage() {
154 // Refresh our samples. Sample more than kMaxHardwareSamples times to
155 // make sure that the code correctly caps the number of cached samples.
156 for (int i
= 0; i
< static_cast<int>(kMaxResourceUsageSamples
+ 1); ++i
)
157 SampleResourceUsage();
161 void CheckIdleState() override
{
162 // This should never be called in testing, as it results in a dbus call.
166 // Each time this is called, returns a time that is a fixed increment
167 // later than the previous time.
168 Time
GetCurrentTime() override
{
169 int poll_interval
= policy::DeviceStatusCollector::kIdlePollIntervalSeconds
;
170 return baseline_time_
+
171 TimeDelta::FromSeconds(poll_interval
* baseline_offset_periods_
++);
174 std::vector
<double> GetPerProcessCPUUsage() override
{
175 return mock_cpu_usage_
;
179 // Baseline time for the fake times returned from GetCurrentTime().
182 // The number of simulated periods since the baseline time.
183 int baseline_offset_periods_
;
185 std::vector
<double> mock_cpu_usage_
;
187 scoped_ptr
<policy::DeviceLocalAccount
> kiosk_account_
;
190 // Return the total number of active milliseconds contained in a device
192 int64
GetActiveMilliseconds(em::DeviceStatusReportRequest
& status
) {
193 int64 active_milliseconds
= 0;
194 for (int i
= 0; i
< status
.active_period_size(); i
++) {
195 active_milliseconds
+= status
.active_period(i
).active_duration();
197 return active_milliseconds
;
200 // Mock VolumeInfoFetcher used to return empty VolumeInfo, to avoid warnings
201 // and test slowdowns from trying to fetch information about non-existent
203 std::vector
<em::VolumeInfo
> GetEmptyVolumeInfo(
204 const std::vector
<std::string
>& mount_points
) {
205 return std::vector
<em::VolumeInfo
>();
208 std::vector
<em::VolumeInfo
> GetFakeVolumeInfo(
209 const std::vector
<em::VolumeInfo
>& volume_info
,
210 const std::vector
<std::string
>& mount_points
) {
211 EXPECT_EQ(volume_info
.size(), mount_points
.size());
212 // Make sure there's a matching mount point for every volume info.
213 for (const em::VolumeInfo
& info
: volume_info
) {
215 for (const std::string
& mount_point
: mount_points
) {
216 if (info
.volume_id() == mount_point
) {
221 EXPECT_TRUE(found
) << "Could not find matching mount point for "
231 // Though it is a unit test, this test is linked with browser_tests so that it
232 // runs in a separate process. The intention is to avoid overriding the timezone
233 // environment variable for other tests.
234 class DeviceStatusCollectorTest
: public testing::Test
{
236 DeviceStatusCollectorTest()
237 : ui_thread_(content::BrowserThread::UI
, &message_loop_
),
238 file_thread_(content::BrowserThread::FILE, &message_loop_
),
239 io_thread_(content::BrowserThread::IO
, &message_loop_
),
240 install_attributes_("managed.com",
243 DEVICE_MODE_ENTERPRISE
),
244 user_manager_(new chromeos::MockUserManager()),
245 user_manager_enabler_(user_manager_
),
246 fake_device_local_account_(
247 policy::DeviceLocalAccount::TYPE_KIOSK_APP
,
250 std::string() /* kiosk_app_update_url */) {
251 // Run this test with a well-known timezone so that Time::LocalMidnight()
252 // returns the same values on all machines.
253 scoped_ptr
<base::Environment
> env(base::Environment::Create());
254 env
->SetVar("TZ", "UTC");
256 // Initialize our mock mounted disk volumes.
257 scoped_ptr
<chromeos::disks::MockDiskMountManager
> mock_disk_mount_manager
=
258 make_scoped_ptr(new chromeos::disks::MockDiskMountManager());
259 AddMountPoint("/mount/volume1");
260 AddMountPoint("/mount/volume2");
261 EXPECT_CALL(*mock_disk_mount_manager
, mount_points())
262 .WillRepeatedly(ReturnRef(mount_point_map_
));
264 // DiskMountManager takes ownership of the MockDiskMountManager.
265 DiskMountManager::InitializeForTesting(mock_disk_mount_manager
.release());
266 TestingDeviceStatusCollector::RegisterPrefs(prefs_
.registry());
268 // Remove the real DeviceSettingsProvider and replace it with a stub.
269 cros_settings_
= chromeos::CrosSettings::Get();
270 device_settings_provider_
=
271 cros_settings_
->GetProvider(chromeos::kReportDeviceVersionInfo
);
272 EXPECT_TRUE(device_settings_provider_
!= NULL
);
274 cros_settings_
->RemoveSettingsProvider(device_settings_provider_
));
275 cros_settings_
->AddSettingsProvider(&stub_settings_provider_
);
277 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo
));
280 void AddMountPoint(const std::string
& mount_point
) {
281 mount_point_map_
.insert(DiskMountManager::MountPointMap::value_type(
283 DiskMountManager::MountPointInfo(
284 mount_point
, mount_point
, chromeos::MOUNT_TYPE_DEVICE
,
285 chromeos::disks::MOUNT_CONDITION_NONE
)));
288 ~DeviceStatusCollectorTest() override
{
289 // Finish pending tasks.
290 content::BrowserThread::GetBlockingPool()->FlushForTesting();
291 message_loop_
.RunUntilIdle();
292 DiskMountManager::Shutdown();
294 // Restore the real DeviceSettingsProvider.
296 cros_settings_
->RemoveSettingsProvider(&stub_settings_provider_
));
297 cros_settings_
->AddSettingsProvider(device_settings_provider_
);
300 void SetUp() override
{
301 // Disable network interface reporting since it requires additional setup.
302 cros_settings_
->SetBoolean(chromeos::kReportDeviceNetworkInterfaces
, false);
305 void RestartStatusCollector(
306 const policy::DeviceStatusCollector::VolumeInfoFetcher
& fetcher
) {
307 policy::DeviceStatusCollector::LocationUpdateRequester callback
=
308 base::Bind(&MockPositionUpdateRequester
);
309 std::vector
<em::VolumeInfo
> expected_volume_info
;
310 status_collector_
.reset(
311 new TestingDeviceStatusCollector(&prefs_
,
312 &fake_statistics_provider_
,
319 status_collector_
->GetDeviceStatus(&status_
);
322 void CheckThatNoLocationIsReported() {
324 EXPECT_FALSE(status_
.has_device_location());
327 void CheckThatAValidLocationIsReported() {
328 // Checks that a location is being reported which matches the valid fix
329 // set using SetMockPositionToReturnNext().
331 EXPECT_TRUE(status_
.has_device_location());
332 em::DeviceLocation location
= status_
.device_location();
333 if (location
.has_error_code())
334 EXPECT_EQ(em::DeviceLocation::ERROR_CODE_NONE
, location
.error_code());
335 EXPECT_TRUE(location
.has_latitude());
336 EXPECT_TRUE(location
.has_longitude());
337 EXPECT_TRUE(location
.has_accuracy());
338 EXPECT_TRUE(location
.has_timestamp());
339 EXPECT_FALSE(location
.has_altitude());
340 EXPECT_FALSE(location
.has_altitude_accuracy());
341 EXPECT_FALSE(location
.has_heading());
342 EXPECT_FALSE(location
.has_speed());
343 EXPECT_FALSE(location
.has_error_message());
344 EXPECT_DOUBLE_EQ(4.3, location
.latitude());
345 EXPECT_DOUBLE_EQ(-7.8, location
.longitude());
346 EXPECT_DOUBLE_EQ(3., location
.accuracy());
347 // Check that the timestamp is not older than ten minutes.
348 EXPECT_TRUE(Time::Now() - Time::FromDoubleT(location
.timestamp() / 1000.) <
349 TimeDelta::FromMinutes(10));
352 void CheckThatALocationErrorIsReported() {
354 EXPECT_TRUE(status_
.has_device_location());
355 em::DeviceLocation location
= status_
.device_location();
356 EXPECT_TRUE(location
.has_error_code());
357 EXPECT_EQ(em::DeviceLocation::ERROR_CODE_POSITION_UNAVAILABLE
,
358 location
.error_code());
361 void MockRunningKioskApp(const DeviceLocalAccount
& account
) {
362 std::vector
<DeviceLocalAccount
> accounts
;
363 accounts
.push_back(account
);
364 SetDeviceLocalAccounts(cros_settings_
, accounts
);
365 user_manager_
->CreateKioskAppUser(account
.user_id
);
366 EXPECT_CALL(*user_manager_
, IsLoggedInAsKioskApp()).WillRepeatedly(
371 // Convenience method.
372 int64
ActivePeriodMilliseconds() {
373 return policy::DeviceStatusCollector::kIdlePollIntervalSeconds
* 1000;
376 // Since this is a unit test running in browser_tests we must do additional
377 // unit test setup and make a TestingBrowserProcess. Must be first member.
378 TestingBrowserProcessInitializer initializer_
;
379 base::MessageLoopForUI message_loop_
;
380 content::TestBrowserThread ui_thread_
;
381 content::TestBrowserThread file_thread_
;
382 content::TestBrowserThread io_thread_
;
384 ScopedStubEnterpriseInstallAttributes install_attributes_
;
385 TestingPrefServiceSimple prefs_
;
386 chromeos::system::ScopedFakeStatisticsProvider fake_statistics_provider_
;
387 DiskMountManager::MountPointMap mount_point_map_
;
388 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
389 chromeos::ScopedTestCrosSettings test_cros_settings_
;
390 chromeos::CrosSettings
* cros_settings_
;
391 chromeos::CrosSettingsProvider
* device_settings_provider_
;
392 chromeos::StubCrosSettingsProvider stub_settings_provider_
;
393 chromeos::MockUserManager
* user_manager_
;
394 chromeos::ScopedUserManagerEnabler user_manager_enabler_
;
395 em::DeviceStatusReportRequest status_
;
396 scoped_ptr
<TestingDeviceStatusCollector
> status_collector_
;
397 const policy::DeviceLocalAccount fake_device_local_account_
;
400 TEST_F(DeviceStatusCollectorTest
, AllIdle
) {
401 ui::IdleState test_states
[] = {
406 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
408 // Test reporting with no data.
410 EXPECT_EQ(0, status_
.active_period_size());
411 EXPECT_EQ(0, GetActiveMilliseconds(status_
));
413 // Test reporting with a single idle sample.
414 status_collector_
->Simulate(test_states
, 1);
416 EXPECT_EQ(0, status_
.active_period_size());
417 EXPECT_EQ(0, GetActiveMilliseconds(status_
));
419 // Test reporting with multiple consecutive idle samples.
420 status_collector_
->Simulate(test_states
,
421 sizeof(test_states
) / sizeof(ui::IdleState
));
423 EXPECT_EQ(0, status_
.active_period_size());
424 EXPECT_EQ(0, GetActiveMilliseconds(status_
));
427 TEST_F(DeviceStatusCollectorTest
, AllActive
) {
428 ui::IdleState test_states
[] = {
429 ui::IDLE_STATE_ACTIVE
,
430 ui::IDLE_STATE_ACTIVE
,
431 ui::IDLE_STATE_ACTIVE
433 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
435 // Test a single active sample.
436 status_collector_
->Simulate(test_states
, 1);
438 EXPECT_EQ(1, status_
.active_period_size());
439 EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
440 status_
.clear_active_period(); // Clear the result protobuf.
442 // Test multiple consecutive active samples.
443 status_collector_
->Simulate(test_states
,
444 sizeof(test_states
) / sizeof(ui::IdleState
));
446 EXPECT_EQ(1, status_
.active_period_size());
447 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
450 TEST_F(DeviceStatusCollectorTest
, MixedStates
) {
451 ui::IdleState test_states
[] = {
452 ui::IDLE_STATE_ACTIVE
,
454 ui::IDLE_STATE_ACTIVE
,
455 ui::IDLE_STATE_ACTIVE
,
458 ui::IDLE_STATE_ACTIVE
460 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
461 status_collector_
->Simulate(test_states
,
462 sizeof(test_states
) / sizeof(ui::IdleState
));
464 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
467 TEST_F(DeviceStatusCollectorTest
, StateKeptInPref
) {
468 ui::IdleState test_states
[] = {
469 ui::IDLE_STATE_ACTIVE
,
471 ui::IDLE_STATE_ACTIVE
,
472 ui::IDLE_STATE_ACTIVE
,
476 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
477 status_collector_
->Simulate(test_states
,
478 sizeof(test_states
) / sizeof(ui::IdleState
));
480 // Process the list a second time after restarting the collector. It should be
481 // able to count the active periods found by the original collector, because
482 // the results are stored in a pref.
483 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo
));
484 status_collector_
->Simulate(test_states
,
485 sizeof(test_states
) / sizeof(ui::IdleState
));
488 EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
491 TEST_F(DeviceStatusCollectorTest
, Times
) {
492 ui::IdleState test_states
[] = {
493 ui::IDLE_STATE_ACTIVE
,
495 ui::IDLE_STATE_ACTIVE
,
496 ui::IDLE_STATE_ACTIVE
,
500 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
501 status_collector_
->Simulate(test_states
,
502 sizeof(test_states
) / sizeof(ui::IdleState
));
504 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
507 TEST_F(DeviceStatusCollectorTest
, MaxStoredPeriods
) {
508 ui::IdleState test_states
[] = {
509 ui::IDLE_STATE_ACTIVE
,
512 const int kMaxDays
= 10;
514 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
515 status_collector_
->set_max_stored_past_activity_days(kMaxDays
- 1);
516 status_collector_
->set_max_stored_future_activity_days(1);
517 Time baseline
= Time::Now().LocalMidnight();
519 // Simulate 12 active periods.
520 for (int i
= 0; i
< kMaxDays
+ 2; i
++) {
521 status_collector_
->Simulate(test_states
,
522 sizeof(test_states
) / sizeof(ui::IdleState
));
523 // Advance the simulated clock by a day.
524 baseline
+= TimeDelta::FromDays(1);
525 status_collector_
->SetBaselineTime(baseline
);
528 // Check that we don't exceed the max number of periods.
530 EXPECT_EQ(kMaxDays
- 1, status_
.active_period_size());
532 // Simulate some future times.
533 for (int i
= 0; i
< kMaxDays
+ 2; i
++) {
534 status_collector_
->Simulate(test_states
,
535 sizeof(test_states
) / sizeof(ui::IdleState
));
536 // Advance the simulated clock by a day.
537 baseline
+= TimeDelta::FromDays(1);
538 status_collector_
->SetBaselineTime(baseline
);
540 // Set the clock back so the previous simulated times are in the future.
541 baseline
-= TimeDelta::FromDays(20);
542 status_collector_
->SetBaselineTime(baseline
);
544 // Collect one more data point to trigger pruning.
545 status_collector_
->Simulate(test_states
, 1);
547 // Check that we don't exceed the max number of periods.
548 status_
.clear_active_period();
550 EXPECT_LT(status_
.active_period_size(), kMaxDays
);
553 TEST_F(DeviceStatusCollectorTest
, ActivityTimesEnabledByDefault
) {
554 // Device activity times should be reported by default.
555 ui::IdleState test_states
[] = {
556 ui::IDLE_STATE_ACTIVE
,
557 ui::IDLE_STATE_ACTIVE
,
558 ui::IDLE_STATE_ACTIVE
560 status_collector_
->Simulate(test_states
,
561 sizeof(test_states
) / sizeof(ui::IdleState
));
563 EXPECT_EQ(1, status_
.active_period_size());
564 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
567 TEST_F(DeviceStatusCollectorTest
, ActivityTimesOff
) {
568 // Device activity times should not be reported if explicitly disabled.
569 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, false);
571 ui::IdleState test_states
[] = {
572 ui::IDLE_STATE_ACTIVE
,
573 ui::IDLE_STATE_ACTIVE
,
574 ui::IDLE_STATE_ACTIVE
576 status_collector_
->Simulate(test_states
,
577 sizeof(test_states
) / sizeof(ui::IdleState
));
579 EXPECT_EQ(0, status_
.active_period_size());
580 EXPECT_EQ(0, GetActiveMilliseconds(status_
));
583 TEST_F(DeviceStatusCollectorTest
, ActivityCrossingMidnight
) {
584 ui::IdleState test_states
[] = {
585 ui::IDLE_STATE_ACTIVE
587 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
589 // Set the baseline time to 10 seconds after midnight.
590 status_collector_
->SetBaselineTime(
591 Time::Now().LocalMidnight() + TimeDelta::FromSeconds(10));
593 status_collector_
->Simulate(test_states
, 1);
595 ASSERT_EQ(2, status_
.active_period_size());
597 em::ActiveTimePeriod period0
= status_
.active_period(0);
598 em::ActiveTimePeriod period1
= status_
.active_period(1);
599 EXPECT_EQ(ActivePeriodMilliseconds() - 10000, period0
.active_duration());
600 EXPECT_EQ(10000, period1
.active_duration());
602 em::TimePeriod time_period0
= period0
.time_period();
603 em::TimePeriod time_period1
= period1
.time_period();
605 EXPECT_EQ(time_period0
.end_timestamp(), time_period1
.start_timestamp());
607 // Ensure that the start and end times for the period are a day apart.
608 EXPECT_EQ(time_period0
.end_timestamp() - time_period0
.start_timestamp(),
609 kMillisecondsPerDay
);
610 EXPECT_EQ(time_period1
.end_timestamp() - time_period1
.start_timestamp(),
611 kMillisecondsPerDay
);
614 TEST_F(DeviceStatusCollectorTest
, ActivityTimesKeptUntilSubmittedSuccessfully
) {
615 ui::IdleState test_states
[] = {
616 ui::IDLE_STATE_ACTIVE
,
617 ui::IDLE_STATE_ACTIVE
,
619 cros_settings_
->SetBoolean(chromeos::kReportDeviceActivityTimes
, true);
621 status_collector_
->Simulate(test_states
, 2);
623 EXPECT_EQ(2 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
624 em::DeviceStatusReportRequest
first_status(status_
);
626 // The collector returns the same status again.
628 EXPECT_EQ(first_status
.SerializeAsString(), status_
.SerializeAsString());
630 // After indicating a successful submit, the submitted status gets cleared,
631 // but what got collected meanwhile sticks around.
632 status_collector_
->Simulate(test_states
, 1);
633 status_collector_
->OnSubmittedSuccessfully();
635 EXPECT_EQ(ActivePeriodMilliseconds(), GetActiveMilliseconds(status_
));
638 TEST_F(DeviceStatusCollectorTest
, DevSwitchBootMode
) {
639 // Test that boot mode data is reported by default.
640 fake_statistics_provider_
.SetMachineStatistic(
641 chromeos::system::kDevSwitchBootKey
,
642 chromeos::system::kDevSwitchBootValueVerified
);
644 EXPECT_EQ("Verified", status_
.boot_mode());
646 // Test that boot mode data is not reported if the pref turned off.
647 cros_settings_
->SetBoolean(chromeos::kReportDeviceBootMode
, false);
650 EXPECT_FALSE(status_
.has_boot_mode());
652 // Turn the pref on, and check that the status is reported iff the
653 // statistics provider returns valid data.
654 cros_settings_
->SetBoolean(chromeos::kReportDeviceBootMode
, true);
656 fake_statistics_provider_
.SetMachineStatistic(
657 chromeos::system::kDevSwitchBootKey
, "(error)");
659 EXPECT_FALSE(status_
.has_boot_mode());
661 fake_statistics_provider_
.SetMachineStatistic(
662 chromeos::system::kDevSwitchBootKey
, " ");
664 EXPECT_FALSE(status_
.has_boot_mode());
666 fake_statistics_provider_
.SetMachineStatistic(
667 chromeos::system::kDevSwitchBootKey
,
668 chromeos::system::kDevSwitchBootValueVerified
);
670 EXPECT_EQ("Verified", status_
.boot_mode());
672 fake_statistics_provider_
.SetMachineStatistic(
673 chromeos::system::kDevSwitchBootKey
,
674 chromeos::system::kDevSwitchBootValueDev
);
676 EXPECT_EQ("Dev", status_
.boot_mode());
679 TEST_F(DeviceStatusCollectorTest
, VersionInfo
) {
680 // Expect the version info to be reported by default.
682 EXPECT_TRUE(status_
.has_browser_version());
683 EXPECT_TRUE(status_
.has_os_version());
684 EXPECT_TRUE(status_
.has_firmware_version());
686 // When the pref to collect this data is not enabled, expect that none of
687 // the fields are present in the protobuf.
688 cros_settings_
->SetBoolean(chromeos::kReportDeviceVersionInfo
, false);
690 EXPECT_FALSE(status_
.has_browser_version());
691 EXPECT_FALSE(status_
.has_os_version());
692 EXPECT_FALSE(status_
.has_firmware_version());
694 cros_settings_
->SetBoolean(chromeos::kReportDeviceVersionInfo
, true);
696 EXPECT_TRUE(status_
.has_browser_version());
697 EXPECT_TRUE(status_
.has_os_version());
698 EXPECT_TRUE(status_
.has_firmware_version());
700 // Check that the browser version is not empty. OS version & firmware
701 // don't have any reasonable values inside the unit test, so those
703 EXPECT_NE("", status_
.browser_version());
706 TEST_F(DeviceStatusCollectorTest
, Location
) {
707 content::Geoposition valid_fix
;
708 valid_fix
.latitude
= 4.3;
709 valid_fix
.longitude
= -7.8;
710 valid_fix
.accuracy
= 3.;
711 valid_fix
.timestamp
= Time::Now();
713 content::Geoposition invalid_fix
;
714 invalid_fix
.error_code
=
715 content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE
;
716 invalid_fix
.timestamp
= Time::Now();
718 // Check that when device location reporting is disabled, no location is
720 SetMockPositionToReturnNext(valid_fix
);
721 CheckThatNoLocationIsReported();
723 // Check that when device location reporting is enabled and a valid fix is
724 // available, the location is reported and is stored in local state.
725 SetMockPositionToReturnNext(valid_fix
);
726 cros_settings_
->SetBoolean(chromeos::kReportDeviceLocation
, true);
727 EXPECT_FALSE(prefs_
.GetDictionary(prefs::kDeviceLocation
)->empty());
728 CheckThatAValidLocationIsReported();
730 // Restart the status collector. Check that the last known location has been
731 // retrieved from local state without requesting a geolocation update.
732 SetMockPositionToReturnNext(valid_fix
);
733 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo
));
734 CheckThatAValidLocationIsReported();
735 EXPECT_TRUE(mock_position_to_return_next
.get());
737 // Check that after disabling location reporting again, the last known
738 // location has been cleared from local state and is no longer reported.
739 SetMockPositionToReturnNext(valid_fix
);
740 cros_settings_
->SetBoolean(chromeos::kReportDeviceLocation
, false);
741 // Allow the new pref to propagate to the status collector.
742 message_loop_
.RunUntilIdle();
743 EXPECT_TRUE(prefs_
.GetDictionary(prefs::kDeviceLocation
)->empty());
744 CheckThatNoLocationIsReported();
746 // Check that after enabling location reporting again, an error is reported
747 // if no valid fix is available.
748 SetMockPositionToReturnNext(invalid_fix
);
749 cros_settings_
->SetBoolean(chromeos::kReportDeviceLocation
, true);
750 // Allow the new pref to propagate to the status collector.
751 message_loop_
.RunUntilIdle();
752 CheckThatALocationErrorIsReported();
755 TEST_F(DeviceStatusCollectorTest
, ReportUsers
) {
756 user_manager_
->CreatePublicAccountUser("public@localhost");
757 user_manager_
->AddUser("user0@managed.com");
758 user_manager_
->AddUser("user1@managed.com");
759 user_manager_
->AddUser("user2@managed.com");
760 user_manager_
->AddUser("user3@unmanaged.com");
761 user_manager_
->AddUser("user4@managed.com");
762 user_manager_
->AddUser("user5@managed.com");
764 // Verify that users are reported by default.
766 EXPECT_EQ(6, status_
.user_size());
768 // Verify that users are reported after enabling the setting.
769 cros_settings_
->SetBoolean(chromeos::kReportDeviceUsers
, true);
771 EXPECT_EQ(6, status_
.user_size());
772 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(0).type());
773 EXPECT_EQ("user0@managed.com", status_
.user(0).email());
774 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(1).type());
775 EXPECT_EQ("user1@managed.com", status_
.user(1).email());
776 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(2).type());
777 EXPECT_EQ("user2@managed.com", status_
.user(2).email());
778 EXPECT_EQ(em::DeviceUser::USER_TYPE_UNMANAGED
, status_
.user(3).type());
779 EXPECT_FALSE(status_
.user(3).has_email());
780 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(4).type());
781 EXPECT_EQ("user4@managed.com", status_
.user(4).email());
782 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED
, status_
.user(5).type());
783 EXPECT_EQ("user5@managed.com", status_
.user(5).email());
785 // Verify that users are no longer reported if setting is disabled.
786 cros_settings_
->SetBoolean(chromeos::kReportDeviceUsers
, false);
788 EXPECT_EQ(0, status_
.user_size());
791 TEST_F(DeviceStatusCollectorTest
, TestVolumeInfo
) {
792 std::vector
<std::string
> expected_mount_points
;
793 std::vector
<em::VolumeInfo
> expected_volume_info
;
795 for (const auto& mount_info
:
796 DiskMountManager::GetInstance()->mount_points()) {
797 expected_mount_points
.push_back(mount_info
.first
);
799 info
.set_volume_id(mount_info
.first
);
800 // Just put unique numbers in for storage_total/free.
801 info
.set_storage_total(size
++);
802 info
.set_storage_free(size
++);
803 expected_volume_info
.push_back(info
);
806 EXPECT_FALSE(expected_volume_info
.empty());
808 RestartStatusCollector(base::Bind(&GetFakeVolumeInfo
, expected_volume_info
));
809 message_loop_
.RunUntilIdle();
812 EXPECT_EQ(expected_mount_points
.size(),
813 static_cast<size_t>(status_
.volume_info_size()));
815 // Walk the returned VolumeInfo to make sure it matches.
816 for (const em::VolumeInfo
& expected_info
: expected_volume_info
) {
818 for (const em::VolumeInfo
& info
: status_
.volume_info()) {
819 if (info
.volume_id() == expected_info
.volume_id()) {
820 EXPECT_EQ(expected_info
.storage_total(), info
.storage_total());
821 EXPECT_EQ(expected_info
.storage_free(), info
.storage_free());
826 EXPECT_TRUE(found
) << "No matching VolumeInfo for "
827 << expected_info
.volume_id();
830 // Now turn off hardware status reporting - should have no data.
831 cros_settings_
->SetBoolean(chromeos::kReportDeviceHardwareStatus
, false);
833 EXPECT_EQ(0, status_
.volume_info_size());
836 TEST_F(DeviceStatusCollectorTest
, TestAvailableMemory
) {
837 status_collector_
->RefreshSampleResourceUsage();
839 EXPECT_EQ(static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples
),
840 status_
.system_ram_free().size());
841 EXPECT_TRUE(status_
.has_system_ram_total());
842 // No good way to inject specific test values for available system RAM, so
843 // just make sure it's > 0.
844 EXPECT_GT(status_
.system_ram_total(), 0);
847 TEST_F(DeviceStatusCollectorTest
, TestCPUSamples
) {
848 // Mock 100% CPU usage and 2 processors.
849 const int full_cpu_usage
= 100;
850 status_collector_
->set_mock_cpu_usage(full_cpu_usage
, 2);
852 EXPECT_EQ(static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples
),
853 status_
.cpu_utilization_pct().size());
854 for (const auto utilization
: status_
.cpu_utilization_pct())
855 EXPECT_EQ(full_cpu_usage
, utilization
);
857 // Now set CPU usage to 0.
858 const int idle_cpu_usage
= 0;
859 status_collector_
->set_mock_cpu_usage(idle_cpu_usage
, 2);
861 EXPECT_EQ(static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples
),
862 status_
.cpu_utilization_pct().size());
863 for (const auto utilization
: status_
.cpu_utilization_pct())
864 EXPECT_EQ(idle_cpu_usage
, utilization
);
866 // Turning off hardware reporting should not report CPU utilization.
867 cros_settings_
->SetBoolean(chromeos::kReportDeviceHardwareStatus
, false);
869 EXPECT_EQ(0, status_
.cpu_utilization_pct().size());
872 TEST_F(DeviceStatusCollectorTest
, NoSessionStatusIfNotKioskMode
) {
873 // Should not report session status if we don't have an active kiosk app.
874 cros_settings_
->SetBoolean(chromeos::kReportDeviceSessionStatus
, true);
875 em::SessionStatusReportRequest session_status
;
876 EXPECT_FALSE(status_collector_
->GetDeviceSessionStatus(&session_status
));
879 TEST_F(DeviceStatusCollectorTest
, NoSessionStatusIfSessionReportingDisabled
) {
880 // Should not report session status if session status reporting is disabled.
881 cros_settings_
->SetBoolean(chromeos::kReportDeviceSessionStatus
, false);
882 status_collector_
->set_kiosk_account(make_scoped_ptr(
883 new policy::DeviceLocalAccount(fake_device_local_account_
)).Pass());
884 // Set up a device-local account for single-app kiosk mode.
885 MockRunningKioskApp(fake_device_local_account_
);
887 em::SessionStatusReportRequest session_status
;
888 EXPECT_FALSE(status_collector_
->GetDeviceSessionStatus(&session_status
));
891 TEST_F(DeviceStatusCollectorTest
, ReportSessionStatus
) {
892 cros_settings_
->SetBoolean(chromeos::kReportDeviceSessionStatus
, true);
893 status_collector_
->set_kiosk_account(make_scoped_ptr(
894 new policy::DeviceLocalAccount(fake_device_local_account_
)).Pass());
896 // Set up a device-local account for single-app kiosk mode.
897 MockRunningKioskApp(fake_device_local_account_
);
899 em::SessionStatusReportRequest session_status
;
900 EXPECT_TRUE(status_collector_
->GetDeviceSessionStatus(&session_status
));
901 ASSERT_EQ(1, session_status
.installed_apps_size());
902 EXPECT_EQ(kKioskAccountId
, session_status
.device_local_account_id());
903 const em::AppStatus app
= session_status
.installed_apps(0);
904 EXPECT_EQ(kKioskAppId
, app
.app_id());
905 // Test code just sets the version to the app ID.
906 EXPECT_EQ(kKioskAppId
, app
.extension_version());
907 EXPECT_FALSE(app
.has_status());
908 EXPECT_FALSE(app
.has_error());
911 // Fake device state.
912 struct FakeDeviceData
{
913 const char* device_path
;
915 const char* object_path
;
916 const char* mac_address
;
919 int expected_type
; // proto enum type value, -1 for not present.
922 static const FakeDeviceData kFakeDevices
[] = {
923 { "/device/ethernet", shill::kTypeEthernet
, "ethernet",
924 "112233445566", "", "",
925 em::NetworkInterface::TYPE_ETHERNET
},
926 { "/device/cellular1", shill::kTypeCellular
, "cellular1",
927 "abcdefabcdef", "A10000009296F2", "",
928 em::NetworkInterface::TYPE_CELLULAR
},
929 { "/device/cellular2", shill::kTypeCellular
, "cellular2",
930 "abcdefabcdef", "", "352099001761481",
931 em::NetworkInterface::TYPE_CELLULAR
},
932 { "/device/wifi", shill::kTypeWifi
, "wifi",
933 "aabbccddeeff", "", "",
934 em::NetworkInterface::TYPE_WIFI
},
935 { "/device/bluetooth", shill::kTypeBluetooth
, "bluetooth",
937 em::NetworkInterface::TYPE_BLUETOOTH
},
938 { "/device/vpn", shill::kTypeVPN
, "vpn",
943 // Fake network state.
944 struct FakeNetworkState
{
946 const char* device_path
;
949 const char* connection_status
;
955 // List of fake networks - primarily used to make sure that signal strength
956 // and connection state are properly populated in status reports. Note that
957 // by convention shill will not report a signal strength of 0 for a visible
958 // network, so we use 1 below.
959 static const FakeNetworkState kFakeNetworks
[] = {
960 { "offline", "/device/wifi", shill::kTypeWifi
, 35,
961 shill::kStateOffline
, em::NetworkState::OFFLINE
, "", "" },
962 { "ethernet", "/device/ethernet", shill::kTypeEthernet
, 0,
963 shill::kStateOnline
, em::NetworkState::ONLINE
,
964 "192.168.0.1", "8.8.8.8" },
965 { "wifi", "/device/wifi", shill::kTypeWifi
, 23, shill::kStatePortal
,
966 em::NetworkState::PORTAL
, "", "" },
967 { "idle", "/device/cellular1", shill::kTypeCellular
, 0, shill::kStateIdle
,
968 em::NetworkState::IDLE
, "", "" },
969 { "carrier", "/device/cellular1", shill::kTypeCellular
, 0,
970 shill::kStateCarrier
, em::NetworkState::CARRIER
, "", "" },
971 { "association", "/device/cellular1", shill::kTypeCellular
, 0,
972 shill::kStateAssociation
, em::NetworkState::ASSOCIATION
, "", "" },
973 { "config", "/device/cellular1", shill::kTypeCellular
, 0,
974 shill::kStateConfiguration
, em::NetworkState::CONFIGURATION
, "", "" },
975 { "ready", "/device/cellular1", shill::kTypeCellular
, 0, shill::kStateReady
,
976 em::NetworkState::READY
, "", "" },
977 { "disconnect", "/device/wifi", shill::kTypeWifi
, 1,
978 shill::kStateDisconnect
, em::NetworkState::DISCONNECT
, "", "" },
979 { "failure", "/device/wifi", shill::kTypeWifi
, 1, shill::kStateFailure
,
980 em::NetworkState::FAILURE
, "", "" },
981 { "activation-failure", "/device/cellular1", shill::kTypeCellular
, 0,
982 shill::kStateActivationFailure
, em::NetworkState::ACTIVATION_FAILURE
,
984 { "unknown", "", shill::kTypeWifi
, 1, "unknown", em::NetworkState::UNKNOWN
,
988 static const FakeNetworkState kUnconfiguredNetwork
= {
989 "unconfigured", "/device/unconfigured", shill::kTypeWifi
, 35,
990 shill::kStateOffline
, em::NetworkState::OFFLINE
, "", ""
993 class DeviceStatusCollectorNetworkInterfacesTest
994 : public DeviceStatusCollectorTest
{
996 void SetUp() override
{
997 chromeos::DBusThreadManager::Initialize();
998 chromeos::NetworkHandler::Initialize();
999 chromeos::ShillDeviceClient::TestInterface
* test_device_client
=
1000 chromeos::DBusThreadManager::Get()->GetShillDeviceClient()->
1002 test_device_client
->ClearDevices();
1003 for (size_t i
= 0; i
< arraysize(kFakeDevices
); ++i
) {
1004 const FakeDeviceData
& dev
= kFakeDevices
[i
];
1005 test_device_client
->AddDevice(dev
.device_path
, dev
.type
,
1007 if (*dev
.mac_address
) {
1008 test_device_client
->SetDeviceProperty(
1009 dev
.device_path
, shill::kAddressProperty
,
1010 base::StringValue(dev
.mac_address
));
1013 test_device_client
->SetDeviceProperty(
1014 dev
.device_path
, shill::kMeidProperty
,
1015 base::StringValue(dev
.meid
));
1018 test_device_client
->SetDeviceProperty(
1019 dev
.device_path
, shill::kImeiProperty
,
1020 base::StringValue(dev
.imei
));
1024 chromeos::ShillServiceClient::TestInterface
* service_client
=
1025 chromeos::DBusThreadManager::Get()->GetShillServiceClient()->
1027 service_client
->ClearServices();
1029 // Now add services for every fake network.
1030 for (const FakeNetworkState
& fake_network
: kFakeNetworks
) {
1031 // Shill forces non-visible networks to report a disconnected state.
1033 fake_network
.connection_status
!= shill::kStateDisconnect
;
1034 service_client
->AddService(
1035 fake_network
.name
, /* service_path */
1036 fake_network
.name
/* guid */,
1037 fake_network
.name
/* name */,
1038 fake_network
.type
/* type */,
1039 fake_network
.connection_status
,
1041 service_client
->SetServiceProperty(
1042 fake_network
.name
, shill::kSignalStrengthProperty
,
1043 base::FundamentalValue(fake_network
.signal_strength
));
1044 service_client
->SetServiceProperty(
1045 fake_network
.name
, shill::kDeviceProperty
,
1046 base::StringValue(fake_network
.device_path
));
1047 // Set the profile so this shows up as a configured network.
1048 service_client
->SetServiceProperty(
1049 fake_network
.name
, shill::kProfileProperty
,
1050 base::StringValue(fake_network
.name
));
1051 if (strlen(fake_network
.address
) > 0) {
1052 // Set the IP config.
1053 base::DictionaryValue ip_config_properties
;
1054 ip_config_properties
.SetStringWithoutPathExpansion(
1055 shill::kAddressProperty
, fake_network
.address
);
1056 ip_config_properties
.SetStringWithoutPathExpansion(
1057 shill::kGatewayProperty
, fake_network
.gateway
);
1058 chromeos::ShillIPConfigClient::TestInterface
* ip_config_test
=
1059 chromeos::DBusThreadManager::Get()->GetShillIPConfigClient()->
1061 const std::string kIPConfigPath
= "test_ip_config";
1062 ip_config_test
->AddIPConfig(kIPConfigPath
, ip_config_properties
);
1063 service_client
->SetServiceProperty(
1064 fake_network
.name
, shill::kIPConfigProperty
,
1065 base::StringValue(kIPConfigPath
));
1069 // Now add an unconfigured network - it should not show up in the
1070 // reported list of networks because it doesn't have a profile specified.
1071 service_client
->AddService(
1072 kUnconfiguredNetwork
.name
, /* service_path */
1073 kUnconfiguredNetwork
.name
/* guid */,
1074 kUnconfiguredNetwork
.name
/* name */,
1075 kUnconfiguredNetwork
.type
/* type */,
1076 kUnconfiguredNetwork
.connection_status
,
1077 true /* visible */);
1078 service_client
->SetServiceProperty(
1079 kUnconfiguredNetwork
.name
, shill::kSignalStrengthProperty
,
1080 base::FundamentalValue(kUnconfiguredNetwork
.signal_strength
));
1081 service_client
->SetServiceProperty(
1082 kUnconfiguredNetwork
.name
, shill::kDeviceProperty
,
1083 base::StringValue(kUnconfiguredNetwork
.device_path
));
1085 // Flush out pending state updates.
1086 base::RunLoop().RunUntilIdle();
1088 chromeos::NetworkStateHandler::NetworkStateList state_list
;
1089 chromeos::NetworkStateHandler
* network_state_handler
=
1090 chromeos::NetworkHandler::Get()->network_state_handler();
1091 network_state_handler
->GetNetworkListByType(
1092 chromeos::NetworkTypePattern::Default(),
1093 true, // configured_only
1094 false, // visible_only,
1095 0, // no limit to number of results
1097 ASSERT_EQ(arraysize(kFakeNetworks
), state_list
.size());
1100 void TearDown() override
{
1101 chromeos::NetworkHandler::Shutdown();
1102 chromeos::DBusThreadManager::Shutdown();
1106 TEST_F(DeviceStatusCollectorNetworkInterfacesTest
, NoNetworkStateIfNotKiosk
) {
1107 // If not in an active kiosk session, there should be network interfaces
1108 // reported, but no network state.
1110 EXPECT_LT(0, status_
.network_interface_size());
1111 EXPECT_EQ(0, status_
.network_state_size());
1114 TEST_F(DeviceStatusCollectorNetworkInterfacesTest
, NetworkInterfaces
) {
1115 // Mock that we are in kiosk mode so we report network state.
1116 status_collector_
->set_kiosk_account(make_scoped_ptr(
1117 new policy::DeviceLocalAccount(fake_device_local_account_
)).Pass());
1119 // Interfaces should be reported by default.
1121 EXPECT_LT(0, status_
.network_interface_size());
1122 EXPECT_LT(0, status_
.network_state_size());
1124 // No interfaces should be reported if the policy is off.
1125 cros_settings_
->SetBoolean(chromeos::kReportDeviceNetworkInterfaces
, false);
1127 EXPECT_EQ(0, status_
.network_interface_size());
1128 EXPECT_EQ(0, status_
.network_state_size());
1130 // Switch the policy on and verify the interface list is present.
1131 cros_settings_
->SetBoolean(chromeos::kReportDeviceNetworkInterfaces
, true);
1135 for (size_t i
= 0; i
< arraysize(kFakeDevices
); ++i
) {
1136 const FakeDeviceData
& dev
= kFakeDevices
[i
];
1137 if (dev
.expected_type
== -1)
1140 // Find the corresponding entry in reporting data.
1141 bool found_match
= false;
1142 google::protobuf::RepeatedPtrField
<em::NetworkInterface
>::const_iterator
1144 for (iface
= status_
.network_interface().begin();
1145 iface
!= status_
.network_interface().end();
1147 // Check whether type, field presence and field values match.
1148 if (dev
.expected_type
== iface
->type() &&
1149 iface
->has_mac_address() == !!*dev
.mac_address
&&
1150 iface
->has_meid() == !!*dev
.meid
&&
1151 iface
->has_imei() == !!*dev
.imei
&&
1152 iface
->mac_address() == dev
.mac_address
&&
1153 iface
->meid() == dev
.meid
&&
1154 iface
->imei() == dev
.imei
&&
1155 iface
->device_path() == dev
.device_path
) {
1161 EXPECT_TRUE(found_match
) << "No matching interface for fake device " << i
;
1165 EXPECT_EQ(count
, status_
.network_interface_size());
1167 // Now make sure network state list is correct.
1168 EXPECT_EQ(arraysize(kFakeNetworks
),
1169 static_cast<size_t>(status_
.network_state_size()));
1170 for (const FakeNetworkState
& state
: kFakeNetworks
) {
1171 bool found_match
= false;
1172 for (const em::NetworkState
& proto_state
: status_
.network_state()) {
1173 // Make sure every item has a matching entry in the proto.
1174 if (proto_state
.has_device_path() == (strlen(state
.device_path
) > 0) &&
1175 proto_state
.signal_strength() == state
.signal_strength
&&
1176 proto_state
.connection_state() == state
.expected_state
) {
1177 if (proto_state
.has_ip_address())
1178 EXPECT_EQ(proto_state
.ip_address(), state
.address
);
1180 EXPECT_EQ(0U, strlen(state
.address
));
1181 if (proto_state
.has_gateway())
1182 EXPECT_EQ(proto_state
.gateway(), state
.gateway
);
1184 EXPECT_EQ(0U, strlen(state
.gateway
));
1189 EXPECT_TRUE(found_match
) << "No matching state for fake network "
1190 << " (" << state
.name
<< ")";
1194 } // namespace policy