Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / device_status_collector_browsertest.cc
blob195d859358d0b6bcec0687eaf4826c44fa932703
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 <string>
8 #include <vector>
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/ownership/fake_owner_settings_service.h"
22 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
23 #include "chrome/browser/chromeos/policy/device_local_account.h"
24 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
25 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/test/base/testing_browser_process.h"
28 #include "chromeos/dbus/cros_disks_client.h"
29 #include "chromeos/dbus/dbus_thread_manager.h"
30 #include "chromeos/dbus/shill_device_client.h"
31 #include "chromeos/dbus/shill_ipconfig_client.h"
32 #include "chromeos/dbus/shill_service_client.h"
33 #include "chromeos/disks/disk_mount_manager.h"
34 #include "chromeos/disks/mock_disk_mount_manager.h"
35 #include "chromeos/network/network_handler.h"
36 #include "chromeos/network/network_state.h"
37 #include "chromeos/network/network_state_handler.h"
38 #include "chromeos/settings/cros_settings_names.h"
39 #include "chromeos/system/fake_statistics_provider.h"
40 #include "content/public/browser/browser_thread.h"
41 #include "content/public/browser/geolocation_provider.h"
42 #include "content/public/test/test_browser_thread.h"
43 #include "content/public/test/test_utils.h"
44 #include "policy/proto/device_management_backend.pb.h"
45 #include "storage/browser/fileapi/external_mount_points.h"
46 #include "storage/browser/fileapi/mount_points.h"
47 #include "storage/common/fileapi/file_system_mount_option.h"
48 #include "storage/common/fileapi/file_system_types.h"
49 #include "testing/gmock/include/gmock/gmock.h"
50 #include "testing/gtest/include/gtest/gtest.h"
51 #include "third_party/cros_system_api/dbus/service_constants.h"
53 using ::testing::Return;
54 using ::testing::ReturnRef;
55 using base::Time;
56 using base::TimeDelta;
57 using chromeos::disks::DiskMountManager;
59 namespace em = enterprise_management;
61 namespace {
63 const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
64 const char kKioskAccountId[] = "kiosk_user@localhost";
65 const char kKioskAppId[] = "kiosk_app_id";
66 const char kExternalMountPoint[] = "/a/b/c";
68 scoped_ptr<content::Geoposition> mock_position_to_return_next;
70 void SetMockPositionToReturnNext(const content::Geoposition &position) {
71 mock_position_to_return_next.reset(new content::Geoposition(position));
74 void MockPositionUpdateRequester(
75 const content::GeolocationProvider::LocationUpdateCallback& callback) {
76 if (!mock_position_to_return_next.get())
77 return;
79 // If the fix is invalid, the DeviceStatusCollector will immediately request
80 // another update when it receives the callback. This is desirable and safe in
81 // real life where geolocation updates arrive asynchronously. In this testing
82 // harness, the callback is invoked synchronously upon request, leading to a
83 // request-callback loop. The loop is broken by returning the mock position
84 // only once.
85 scoped_ptr<content::Geoposition> position(
86 mock_position_to_return_next.release());
87 callback.Run(*position);
90 class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
91 public:
92 TestingDeviceStatusCollector(
93 PrefService* local_state,
94 chromeos::system::StatisticsProvider* provider,
95 const policy::DeviceStatusCollector::LocationUpdateRequester&
96 location_update_requester,
97 const policy::DeviceStatusCollector::VolumeInfoFetcher&
98 volume_info_fetcher,
99 const policy::DeviceStatusCollector::CPUStatisticsFetcher& cpu_fetcher)
100 : policy::DeviceStatusCollector(local_state,
101 provider,
102 location_update_requester,
103 volume_info_fetcher,
104 cpu_fetcher) {
105 // Set the baseline time to a fixed value (1 AM) to prevent test flakiness
106 // due to a single activity period spanning two days.
107 SetBaselineTime(Time::Now().LocalMidnight() + TimeDelta::FromHours(1));
110 void Simulate(ui::IdleState* states, int len) {
111 for (int i = 0; i < len; i++)
112 IdleStateCallback(states[i]);
115 void set_max_stored_past_activity_days(unsigned int value) {
116 max_stored_past_activity_days_ = value;
119 void set_max_stored_future_activity_days(unsigned int value) {
120 max_stored_future_activity_days_ = value;
123 // Reset the baseline time.
124 void SetBaselineTime(Time time) {
125 baseline_time_ = time;
126 baseline_offset_periods_ = 0;
129 void set_kiosk_account(scoped_ptr<policy::DeviceLocalAccount> account) {
130 kiosk_account_ = account.Pass();
133 scoped_ptr<policy::DeviceLocalAccount>
134 GetAutoLaunchedKioskSessionInfo() override {
135 if (kiosk_account_)
136 return make_scoped_ptr(new policy::DeviceLocalAccount(*kiosk_account_));
137 return scoped_ptr<policy::DeviceLocalAccount>();
140 std::string GetAppVersion(const std::string& app_id) override {
141 // Just return the app_id as the version - this makes it easy for tests
142 // to confirm that the correct app's version was requested.
143 return app_id;
146 void RefreshSampleResourceUsage() {
147 SampleHardwareStatus();
148 content::BrowserThread::GetBlockingPool()->FlushForTesting();
151 protected:
152 void CheckIdleState() override {
153 // This should never be called in testing, as it results in a dbus call.
154 ADD_FAILURE();
157 // Each time this is called, returns a time that is a fixed increment
158 // later than the previous time.
159 Time GetCurrentTime() override {
160 int poll_interval = policy::DeviceStatusCollector::kIdlePollIntervalSeconds;
161 return baseline_time_ +
162 TimeDelta::FromSeconds(poll_interval * baseline_offset_periods_++);
165 private:
166 // Baseline time for the fake times returned from GetCurrentTime().
167 Time baseline_time_;
169 // The number of simulated periods since the baseline time.
170 int baseline_offset_periods_;
172 scoped_ptr<policy::DeviceLocalAccount> kiosk_account_;
175 // Return the total number of active milliseconds contained in a device
176 // status report.
177 int64 GetActiveMilliseconds(em::DeviceStatusReportRequest& status) {
178 int64 active_milliseconds = 0;
179 for (int i = 0; i < status.active_period_size(); i++) {
180 active_milliseconds += status.active_period(i).active_duration();
182 return active_milliseconds;
185 // Mock CPUStatisticsFetcher used to return an empty set of statistics.
186 std::string GetEmptyCPUStatistics() {
187 return std::string();
190 std::string GetFakeCPUStatistics(const std::string& fake) {
191 return fake;
194 // Mock VolumeInfoFetcher used to return empty VolumeInfo, to avoid warnings
195 // and test slowdowns from trying to fetch information about non-existent
196 // volumes.
197 std::vector<em::VolumeInfo> GetEmptyVolumeInfo(
198 const std::vector<std::string>& mount_points) {
199 return std::vector<em::VolumeInfo>();
202 std::vector<em::VolumeInfo> GetFakeVolumeInfo(
203 const std::vector<em::VolumeInfo>& volume_info,
204 const std::vector<std::string>& mount_points) {
205 EXPECT_EQ(volume_info.size(), mount_points.size());
206 // Make sure there's a matching mount point for every volume info.
207 for (const em::VolumeInfo& info : volume_info) {
208 bool found = false;
209 for (const std::string& mount_point : mount_points) {
210 if (info.volume_id() == mount_point) {
211 found = true;
212 break;
215 EXPECT_TRUE(found) << "Could not find matching mount point for "
216 << info.volume_id();
218 return volume_info;
221 } // namespace
223 namespace policy {
225 // Though it is a unit test, this test is linked with browser_tests so that it
226 // runs in a separate process. The intention is to avoid overriding the timezone
227 // environment variable for other tests.
228 class DeviceStatusCollectorTest : public testing::Test {
229 public:
230 DeviceStatusCollectorTest()
231 : ui_thread_(content::BrowserThread::UI, &message_loop_),
232 file_thread_(content::BrowserThread::FILE, &message_loop_),
233 io_thread_(content::BrowserThread::IO, &message_loop_),
234 install_attributes_("managed.com",
235 "user@managed.com",
236 "device_id",
237 DEVICE_MODE_ENTERPRISE),
238 settings_helper_(false),
239 user_manager_(new chromeos::MockUserManager()),
240 user_manager_enabler_(user_manager_),
241 fake_device_local_account_(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
242 kKioskAccountId,
243 kKioskAppId,
244 std::string() /* kiosk_app_update_url */) {
245 // Run this test with a well-known timezone so that Time::LocalMidnight()
246 // returns the same values on all machines.
247 scoped_ptr<base::Environment> env(base::Environment::Create());
248 env->SetVar("TZ", "UTC");
250 // Initialize our mock mounted disk volumes.
251 scoped_ptr<chromeos::disks::MockDiskMountManager> mock_disk_mount_manager =
252 make_scoped_ptr(new chromeos::disks::MockDiskMountManager());
253 AddMountPoint("/mount/volume1");
254 AddMountPoint("/mount/volume2");
255 EXPECT_CALL(*mock_disk_mount_manager, mount_points())
256 .WillRepeatedly(ReturnRef(mount_point_map_));
258 // Setup a fake file system that should show up in mount points.
259 storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
260 storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
261 "c", storage::kFileSystemTypeNativeLocal,
262 storage::FileSystemMountOption(),
263 base::FilePath(FILE_PATH_LITERAL(kExternalMountPoint)));
265 // Just verify that we are properly setting the mount points.
266 std::vector<storage::MountPoints::MountPointInfo> external_mount_points;
267 storage::ExternalMountPoints::GetSystemInstance()->AddMountPointInfosTo(
268 &external_mount_points);
269 EXPECT_FALSE(external_mount_points.empty());
271 // DiskMountManager takes ownership of the MockDiskMountManager.
272 DiskMountManager::InitializeForTesting(mock_disk_mount_manager.release());
273 TestingDeviceStatusCollector::RegisterPrefs(prefs_.registry());
275 settings_helper_.ReplaceProvider(chromeos::kReportDeviceActivityTimes);
276 owner_settings_service_ =
277 settings_helper_.CreateOwnerSettingsService(nullptr);
279 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo),
280 base::Bind(&GetEmptyCPUStatistics));
283 void AddMountPoint(const std::string& mount_point) {
284 mount_point_map_.insert(DiskMountManager::MountPointMap::value_type(
285 mount_point,
286 DiskMountManager::MountPointInfo(
287 mount_point, mount_point, chromeos::MOUNT_TYPE_DEVICE,
288 chromeos::disks::MOUNT_CONDITION_NONE)));
291 ~DeviceStatusCollectorTest() override {
292 // Finish pending tasks.
293 content::BrowserThread::GetBlockingPool()->FlushForTesting();
294 message_loop_.RunUntilIdle();
295 storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
296 DiskMountManager::Shutdown();
299 void SetUp() override {
300 // Disable network interface reporting since it requires additional setup.
301 settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces,
302 false);
305 void TearDown() override { settings_helper_.RestoreProvider(); }
307 void RestartStatusCollector(
308 const policy::DeviceStatusCollector::VolumeInfoFetcher& volume_info,
309 const policy::DeviceStatusCollector::CPUStatisticsFetcher& cpu_stats) {
310 policy::DeviceStatusCollector::LocationUpdateRequester callback =
311 base::Bind(&MockPositionUpdateRequester);
312 std::vector<em::VolumeInfo> expected_volume_info;
313 status_collector_.reset(new TestingDeviceStatusCollector(
314 &prefs_, &fake_statistics_provider_, callback, volume_info, cpu_stats));
317 void GetStatus() {
318 status_.Clear();
319 status_collector_->GetDeviceStatus(&status_);
322 void CheckThatNoLocationIsReported() {
323 GetStatus();
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().
330 GetStatus();
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() {
353 GetStatus();
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(owner_settings_service_.get(), accounts);
365 user_manager_->CreateKioskAppUser(account.user_id);
366 EXPECT_CALL(*user_manager_, IsLoggedInAsKioskApp()).WillRepeatedly(
367 Return(true));
370 protected:
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::ScopedCrosSettingsTestHelper settings_helper_;
391 scoped_ptr<chromeos::FakeOwnerSettingsService> owner_settings_service_;
392 chromeos::MockUserManager* user_manager_;
393 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
394 em::DeviceStatusReportRequest status_;
395 scoped_ptr<TestingDeviceStatusCollector> status_collector_;
396 const policy::DeviceLocalAccount fake_device_local_account_;
399 TEST_F(DeviceStatusCollectorTest, AllIdle) {
400 ui::IdleState test_states[] = {
401 ui::IDLE_STATE_IDLE,
402 ui::IDLE_STATE_IDLE,
403 ui::IDLE_STATE_IDLE
405 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
407 // Test reporting with no data.
408 GetStatus();
409 EXPECT_EQ(0, status_.active_period_size());
410 EXPECT_EQ(0, GetActiveMilliseconds(status_));
412 // Test reporting with a single idle sample.
413 status_collector_->Simulate(test_states, 1);
414 GetStatus();
415 EXPECT_EQ(0, status_.active_period_size());
416 EXPECT_EQ(0, GetActiveMilliseconds(status_));
418 // Test reporting with multiple consecutive idle samples.
419 status_collector_->Simulate(test_states,
420 sizeof(test_states) / sizeof(ui::IdleState));
421 GetStatus();
422 EXPECT_EQ(0, status_.active_period_size());
423 EXPECT_EQ(0, GetActiveMilliseconds(status_));
426 TEST_F(DeviceStatusCollectorTest, AllActive) {
427 ui::IdleState test_states[] = {
428 ui::IDLE_STATE_ACTIVE,
429 ui::IDLE_STATE_ACTIVE,
430 ui::IDLE_STATE_ACTIVE
432 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
434 // Test a single active sample.
435 status_collector_->Simulate(test_states, 1);
436 GetStatus();
437 EXPECT_EQ(1, status_.active_period_size());
438 EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
439 status_.clear_active_period(); // Clear the result protobuf.
441 // Test multiple consecutive active samples.
442 status_collector_->Simulate(test_states,
443 sizeof(test_states) / sizeof(ui::IdleState));
444 GetStatus();
445 EXPECT_EQ(1, status_.active_period_size());
446 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
449 TEST_F(DeviceStatusCollectorTest, MixedStates) {
450 ui::IdleState test_states[] = {
451 ui::IDLE_STATE_ACTIVE,
452 ui::IDLE_STATE_IDLE,
453 ui::IDLE_STATE_ACTIVE,
454 ui::IDLE_STATE_ACTIVE,
455 ui::IDLE_STATE_IDLE,
456 ui::IDLE_STATE_IDLE,
457 ui::IDLE_STATE_ACTIVE
459 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
460 status_collector_->Simulate(test_states,
461 sizeof(test_states) / sizeof(ui::IdleState));
462 GetStatus();
463 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
466 TEST_F(DeviceStatusCollectorTest, StateKeptInPref) {
467 ui::IdleState test_states[] = {
468 ui::IDLE_STATE_ACTIVE,
469 ui::IDLE_STATE_IDLE,
470 ui::IDLE_STATE_ACTIVE,
471 ui::IDLE_STATE_ACTIVE,
472 ui::IDLE_STATE_IDLE,
473 ui::IDLE_STATE_IDLE
475 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
476 status_collector_->Simulate(test_states,
477 sizeof(test_states) / sizeof(ui::IdleState));
479 // Process the list a second time after restarting the collector. It should be
480 // able to count the active periods found by the original collector, because
481 // the results are stored in a pref.
482 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo),
483 base::Bind(&GetEmptyCPUStatistics));
484 status_collector_->Simulate(test_states,
485 sizeof(test_states) / sizeof(ui::IdleState));
487 GetStatus();
488 EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
491 TEST_F(DeviceStatusCollectorTest, Times) {
492 ui::IdleState test_states[] = {
493 ui::IDLE_STATE_ACTIVE,
494 ui::IDLE_STATE_IDLE,
495 ui::IDLE_STATE_ACTIVE,
496 ui::IDLE_STATE_ACTIVE,
497 ui::IDLE_STATE_IDLE,
498 ui::IDLE_STATE_IDLE
500 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
501 status_collector_->Simulate(test_states,
502 sizeof(test_states) / sizeof(ui::IdleState));
503 GetStatus();
504 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
507 TEST_F(DeviceStatusCollectorTest, MaxStoredPeriods) {
508 ui::IdleState test_states[] = {
509 ui::IDLE_STATE_ACTIVE,
510 ui::IDLE_STATE_IDLE
512 const int kMaxDays = 10;
514 settings_helper_.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.
529 GetStatus();
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();
549 GetStatus();
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));
562 GetStatus();
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 settings_helper_.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));
578 GetStatus();
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 settings_helper_.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);
594 GetStatus();
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 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
621 status_collector_->Simulate(test_states, 2);
622 GetStatus();
623 EXPECT_EQ(2 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
624 em::DeviceStatusReportRequest first_status(status_);
626 // The collector returns the same status again.
627 GetStatus();
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();
634 GetStatus();
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);
643 GetStatus();
644 EXPECT_EQ("Verified", status_.boot_mode());
646 // Test that boot mode data is not reported if the pref turned off.
647 settings_helper_.SetBoolean(chromeos::kReportDeviceBootMode, false);
649 GetStatus();
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 settings_helper_.SetBoolean(chromeos::kReportDeviceBootMode, true);
656 fake_statistics_provider_.SetMachineStatistic(
657 chromeos::system::kDevSwitchBootKey, "(error)");
658 GetStatus();
659 EXPECT_FALSE(status_.has_boot_mode());
661 fake_statistics_provider_.SetMachineStatistic(
662 chromeos::system::kDevSwitchBootKey, " ");
663 GetStatus();
664 EXPECT_FALSE(status_.has_boot_mode());
666 fake_statistics_provider_.SetMachineStatistic(
667 chromeos::system::kDevSwitchBootKey,
668 chromeos::system::kDevSwitchBootValueVerified);
669 GetStatus();
670 EXPECT_EQ("Verified", status_.boot_mode());
672 fake_statistics_provider_.SetMachineStatistic(
673 chromeos::system::kDevSwitchBootKey,
674 chromeos::system::kDevSwitchBootValueDev);
675 GetStatus();
676 EXPECT_EQ("Dev", status_.boot_mode());
679 TEST_F(DeviceStatusCollectorTest, VersionInfo) {
680 // Expect the version info to be reported by default.
681 GetStatus();
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 settings_helper_.SetBoolean(chromeos::kReportDeviceVersionInfo, false);
689 GetStatus();
690 EXPECT_FALSE(status_.has_browser_version());
691 EXPECT_FALSE(status_.has_os_version());
692 EXPECT_FALSE(status_.has_firmware_version());
694 settings_helper_.SetBoolean(chromeos::kReportDeviceVersionInfo, true);
695 GetStatus();
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
702 // aren't checked.
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
719 // reported.
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 settings_helper_.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 base::Bind(&GetEmptyCPUStatistics));
735 CheckThatAValidLocationIsReported();
736 EXPECT_TRUE(mock_position_to_return_next.get());
738 // Check that after disabling location reporting again, the last known
739 // location has been cleared from local state and is no longer reported.
740 SetMockPositionToReturnNext(valid_fix);
741 settings_helper_.SetBoolean(chromeos::kReportDeviceLocation, false);
742 // Allow the new pref to propagate to the status collector.
743 message_loop_.RunUntilIdle();
744 EXPECT_TRUE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
745 CheckThatNoLocationIsReported();
747 // Check that after enabling location reporting again, an error is reported
748 // if no valid fix is available.
749 SetMockPositionToReturnNext(invalid_fix);
750 settings_helper_.SetBoolean(chromeos::kReportDeviceLocation, true);
751 // Allow the new pref to propagate to the status collector.
752 message_loop_.RunUntilIdle();
753 CheckThatALocationErrorIsReported();
756 TEST_F(DeviceStatusCollectorTest, ReportUsers) {
757 user_manager_->CreatePublicAccountUser("public@localhost");
758 user_manager_->AddUser("user0@managed.com");
759 user_manager_->AddUser("user1@managed.com");
760 user_manager_->AddUser("user2@managed.com");
761 user_manager_->AddUser("user3@unmanaged.com");
762 user_manager_->AddUser("user4@managed.com");
763 user_manager_->AddUser("user5@managed.com");
765 // Verify that users are reported by default.
766 GetStatus();
767 EXPECT_EQ(6, status_.user_size());
769 // Verify that users are reported after enabling the setting.
770 settings_helper_.SetBoolean(chromeos::kReportDeviceUsers, true);
771 GetStatus();
772 EXPECT_EQ(6, status_.user_size());
773 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(0).type());
774 EXPECT_EQ("user0@managed.com", status_.user(0).email());
775 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(1).type());
776 EXPECT_EQ("user1@managed.com", status_.user(1).email());
777 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(2).type());
778 EXPECT_EQ("user2@managed.com", status_.user(2).email());
779 EXPECT_EQ(em::DeviceUser::USER_TYPE_UNMANAGED, status_.user(3).type());
780 EXPECT_FALSE(status_.user(3).has_email());
781 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(4).type());
782 EXPECT_EQ("user4@managed.com", status_.user(4).email());
783 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(5).type());
784 EXPECT_EQ("user5@managed.com", status_.user(5).email());
786 // Verify that users are no longer reported if setting is disabled.
787 settings_helper_.SetBoolean(chromeos::kReportDeviceUsers, false);
788 GetStatus();
789 EXPECT_EQ(0, status_.user_size());
792 TEST_F(DeviceStatusCollectorTest, TestVolumeInfo) {
793 std::vector<std::string> expected_mount_points;
794 std::vector<em::VolumeInfo> expected_volume_info;
795 int size = 12345678;
796 for (const auto& mount_info :
797 DiskMountManager::GetInstance()->mount_points()) {
798 expected_mount_points.push_back(mount_info.first);
800 expected_mount_points.push_back(kExternalMountPoint);
802 for (const std::string& mount_point : expected_mount_points) {
803 em::VolumeInfo info;
804 info.set_volume_id(mount_point);
805 // Just put unique numbers in for storage_total/free.
806 info.set_storage_total(size++);
807 info.set_storage_free(size++);
808 expected_volume_info.push_back(info);
810 EXPECT_FALSE(expected_volume_info.empty());
812 RestartStatusCollector(base::Bind(&GetFakeVolumeInfo, expected_volume_info),
813 base::Bind(&GetEmptyCPUStatistics));
814 // Force finishing tasks posted by ctor of DeviceStatusCollector.
815 content::BrowserThread::GetBlockingPool()->FlushForTesting();
816 message_loop_.RunUntilIdle();
818 GetStatus();
819 EXPECT_EQ(expected_mount_points.size(),
820 static_cast<size_t>(status_.volume_info_size()));
822 // Walk the returned VolumeInfo to make sure it matches.
823 for (const em::VolumeInfo& expected_info : expected_volume_info) {
824 bool found = false;
825 for (const em::VolumeInfo& info : status_.volume_info()) {
826 if (info.volume_id() == expected_info.volume_id()) {
827 EXPECT_EQ(expected_info.storage_total(), info.storage_total());
828 EXPECT_EQ(expected_info.storage_free(), info.storage_free());
829 found = true;
830 break;
833 EXPECT_TRUE(found) << "No matching VolumeInfo for "
834 << expected_info.volume_id();
837 // Now turn off hardware status reporting - should have no data.
838 settings_helper_.SetBoolean(chromeos::kReportDeviceHardwareStatus, false);
839 GetStatus();
840 EXPECT_EQ(0, status_.volume_info_size());
843 TEST_F(DeviceStatusCollectorTest, TestAvailableMemory) {
844 // Refresh our samples. Sample more than kMaxHardwareSamples times to
845 // make sure that the code correctly caps the number of cached samples.
846 for (int i = 0; i < static_cast<int>(
847 DeviceStatusCollector::kMaxResourceUsageSamples + 1);
848 ++i) {
849 status_collector_->RefreshSampleResourceUsage();
850 message_loop_.RunUntilIdle();
852 GetStatus();
853 EXPECT_EQ(static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples),
854 status_.system_ram_free().size());
855 EXPECT_TRUE(status_.has_system_ram_total());
856 // No good way to inject specific test values for available system RAM, so
857 // just make sure it's > 0.
858 EXPECT_GT(status_.system_ram_total(), 0);
861 TEST_F(DeviceStatusCollectorTest, TestCPUSamples) {
862 // Mock 100% CPU usage.
863 std::string full_cpu_usage("cpu 500 0 500 0 0 0 0");
864 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo),
865 base::Bind(&GetFakeCPUStatistics, full_cpu_usage));
866 // Force finishing tasks posted by ctor of DeviceStatusCollector.
867 content::BrowserThread::GetBlockingPool()->FlushForTesting();
868 message_loop_.RunUntilIdle();
869 GetStatus();
870 ASSERT_EQ(1, status_.cpu_utilization_pct().size());
871 EXPECT_EQ(100, status_.cpu_utilization_pct(0));
873 // Now sample CPU usage again (active usage counters will not increase
874 // so should show 0% cpu usage).
875 status_collector_->RefreshSampleResourceUsage();
876 message_loop_.RunUntilIdle();
877 GetStatus();
878 ASSERT_EQ(2, status_.cpu_utilization_pct().size());
879 EXPECT_EQ(0, status_.cpu_utilization_pct(1));
881 // Now store a bunch of 0% cpu usage and make sure we cap the max number of
882 // samples.
883 for (int i = 0;
884 i < static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples);
885 ++i) {
886 status_collector_->RefreshSampleResourceUsage();
887 message_loop_.RunUntilIdle();
889 GetStatus();
891 // Should not be more than kMaxResourceUsageSamples, and they should all show
892 // the CPU is idle.
893 EXPECT_EQ(static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples),
894 status_.cpu_utilization_pct().size());
895 for (const auto utilization : status_.cpu_utilization_pct())
896 EXPECT_EQ(0, utilization);
898 // Turning off hardware reporting should not report CPU utilization.
899 settings_helper_.SetBoolean(chromeos::kReportDeviceHardwareStatus, false);
900 GetStatus();
901 EXPECT_EQ(0, status_.cpu_utilization_pct().size());
904 TEST_F(DeviceStatusCollectorTest, NoSessionStatusIfNotKioskMode) {
905 // Should not report session status if we don't have an active kiosk app.
906 settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, true);
907 em::SessionStatusReportRequest session_status;
908 EXPECT_FALSE(status_collector_->GetDeviceSessionStatus(&session_status));
911 TEST_F(DeviceStatusCollectorTest, NoSessionStatusIfSessionReportingDisabled) {
912 // Should not report session status if session status reporting is disabled.
913 settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, false);
914 status_collector_->set_kiosk_account(make_scoped_ptr(
915 new policy::DeviceLocalAccount(fake_device_local_account_)).Pass());
916 // Set up a device-local account for single-app kiosk mode.
917 MockRunningKioskApp(fake_device_local_account_);
919 em::SessionStatusReportRequest session_status;
920 EXPECT_FALSE(status_collector_->GetDeviceSessionStatus(&session_status));
923 TEST_F(DeviceStatusCollectorTest, ReportSessionStatus) {
924 settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, true);
925 status_collector_->set_kiosk_account(make_scoped_ptr(
926 new policy::DeviceLocalAccount(fake_device_local_account_)).Pass());
928 // Set up a device-local account for single-app kiosk mode.
929 MockRunningKioskApp(fake_device_local_account_);
931 em::SessionStatusReportRequest session_status;
932 EXPECT_TRUE(status_collector_->GetDeviceSessionStatus(&session_status));
933 ASSERT_EQ(1, session_status.installed_apps_size());
934 EXPECT_EQ(kKioskAccountId, session_status.device_local_account_id());
935 const em::AppStatus app = session_status.installed_apps(0);
936 EXPECT_EQ(kKioskAppId, app.app_id());
937 // Test code just sets the version to the app ID.
938 EXPECT_EQ(kKioskAppId, app.extension_version());
939 EXPECT_FALSE(app.has_status());
940 EXPECT_FALSE(app.has_error());
943 // Fake device state.
944 struct FakeDeviceData {
945 const char* device_path;
946 const char* type;
947 const char* object_path;
948 const char* mac_address;
949 const char* meid;
950 const char* imei;
951 int expected_type; // proto enum type value, -1 for not present.
954 static const FakeDeviceData kFakeDevices[] = {
955 { "/device/ethernet", shill::kTypeEthernet, "ethernet",
956 "112233445566", "", "",
957 em::NetworkInterface::TYPE_ETHERNET },
958 { "/device/cellular1", shill::kTypeCellular, "cellular1",
959 "abcdefabcdef", "A10000009296F2", "",
960 em::NetworkInterface::TYPE_CELLULAR },
961 { "/device/cellular2", shill::kTypeCellular, "cellular2",
962 "abcdefabcdef", "", "352099001761481",
963 em::NetworkInterface::TYPE_CELLULAR },
964 { "/device/wifi", shill::kTypeWifi, "wifi",
965 "aabbccddeeff", "", "",
966 em::NetworkInterface::TYPE_WIFI },
967 { "/device/bluetooth", shill::kTypeBluetooth, "bluetooth",
968 "", "", "",
969 em::NetworkInterface::TYPE_BLUETOOTH },
970 { "/device/vpn", shill::kTypeVPN, "vpn",
971 "", "", "",
972 -1 },
975 // Fake network state.
976 struct FakeNetworkState {
977 const char* name;
978 const char* device_path;
979 const char* type;
980 int signal_strength;
981 int expected_signal_strength;
982 const char* connection_status;
983 int expected_state;
984 const char* address;
985 const char* gateway;
988 // List of fake networks - primarily used to make sure that signal strength
989 // and connection state are properly populated in status reports. Note that
990 // by convention shill will not report a signal strength of 0 for a visible
991 // network, so we use 1 below.
992 static const FakeNetworkState kFakeNetworks[] = {
993 { "offline", "/device/wifi", shill::kTypeWifi, 35, -85,
994 shill::kStateOffline, em::NetworkState::OFFLINE, "", "" },
995 { "ethernet", "/device/ethernet", shill::kTypeEthernet, 0, 0,
996 shill::kStateOnline, em::NetworkState::ONLINE,
997 "192.168.0.1", "8.8.8.8" },
998 { "wifi", "/device/wifi", shill::kTypeWifi, 23, -97, shill::kStatePortal,
999 em::NetworkState::PORTAL, "", "" },
1000 { "idle", "/device/cellular1", shill::kTypeCellular, 0, 0, shill::kStateIdle,
1001 em::NetworkState::IDLE, "", "" },
1002 { "carrier", "/device/cellular1", shill::kTypeCellular, 0, 0,
1003 shill::kStateCarrier, em::NetworkState::CARRIER, "", "" },
1004 { "association", "/device/cellular1", shill::kTypeCellular, 0, 0,
1005 shill::kStateAssociation, em::NetworkState::ASSOCIATION, "", "" },
1006 { "config", "/device/cellular1", shill::kTypeCellular, 0, 0,
1007 shill::kStateConfiguration, em::NetworkState::CONFIGURATION, "", "" },
1008 // Set signal strength for this network to -20, but expected strength to 0
1009 // to test that we only report signal_strength for wifi connections.
1010 { "ready", "/device/cellular1", shill::kTypeCellular, -20, 0,
1011 shill::kStateReady, em::NetworkState::READY, "", "" },
1012 { "disconnect", "/device/wifi", shill::kTypeWifi, 1, -119,
1013 shill::kStateDisconnect, em::NetworkState::DISCONNECT, "", "" },
1014 { "failure", "/device/wifi", shill::kTypeWifi, 1, -119, shill::kStateFailure,
1015 em::NetworkState::FAILURE, "", "" },
1016 { "activation-failure", "/device/cellular1", shill::kTypeCellular, 0, 0,
1017 shill::kStateActivationFailure, em::NetworkState::ACTIVATION_FAILURE,
1018 "", "" },
1019 { "unknown", "", shill::kTypeWifi, 1, -119, "unknown",
1020 em::NetworkState::UNKNOWN, "", "" },
1023 static const FakeNetworkState kUnconfiguredNetwork = {
1024 "unconfigured", "/device/unconfigured", shill::kTypeWifi, 35, -85,
1025 shill::kStateOffline, em::NetworkState::OFFLINE, "", ""
1028 class DeviceStatusCollectorNetworkInterfacesTest
1029 : public DeviceStatusCollectorTest {
1030 protected:
1031 void SetUp() override {
1032 chromeos::DBusThreadManager::Initialize();
1033 chromeos::NetworkHandler::Initialize();
1034 chromeos::ShillDeviceClient::TestInterface* test_device_client =
1035 chromeos::DBusThreadManager::Get()->GetShillDeviceClient()->
1036 GetTestInterface();
1037 test_device_client->ClearDevices();
1038 for (size_t i = 0; i < arraysize(kFakeDevices); ++i) {
1039 const FakeDeviceData& dev = kFakeDevices[i];
1040 test_device_client->AddDevice(dev.device_path, dev.type,
1041 dev.object_path);
1042 if (*dev.mac_address) {
1043 test_device_client->SetDeviceProperty(
1044 dev.device_path, shill::kAddressProperty,
1045 base::StringValue(dev.mac_address));
1047 if (*dev.meid) {
1048 test_device_client->SetDeviceProperty(
1049 dev.device_path, shill::kMeidProperty,
1050 base::StringValue(dev.meid));
1052 if (*dev.imei) {
1053 test_device_client->SetDeviceProperty(
1054 dev.device_path, shill::kImeiProperty,
1055 base::StringValue(dev.imei));
1059 chromeos::ShillServiceClient::TestInterface* service_client =
1060 chromeos::DBusThreadManager::Get()->GetShillServiceClient()->
1061 GetTestInterface();
1062 service_client->ClearServices();
1064 // Now add services for every fake network.
1065 for (const FakeNetworkState& fake_network : kFakeNetworks) {
1066 // Shill forces non-visible networks to report a disconnected state.
1067 bool is_visible =
1068 fake_network.connection_status != shill::kStateDisconnect;
1069 service_client->AddService(
1070 fake_network.name, /* service_path */
1071 fake_network.name /* guid */,
1072 fake_network.name /* name */,
1073 fake_network.type /* type */,
1074 fake_network.connection_status,
1075 is_visible);
1076 service_client->SetServiceProperty(
1077 fake_network.name, shill::kSignalStrengthProperty,
1078 base::FundamentalValue(fake_network.signal_strength));
1079 service_client->SetServiceProperty(
1080 fake_network.name, shill::kDeviceProperty,
1081 base::StringValue(fake_network.device_path));
1082 // Set the profile so this shows up as a configured network.
1083 service_client->SetServiceProperty(
1084 fake_network.name, shill::kProfileProperty,
1085 base::StringValue(fake_network.name));
1086 if (strlen(fake_network.address) > 0) {
1087 // Set the IP config.
1088 base::DictionaryValue ip_config_properties;
1089 ip_config_properties.SetStringWithoutPathExpansion(
1090 shill::kAddressProperty, fake_network.address);
1091 ip_config_properties.SetStringWithoutPathExpansion(
1092 shill::kGatewayProperty, fake_network.gateway);
1093 chromeos::ShillIPConfigClient::TestInterface* ip_config_test =
1094 chromeos::DBusThreadManager::Get()->GetShillIPConfigClient()->
1095 GetTestInterface();
1096 const std::string kIPConfigPath = "test_ip_config";
1097 ip_config_test->AddIPConfig(kIPConfigPath, ip_config_properties);
1098 service_client->SetServiceProperty(
1099 fake_network.name, shill::kIPConfigProperty,
1100 base::StringValue(kIPConfigPath));
1104 // Now add an unconfigured network - it should not show up in the
1105 // reported list of networks because it doesn't have a profile specified.
1106 service_client->AddService(
1107 kUnconfiguredNetwork.name, /* service_path */
1108 kUnconfiguredNetwork.name /* guid */,
1109 kUnconfiguredNetwork.name /* name */,
1110 kUnconfiguredNetwork.type /* type */,
1111 kUnconfiguredNetwork.connection_status,
1112 true /* visible */);
1113 service_client->SetServiceProperty(
1114 kUnconfiguredNetwork.name, shill::kSignalStrengthProperty,
1115 base::FundamentalValue(kUnconfiguredNetwork.signal_strength));
1116 service_client->SetServiceProperty(
1117 kUnconfiguredNetwork.name, shill::kDeviceProperty,
1118 base::StringValue(kUnconfiguredNetwork.device_path));
1120 // Flush out pending state updates.
1121 base::RunLoop().RunUntilIdle();
1123 chromeos::NetworkStateHandler::NetworkStateList state_list;
1124 chromeos::NetworkStateHandler* network_state_handler =
1125 chromeos::NetworkHandler::Get()->network_state_handler();
1126 network_state_handler->GetNetworkListByType(
1127 chromeos::NetworkTypePattern::Default(),
1128 true, // configured_only
1129 false, // visible_only,
1130 0, // no limit to number of results
1131 &state_list);
1132 ASSERT_EQ(arraysize(kFakeNetworks), state_list.size());
1135 void TearDown() override {
1136 chromeos::NetworkHandler::Shutdown();
1137 chromeos::DBusThreadManager::Shutdown();
1141 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, NoNetworkStateIfNotKiosk) {
1142 // If not in an active kiosk session, there should be network interfaces
1143 // reported, but no network state.
1144 GetStatus();
1145 EXPECT_LT(0, status_.network_interface_size());
1146 EXPECT_EQ(0, status_.network_state_size());
1149 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, NetworkInterfaces) {
1150 // Mock that we are in kiosk mode so we report network state.
1151 status_collector_->set_kiosk_account(make_scoped_ptr(
1152 new policy::DeviceLocalAccount(fake_device_local_account_)).Pass());
1154 // Interfaces should be reported by default.
1155 GetStatus();
1156 EXPECT_LT(0, status_.network_interface_size());
1157 EXPECT_LT(0, status_.network_state_size());
1159 // No interfaces should be reported if the policy is off.
1160 settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces, false);
1161 GetStatus();
1162 EXPECT_EQ(0, status_.network_interface_size());
1163 EXPECT_EQ(0, status_.network_state_size());
1165 // Switch the policy on and verify the interface list is present.
1166 settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces, true);
1167 GetStatus();
1169 int count = 0;
1170 for (size_t i = 0; i < arraysize(kFakeDevices); ++i) {
1171 const FakeDeviceData& dev = kFakeDevices[i];
1172 if (dev.expected_type == -1)
1173 continue;
1175 // Find the corresponding entry in reporting data.
1176 bool found_match = false;
1177 google::protobuf::RepeatedPtrField<em::NetworkInterface>::const_iterator
1178 iface;
1179 for (iface = status_.network_interface().begin();
1180 iface != status_.network_interface().end();
1181 ++iface) {
1182 // Check whether type, field presence and field values match.
1183 if (dev.expected_type == iface->type() &&
1184 iface->has_mac_address() == !!*dev.mac_address &&
1185 iface->has_meid() == !!*dev.meid &&
1186 iface->has_imei() == !!*dev.imei &&
1187 iface->mac_address() == dev.mac_address &&
1188 iface->meid() == dev.meid &&
1189 iface->imei() == dev.imei &&
1190 iface->device_path() == dev.device_path) {
1191 found_match = true;
1192 break;
1196 EXPECT_TRUE(found_match) << "No matching interface for fake device " << i;
1197 count++;
1200 EXPECT_EQ(count, status_.network_interface_size());
1202 // Now make sure network state list is correct.
1203 EXPECT_EQ(arraysize(kFakeNetworks),
1204 static_cast<size_t>(status_.network_state_size()));
1205 for (const FakeNetworkState& state : kFakeNetworks) {
1206 bool found_match = false;
1207 for (const em::NetworkState& proto_state : status_.network_state()) {
1208 // Make sure every item has a matching entry in the proto.
1209 bool should_have_signal_strength = state.expected_signal_strength != 0;
1210 if (proto_state.has_device_path() == (strlen(state.device_path) > 0) &&
1211 proto_state.has_signal_strength() == should_have_signal_strength &&
1212 proto_state.signal_strength() == state.expected_signal_strength &&
1213 proto_state.connection_state() == state.expected_state) {
1214 if (proto_state.has_ip_address())
1215 EXPECT_EQ(proto_state.ip_address(), state.address);
1216 else
1217 EXPECT_EQ(0U, strlen(state.address));
1218 if (proto_state.has_gateway())
1219 EXPECT_EQ(proto_state.gateway(), state.gateway);
1220 else
1221 EXPECT_EQ(0U, strlen(state.gateway));
1222 found_match = true;
1223 break;
1226 EXPECT_TRUE(found_match) << "No matching state for fake network "
1227 << " (" << state.name << ")";
1231 } // namespace policy