Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / device_status_collector_browsertest.cc
blobec8f39556af8274c9c9c0855efe50f281d6197a5
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/strings/stringprintf.h"
19 #include "base/threading/sequenced_worker_pool.h"
20 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
21 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
22 #include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h"
23 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
24 #include "chrome/browser/chromeos/policy/device_local_account.h"
25 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
26 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.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/system/fake_statistics_provider.h"
41 #include "content/public/browser/browser_thread.h"
42 #include "content/public/browser/geolocation_provider.h"
43 #include "content/public/test/test_browser_thread.h"
44 #include "content/public/test/test_utils.h"
45 #include "policy/proto/device_management_backend.pb.h"
46 #include "storage/browser/fileapi/external_mount_points.h"
47 #include "storage/browser/fileapi/mount_points.h"
48 #include "storage/common/fileapi/file_system_mount_option.h"
49 #include "storage/common/fileapi/file_system_types.h"
50 #include "testing/gmock/include/gmock/gmock.h"
51 #include "testing/gtest/include/gtest/gtest.h"
52 #include "third_party/cros_system_api/dbus/service_constants.h"
54 using ::testing::Return;
55 using ::testing::ReturnRef;
56 using base::Time;
57 using base::TimeDelta;
58 using chromeos::disks::DiskMountManager;
60 namespace em = enterprise_management;
62 namespace {
64 const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
65 const char kKioskAccountId[] = "kiosk_user@localhost";
66 const char kKioskAppId[] = "kiosk_app_id";
67 const char kExternalMountPoint[] = "/a/b/c";
68 const char kPublicAccountId[] = "public_user@localhost";
70 scoped_ptr<content::Geoposition> mock_position_to_return_next;
72 void SetMockPositionToReturnNext(const content::Geoposition &position) {
73 mock_position_to_return_next.reset(new content::Geoposition(position));
76 void MockPositionUpdateRequester(
77 const content::GeolocationProvider::LocationUpdateCallback& callback) {
78 if (!mock_position_to_return_next.get())
79 return;
81 // If the fix is invalid, the DeviceStatusCollector will immediately request
82 // another update when it receives the callback. This is desirable and safe in
83 // real life where geolocation updates arrive asynchronously. In this testing
84 // harness, the callback is invoked synchronously upon request, leading to a
85 // request-callback loop. The loop is broken by returning the mock position
86 // only once.
87 scoped_ptr<content::Geoposition> position(
88 mock_position_to_return_next.release());
89 callback.Run(*position);
92 class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
93 public:
94 TestingDeviceStatusCollector(
95 PrefService* local_state,
96 chromeos::system::StatisticsProvider* provider,
97 const policy::DeviceStatusCollector::LocationUpdateRequester&
98 location_update_requester,
99 const policy::DeviceStatusCollector::VolumeInfoFetcher&
100 volume_info_fetcher,
101 const policy::DeviceStatusCollector::CPUStatisticsFetcher& cpu_fetcher,
102 const policy::DeviceStatusCollector::CPUTempFetcher& cpu_temp_fetcher)
103 : policy::DeviceStatusCollector(local_state,
104 provider,
105 location_update_requester,
106 volume_info_fetcher,
107 cpu_fetcher,
108 cpu_temp_fetcher) {
109 // Set the baseline time to a fixed value (1 AM) to prevent test flakiness
110 // due to a single activity period spanning two days.
111 SetBaselineTime(Time::Now().LocalMidnight() + TimeDelta::FromHours(1));
114 void Simulate(ui::IdleState* states, int len) {
115 for (int i = 0; i < len; i++)
116 IdleStateCallback(states[i]);
119 void set_max_stored_past_activity_days(unsigned int value) {
120 max_stored_past_activity_days_ = value;
123 void set_max_stored_future_activity_days(unsigned int value) {
124 max_stored_future_activity_days_ = value;
127 // Reset the baseline time.
128 void SetBaselineTime(Time time) {
129 baseline_time_ = time;
130 baseline_offset_periods_ = 0;
133 void set_kiosk_account(scoped_ptr<policy::DeviceLocalAccount> account) {
134 kiosk_account_ = account.Pass();
137 scoped_ptr<policy::DeviceLocalAccount>
138 GetAutoLaunchedKioskSessionInfo() override {
139 if (kiosk_account_)
140 return make_scoped_ptr(new policy::DeviceLocalAccount(*kiosk_account_));
141 return scoped_ptr<policy::DeviceLocalAccount>();
144 std::string GetAppVersion(const std::string& app_id) override {
145 // Just return the app_id as the version - this makes it easy for tests
146 // to confirm that the correct app's version was requested.
147 return app_id;
150 void RefreshSampleResourceUsage() {
151 SampleHardwareStatus();
152 content::BrowserThread::GetBlockingPool()->FlushForTesting();
155 protected:
156 void CheckIdleState() override {
157 // This should never be called in testing, as it results in a dbus call.
158 ADD_FAILURE();
161 // Each time this is called, returns a time that is a fixed increment
162 // later than the previous time.
163 Time GetCurrentTime() override {
164 int poll_interval = policy::DeviceStatusCollector::kIdlePollIntervalSeconds;
165 return baseline_time_ +
166 TimeDelta::FromSeconds(poll_interval * baseline_offset_periods_++);
169 private:
170 // Baseline time for the fake times returned from GetCurrentTime().
171 Time baseline_time_;
173 // The number of simulated periods since the baseline time.
174 int baseline_offset_periods_;
176 scoped_ptr<policy::DeviceLocalAccount> kiosk_account_;
179 // Return the total number of active milliseconds contained in a device
180 // status report.
181 int64 GetActiveMilliseconds(em::DeviceStatusReportRequest& status) {
182 int64 active_milliseconds = 0;
183 for (int i = 0; i < status.active_period_size(); i++) {
184 active_milliseconds += status.active_period(i).active_duration();
186 return active_milliseconds;
189 // Mock CPUStatisticsFetcher used to return an empty set of statistics.
190 std::string GetEmptyCPUStatistics() {
191 return std::string();
194 std::string GetFakeCPUStatistics(const std::string& fake) {
195 return fake;
198 // Mock VolumeInfoFetcher used to return empty VolumeInfo, to avoid warnings
199 // and test slowdowns from trying to fetch information about non-existent
200 // volumes.
201 std::vector<em::VolumeInfo> GetEmptyVolumeInfo(
202 const std::vector<std::string>& mount_points) {
203 return std::vector<em::VolumeInfo>();
206 std::vector<em::VolumeInfo> GetFakeVolumeInfo(
207 const std::vector<em::VolumeInfo>& volume_info,
208 const std::vector<std::string>& mount_points) {
209 EXPECT_EQ(volume_info.size(), mount_points.size());
210 // Make sure there's a matching mount point for every volume info.
211 for (const em::VolumeInfo& info : volume_info) {
212 bool found = false;
213 for (const std::string& mount_point : mount_points) {
214 if (info.volume_id() == mount_point) {
215 found = true;
216 break;
219 EXPECT_TRUE(found) << "Could not find matching mount point for "
220 << info.volume_id();
222 return volume_info;
225 std::vector<em::CPUTempInfo> GetEmptyCPUTempInfo() {
226 return std::vector<em::CPUTempInfo>();
229 std::vector<em::CPUTempInfo> GetFakeCPUTempInfo(
230 const std::vector<em::CPUTempInfo>& cpu_temp_info) {
231 return cpu_temp_info;
234 } // namespace
236 namespace policy {
238 // Though it is a unit test, this test is linked with browser_tests so that it
239 // runs in a separate process. The intention is to avoid overriding the timezone
240 // environment variable for other tests.
241 class DeviceStatusCollectorTest : public testing::Test {
242 public:
243 DeviceStatusCollectorTest()
244 : ui_thread_(content::BrowserThread::UI, &message_loop_),
245 file_thread_(content::BrowserThread::FILE, &message_loop_),
246 io_thread_(content::BrowserThread::IO, &message_loop_),
247 install_attributes_("managed.com",
248 "user@managed.com",
249 "device_id",
250 DEVICE_MODE_ENTERPRISE),
251 settings_helper_(false),
252 user_manager_(new chromeos::MockUserManager()),
253 user_manager_enabler_(user_manager_),
254 fake_device_local_account_(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
255 kKioskAccountId,
256 kKioskAppId,
257 std::string() /* kiosk_app_update_url */) {
258 // Run this test with a well-known timezone so that Time::LocalMidnight()
259 // returns the same values on all machines.
260 scoped_ptr<base::Environment> env(base::Environment::Create());
261 env->SetVar("TZ", "UTC");
263 // Initialize our mock mounted disk volumes.
264 scoped_ptr<chromeos::disks::MockDiskMountManager> mock_disk_mount_manager =
265 make_scoped_ptr(new chromeos::disks::MockDiskMountManager());
266 AddMountPoint("/mount/volume1");
267 AddMountPoint("/mount/volume2");
268 EXPECT_CALL(*mock_disk_mount_manager, mount_points())
269 .WillRepeatedly(ReturnRef(mount_point_map_));
271 // Setup a fake file system that should show up in mount points.
272 storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
273 storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
274 "c", storage::kFileSystemTypeNativeLocal,
275 storage::FileSystemMountOption(),
276 base::FilePath(FILE_PATH_LITERAL(kExternalMountPoint)));
278 // Just verify that we are properly setting the mount points.
279 std::vector<storage::MountPoints::MountPointInfo> external_mount_points;
280 storage::ExternalMountPoints::GetSystemInstance()->AddMountPointInfosTo(
281 &external_mount_points);
282 EXPECT_FALSE(external_mount_points.empty());
284 // DiskMountManager takes ownership of the MockDiskMountManager.
285 DiskMountManager::InitializeForTesting(mock_disk_mount_manager.release());
286 TestingDeviceStatusCollector::RegisterPrefs(prefs_.registry());
288 settings_helper_.ReplaceProvider(chromeos::kReportDeviceActivityTimes);
289 owner_settings_service_ =
290 settings_helper_.CreateOwnerSettingsService(nullptr);
292 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo),
293 base::Bind(&GetEmptyCPUStatistics),
294 base::Bind(&GetEmptyCPUTempInfo));
297 void AddMountPoint(const std::string& mount_point) {
298 mount_point_map_.insert(DiskMountManager::MountPointMap::value_type(
299 mount_point,
300 DiskMountManager::MountPointInfo(
301 mount_point, mount_point, chromeos::MOUNT_TYPE_DEVICE,
302 chromeos::disks::MOUNT_CONDITION_NONE)));
305 ~DeviceStatusCollectorTest() override {
306 // Finish pending tasks.
307 content::BrowserThread::GetBlockingPool()->FlushForTesting();
308 message_loop_.RunUntilIdle();
309 storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
310 DiskMountManager::Shutdown();
313 void SetUp() override {
314 // Disable network interface reporting since it requires additional setup.
315 settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces,
316 false);
319 void TearDown() override { settings_helper_.RestoreProvider(); }
321 void RestartStatusCollector(
322 const policy::DeviceStatusCollector::VolumeInfoFetcher& volume_info,
323 const policy::DeviceStatusCollector::CPUStatisticsFetcher& cpu_stats,
324 const policy::DeviceStatusCollector::CPUTempFetcher& cpu_temp_fetcher) {
325 policy::DeviceStatusCollector::LocationUpdateRequester callback =
326 base::Bind(&MockPositionUpdateRequester);
327 std::vector<em::VolumeInfo> expected_volume_info;
328 status_collector_.reset(new TestingDeviceStatusCollector(
329 &prefs_, &fake_statistics_provider_, callback, volume_info, cpu_stats,
330 cpu_temp_fetcher));
333 void GetStatus() {
334 status_.Clear();
335 status_collector_->GetDeviceStatus(&status_);
338 void CheckThatNoLocationIsReported() {
339 GetStatus();
340 EXPECT_FALSE(status_.has_device_location());
343 void CheckThatAValidLocationIsReported() {
344 // Checks that a location is being reported which matches the valid fix
345 // set using SetMockPositionToReturnNext().
346 GetStatus();
347 EXPECT_TRUE(status_.has_device_location());
348 em::DeviceLocation location = status_.device_location();
349 if (location.has_error_code())
350 EXPECT_EQ(em::DeviceLocation::ERROR_CODE_NONE, location.error_code());
351 EXPECT_TRUE(location.has_latitude());
352 EXPECT_TRUE(location.has_longitude());
353 EXPECT_TRUE(location.has_accuracy());
354 EXPECT_TRUE(location.has_timestamp());
355 EXPECT_FALSE(location.has_altitude());
356 EXPECT_FALSE(location.has_altitude_accuracy());
357 EXPECT_FALSE(location.has_heading());
358 EXPECT_FALSE(location.has_speed());
359 EXPECT_FALSE(location.has_error_message());
360 EXPECT_DOUBLE_EQ(4.3, location.latitude());
361 EXPECT_DOUBLE_EQ(-7.8, location.longitude());
362 EXPECT_DOUBLE_EQ(3., location.accuracy());
363 // Check that the timestamp is not older than ten minutes.
364 EXPECT_TRUE(Time::Now() - Time::FromDoubleT(location.timestamp() / 1000.) <
365 TimeDelta::FromMinutes(10));
368 void CheckThatALocationErrorIsReported() {
369 GetStatus();
370 EXPECT_TRUE(status_.has_device_location());
371 em::DeviceLocation location = status_.device_location();
372 EXPECT_TRUE(location.has_error_code());
373 EXPECT_EQ(em::DeviceLocation::ERROR_CODE_POSITION_UNAVAILABLE,
374 location.error_code());
377 void MockRunningKioskApp(const DeviceLocalAccount& account) {
378 std::vector<DeviceLocalAccount> accounts;
379 accounts.push_back(account);
380 SetDeviceLocalAccounts(owner_settings_service_.get(), accounts);
381 user_manager_->CreateKioskAppUser(account.user_id);
382 EXPECT_CALL(*user_manager_, IsLoggedInAsKioskApp()).WillRepeatedly(
383 Return(true));
386 protected:
387 // Convenience method.
388 int64 ActivePeriodMilliseconds() {
389 return policy::DeviceStatusCollector::kIdlePollIntervalSeconds * 1000;
392 // Since this is a unit test running in browser_tests we must do additional
393 // unit test setup and make a TestingBrowserProcess. Must be first member.
394 TestingBrowserProcessInitializer initializer_;
395 base::MessageLoopForUI message_loop_;
396 content::TestBrowserThread ui_thread_;
397 content::TestBrowserThread file_thread_;
398 content::TestBrowserThread io_thread_;
400 ScopedStubEnterpriseInstallAttributes install_attributes_;
401 TestingPrefServiceSimple prefs_;
402 chromeos::system::ScopedFakeStatisticsProvider fake_statistics_provider_;
403 DiskMountManager::MountPointMap mount_point_map_;
404 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
405 chromeos::ScopedTestCrosSettings test_cros_settings_;
406 chromeos::ScopedCrosSettingsTestHelper settings_helper_;
407 scoped_ptr<chromeos::FakeOwnerSettingsService> owner_settings_service_;
408 chromeos::MockUserManager* user_manager_;
409 chromeos::ScopedUserManagerEnabler user_manager_enabler_;
410 em::DeviceStatusReportRequest status_;
411 scoped_ptr<TestingDeviceStatusCollector> status_collector_;
412 const policy::DeviceLocalAccount fake_device_local_account_;
415 TEST_F(DeviceStatusCollectorTest, AllIdle) {
416 ui::IdleState test_states[] = {
417 ui::IDLE_STATE_IDLE,
418 ui::IDLE_STATE_IDLE,
419 ui::IDLE_STATE_IDLE
421 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
423 // Test reporting with no data.
424 GetStatus();
425 EXPECT_EQ(0, status_.active_period_size());
426 EXPECT_EQ(0, GetActiveMilliseconds(status_));
428 // Test reporting with a single idle sample.
429 status_collector_->Simulate(test_states, 1);
430 GetStatus();
431 EXPECT_EQ(0, status_.active_period_size());
432 EXPECT_EQ(0, GetActiveMilliseconds(status_));
434 // Test reporting with multiple consecutive idle samples.
435 status_collector_->Simulate(test_states,
436 sizeof(test_states) / sizeof(ui::IdleState));
437 GetStatus();
438 EXPECT_EQ(0, status_.active_period_size());
439 EXPECT_EQ(0, GetActiveMilliseconds(status_));
442 TEST_F(DeviceStatusCollectorTest, AllActive) {
443 ui::IdleState test_states[] = {
444 ui::IDLE_STATE_ACTIVE,
445 ui::IDLE_STATE_ACTIVE,
446 ui::IDLE_STATE_ACTIVE
448 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
450 // Test a single active sample.
451 status_collector_->Simulate(test_states, 1);
452 GetStatus();
453 EXPECT_EQ(1, status_.active_period_size());
454 EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
455 status_.clear_active_period(); // Clear the result protobuf.
457 // Test multiple consecutive active samples.
458 status_collector_->Simulate(test_states,
459 sizeof(test_states) / sizeof(ui::IdleState));
460 GetStatus();
461 EXPECT_EQ(1, status_.active_period_size());
462 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
465 TEST_F(DeviceStatusCollectorTest, MixedStates) {
466 ui::IdleState test_states[] = {
467 ui::IDLE_STATE_ACTIVE,
468 ui::IDLE_STATE_IDLE,
469 ui::IDLE_STATE_ACTIVE,
470 ui::IDLE_STATE_ACTIVE,
471 ui::IDLE_STATE_IDLE,
472 ui::IDLE_STATE_IDLE,
473 ui::IDLE_STATE_ACTIVE
475 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
476 status_collector_->Simulate(test_states,
477 sizeof(test_states) / sizeof(ui::IdleState));
478 GetStatus();
479 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
482 TEST_F(DeviceStatusCollectorTest, StateKeptInPref) {
483 ui::IdleState test_states[] = {
484 ui::IDLE_STATE_ACTIVE,
485 ui::IDLE_STATE_IDLE,
486 ui::IDLE_STATE_ACTIVE,
487 ui::IDLE_STATE_ACTIVE,
488 ui::IDLE_STATE_IDLE,
489 ui::IDLE_STATE_IDLE
491 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
492 status_collector_->Simulate(test_states,
493 sizeof(test_states) / sizeof(ui::IdleState));
495 // Process the list a second time after restarting the collector. It should be
496 // able to count the active periods found by the original collector, because
497 // the results are stored in a pref.
498 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo),
499 base::Bind(&GetEmptyCPUStatistics),
500 base::Bind(&GetEmptyCPUTempInfo));
501 status_collector_->Simulate(test_states,
502 sizeof(test_states) / sizeof(ui::IdleState));
504 GetStatus();
505 EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
508 TEST_F(DeviceStatusCollectorTest, Times) {
509 ui::IdleState test_states[] = {
510 ui::IDLE_STATE_ACTIVE,
511 ui::IDLE_STATE_IDLE,
512 ui::IDLE_STATE_ACTIVE,
513 ui::IDLE_STATE_ACTIVE,
514 ui::IDLE_STATE_IDLE,
515 ui::IDLE_STATE_IDLE
517 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
518 status_collector_->Simulate(test_states,
519 sizeof(test_states) / sizeof(ui::IdleState));
520 GetStatus();
521 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
524 TEST_F(DeviceStatusCollectorTest, MaxStoredPeriods) {
525 ui::IdleState test_states[] = {
526 ui::IDLE_STATE_ACTIVE,
527 ui::IDLE_STATE_IDLE
529 const int kMaxDays = 10;
531 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
532 status_collector_->set_max_stored_past_activity_days(kMaxDays - 1);
533 status_collector_->set_max_stored_future_activity_days(1);
534 Time baseline = Time::Now().LocalMidnight();
536 // Simulate 12 active periods.
537 for (int i = 0; i < kMaxDays + 2; i++) {
538 status_collector_->Simulate(test_states,
539 sizeof(test_states) / sizeof(ui::IdleState));
540 // Advance the simulated clock by a day.
541 baseline += TimeDelta::FromDays(1);
542 status_collector_->SetBaselineTime(baseline);
545 // Check that we don't exceed the max number of periods.
546 GetStatus();
547 EXPECT_EQ(kMaxDays - 1, status_.active_period_size());
549 // Simulate some future times.
550 for (int i = 0; i < kMaxDays + 2; i++) {
551 status_collector_->Simulate(test_states,
552 sizeof(test_states) / sizeof(ui::IdleState));
553 // Advance the simulated clock by a day.
554 baseline += TimeDelta::FromDays(1);
555 status_collector_->SetBaselineTime(baseline);
557 // Set the clock back so the previous simulated times are in the future.
558 baseline -= TimeDelta::FromDays(20);
559 status_collector_->SetBaselineTime(baseline);
561 // Collect one more data point to trigger pruning.
562 status_collector_->Simulate(test_states, 1);
564 // Check that we don't exceed the max number of periods.
565 status_.clear_active_period();
566 GetStatus();
567 EXPECT_LT(status_.active_period_size(), kMaxDays);
570 TEST_F(DeviceStatusCollectorTest, ActivityTimesEnabledByDefault) {
571 // Device activity times should be reported by default.
572 ui::IdleState test_states[] = {
573 ui::IDLE_STATE_ACTIVE,
574 ui::IDLE_STATE_ACTIVE,
575 ui::IDLE_STATE_ACTIVE
577 status_collector_->Simulate(test_states,
578 sizeof(test_states) / sizeof(ui::IdleState));
579 GetStatus();
580 EXPECT_EQ(1, status_.active_period_size());
581 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
584 TEST_F(DeviceStatusCollectorTest, ActivityTimesOff) {
585 // Device activity times should not be reported if explicitly disabled.
586 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, false);
588 ui::IdleState test_states[] = {
589 ui::IDLE_STATE_ACTIVE,
590 ui::IDLE_STATE_ACTIVE,
591 ui::IDLE_STATE_ACTIVE
593 status_collector_->Simulate(test_states,
594 sizeof(test_states) / sizeof(ui::IdleState));
595 GetStatus();
596 EXPECT_EQ(0, status_.active_period_size());
597 EXPECT_EQ(0, GetActiveMilliseconds(status_));
600 TEST_F(DeviceStatusCollectorTest, ActivityCrossingMidnight) {
601 ui::IdleState test_states[] = {
602 ui::IDLE_STATE_ACTIVE
604 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
606 // Set the baseline time to 10 seconds after midnight.
607 status_collector_->SetBaselineTime(
608 Time::Now().LocalMidnight() + TimeDelta::FromSeconds(10));
610 status_collector_->Simulate(test_states, 1);
611 GetStatus();
612 ASSERT_EQ(2, status_.active_period_size());
614 em::ActiveTimePeriod period0 = status_.active_period(0);
615 em::ActiveTimePeriod period1 = status_.active_period(1);
616 EXPECT_EQ(ActivePeriodMilliseconds() - 10000, period0.active_duration());
617 EXPECT_EQ(10000, period1.active_duration());
619 em::TimePeriod time_period0 = period0.time_period();
620 em::TimePeriod time_period1 = period1.time_period();
622 EXPECT_EQ(time_period0.end_timestamp(), time_period1.start_timestamp());
624 // Ensure that the start and end times for the period are a day apart.
625 EXPECT_EQ(time_period0.end_timestamp() - time_period0.start_timestamp(),
626 kMillisecondsPerDay);
627 EXPECT_EQ(time_period1.end_timestamp() - time_period1.start_timestamp(),
628 kMillisecondsPerDay);
631 TEST_F(DeviceStatusCollectorTest, ActivityTimesKeptUntilSubmittedSuccessfully) {
632 ui::IdleState test_states[] = {
633 ui::IDLE_STATE_ACTIVE,
634 ui::IDLE_STATE_ACTIVE,
636 settings_helper_.SetBoolean(chromeos::kReportDeviceActivityTimes, true);
638 status_collector_->Simulate(test_states, 2);
639 GetStatus();
640 EXPECT_EQ(2 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
641 em::DeviceStatusReportRequest first_status(status_);
643 // The collector returns the same status again.
644 GetStatus();
645 EXPECT_EQ(first_status.SerializeAsString(), status_.SerializeAsString());
647 // After indicating a successful submit, the submitted status gets cleared,
648 // but what got collected meanwhile sticks around.
649 status_collector_->Simulate(test_states, 1);
650 status_collector_->OnSubmittedSuccessfully();
651 GetStatus();
652 EXPECT_EQ(ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
655 TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) {
656 // Test that boot mode data is reported by default.
657 fake_statistics_provider_.SetMachineStatistic(
658 chromeos::system::kDevSwitchBootKey,
659 chromeos::system::kDevSwitchBootValueVerified);
660 GetStatus();
661 EXPECT_EQ("Verified", status_.boot_mode());
663 // Test that boot mode data is not reported if the pref turned off.
664 settings_helper_.SetBoolean(chromeos::kReportDeviceBootMode, false);
666 GetStatus();
667 EXPECT_FALSE(status_.has_boot_mode());
669 // Turn the pref on, and check that the status is reported iff the
670 // statistics provider returns valid data.
671 settings_helper_.SetBoolean(chromeos::kReportDeviceBootMode, true);
673 fake_statistics_provider_.SetMachineStatistic(
674 chromeos::system::kDevSwitchBootKey, "(error)");
675 GetStatus();
676 EXPECT_FALSE(status_.has_boot_mode());
678 fake_statistics_provider_.SetMachineStatistic(
679 chromeos::system::kDevSwitchBootKey, " ");
680 GetStatus();
681 EXPECT_FALSE(status_.has_boot_mode());
683 fake_statistics_provider_.SetMachineStatistic(
684 chromeos::system::kDevSwitchBootKey,
685 chromeos::system::kDevSwitchBootValueVerified);
686 GetStatus();
687 EXPECT_EQ("Verified", status_.boot_mode());
689 fake_statistics_provider_.SetMachineStatistic(
690 chromeos::system::kDevSwitchBootKey,
691 chromeos::system::kDevSwitchBootValueDev);
692 GetStatus();
693 EXPECT_EQ("Dev", status_.boot_mode());
696 TEST_F(DeviceStatusCollectorTest, VersionInfo) {
697 // Expect the version info to be reported by default.
698 GetStatus();
699 EXPECT_TRUE(status_.has_browser_version());
700 EXPECT_TRUE(status_.has_os_version());
701 EXPECT_TRUE(status_.has_firmware_version());
703 // When the pref to collect this data is not enabled, expect that none of
704 // the fields are present in the protobuf.
705 settings_helper_.SetBoolean(chromeos::kReportDeviceVersionInfo, false);
706 GetStatus();
707 EXPECT_FALSE(status_.has_browser_version());
708 EXPECT_FALSE(status_.has_os_version());
709 EXPECT_FALSE(status_.has_firmware_version());
711 settings_helper_.SetBoolean(chromeos::kReportDeviceVersionInfo, true);
712 GetStatus();
713 EXPECT_TRUE(status_.has_browser_version());
714 EXPECT_TRUE(status_.has_os_version());
715 EXPECT_TRUE(status_.has_firmware_version());
717 // Check that the browser version is not empty. OS version & firmware
718 // don't have any reasonable values inside the unit test, so those
719 // aren't checked.
720 EXPECT_NE("", status_.browser_version());
723 TEST_F(DeviceStatusCollectorTest, Location) {
724 content::Geoposition valid_fix;
725 valid_fix.latitude = 4.3;
726 valid_fix.longitude = -7.8;
727 valid_fix.accuracy = 3.;
728 valid_fix.timestamp = Time::Now();
730 content::Geoposition invalid_fix;
731 invalid_fix.error_code =
732 content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
733 invalid_fix.timestamp = Time::Now();
735 // Check that when device location reporting is disabled, no location is
736 // reported.
737 SetMockPositionToReturnNext(valid_fix);
738 CheckThatNoLocationIsReported();
740 // Check that when device location reporting is enabled and a valid fix is
741 // available, the location is reported and is stored in local state.
742 SetMockPositionToReturnNext(valid_fix);
743 settings_helper_.SetBoolean(chromeos::kReportDeviceLocation, true);
744 EXPECT_FALSE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
745 CheckThatAValidLocationIsReported();
747 // Restart the status collector. Check that the last known location has been
748 // retrieved from local state without requesting a geolocation update.
749 SetMockPositionToReturnNext(valid_fix);
750 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo),
751 base::Bind(&GetEmptyCPUStatistics),
752 base::Bind(&GetEmptyCPUTempInfo));
753 CheckThatAValidLocationIsReported();
754 EXPECT_TRUE(mock_position_to_return_next.get());
756 // Check that after disabling location reporting again, the last known
757 // location has been cleared from local state and is no longer reported.
758 SetMockPositionToReturnNext(valid_fix);
759 settings_helper_.SetBoolean(chromeos::kReportDeviceLocation, false);
760 // Allow the new pref to propagate to the status collector.
761 message_loop_.RunUntilIdle();
762 EXPECT_TRUE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
763 CheckThatNoLocationIsReported();
765 // Check that after enabling location reporting again, an error is reported
766 // if no valid fix is available.
767 SetMockPositionToReturnNext(invalid_fix);
768 settings_helper_.SetBoolean(chromeos::kReportDeviceLocation, true);
769 // Allow the new pref to propagate to the status collector.
770 message_loop_.RunUntilIdle();
771 CheckThatALocationErrorIsReported();
774 TEST_F(DeviceStatusCollectorTest, ReportUsers) {
775 user_manager_->CreatePublicAccountUser("public@localhost");
776 user_manager_->AddUserWithAffiliation("user0@managed.com", true);
777 user_manager_->AddUserWithAffiliation("user1@managed.com", true);
778 user_manager_->AddUserWithAffiliation("user2@managed.com", true);
779 user_manager_->AddUserWithAffiliation("user3@unmanaged.com", false);
780 user_manager_->AddUserWithAffiliation("user4@managed.com", true);
781 user_manager_->AddUserWithAffiliation("user5@managed.com", true);
783 // Verify that users are reported by default.
784 GetStatus();
785 EXPECT_EQ(6, status_.user_size());
787 // Verify that users are reported after enabling the setting.
788 settings_helper_.SetBoolean(chromeos::kReportDeviceUsers, true);
789 GetStatus();
790 EXPECT_EQ(6, status_.user_size());
791 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(0).type());
792 EXPECT_EQ("user0@managed.com", status_.user(0).email());
793 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(1).type());
794 EXPECT_EQ("user1@managed.com", status_.user(1).email());
795 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(2).type());
796 EXPECT_EQ("user2@managed.com", status_.user(2).email());
797 EXPECT_EQ(em::DeviceUser::USER_TYPE_UNMANAGED, status_.user(3).type());
798 EXPECT_FALSE(status_.user(3).has_email());
799 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(4).type());
800 EXPECT_EQ("user4@managed.com", status_.user(4).email());
801 EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(5).type());
802 EXPECT_EQ("user5@managed.com", status_.user(5).email());
804 // Verify that users are no longer reported if setting is disabled.
805 settings_helper_.SetBoolean(chromeos::kReportDeviceUsers, false);
806 GetStatus();
807 EXPECT_EQ(0, status_.user_size());
810 TEST_F(DeviceStatusCollectorTest, TestVolumeInfo) {
811 std::vector<std::string> expected_mount_points;
812 std::vector<em::VolumeInfo> expected_volume_info;
813 int size = 12345678;
814 for (const auto& mount_info :
815 DiskMountManager::GetInstance()->mount_points()) {
816 expected_mount_points.push_back(mount_info.first);
818 expected_mount_points.push_back(kExternalMountPoint);
820 for (const std::string& mount_point : expected_mount_points) {
821 em::VolumeInfo info;
822 info.set_volume_id(mount_point);
823 // Just put unique numbers in for storage_total/free.
824 info.set_storage_total(size++);
825 info.set_storage_free(size++);
826 expected_volume_info.push_back(info);
828 EXPECT_FALSE(expected_volume_info.empty());
830 RestartStatusCollector(base::Bind(&GetFakeVolumeInfo, expected_volume_info),
831 base::Bind(&GetEmptyCPUStatistics),
832 base::Bind(&GetEmptyCPUTempInfo));
833 // Force finishing tasks posted by ctor of DeviceStatusCollector.
834 content::BrowserThread::GetBlockingPool()->FlushForTesting();
835 message_loop_.RunUntilIdle();
837 GetStatus();
838 EXPECT_EQ(expected_mount_points.size(),
839 static_cast<size_t>(status_.volume_info_size()));
841 // Walk the returned VolumeInfo to make sure it matches.
842 for (const em::VolumeInfo& expected_info : expected_volume_info) {
843 bool found = false;
844 for (const em::VolumeInfo& info : status_.volume_info()) {
845 if (info.volume_id() == expected_info.volume_id()) {
846 EXPECT_EQ(expected_info.storage_total(), info.storage_total());
847 EXPECT_EQ(expected_info.storage_free(), info.storage_free());
848 found = true;
849 break;
852 EXPECT_TRUE(found) << "No matching VolumeInfo for "
853 << expected_info.volume_id();
856 // Now turn off hardware status reporting - should have no data.
857 settings_helper_.SetBoolean(chromeos::kReportDeviceHardwareStatus, false);
858 GetStatus();
859 EXPECT_EQ(0, status_.volume_info_size());
862 TEST_F(DeviceStatusCollectorTest, TestAvailableMemory) {
863 // Refresh our samples. Sample more than kMaxHardwareSamples times to
864 // make sure that the code correctly caps the number of cached samples.
865 for (int i = 0; i < static_cast<int>(
866 DeviceStatusCollector::kMaxResourceUsageSamples + 1);
867 ++i) {
868 status_collector_->RefreshSampleResourceUsage();
869 message_loop_.RunUntilIdle();
871 GetStatus();
872 EXPECT_EQ(static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples),
873 status_.system_ram_free().size());
874 EXPECT_TRUE(status_.has_system_ram_total());
875 // No good way to inject specific test values for available system RAM, so
876 // just make sure it's > 0.
877 EXPECT_GT(status_.system_ram_total(), 0);
880 TEST_F(DeviceStatusCollectorTest, TestCPUSamples) {
881 // Mock 100% CPU usage.
882 std::string full_cpu_usage("cpu 500 0 500 0 0 0 0");
883 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo),
884 base::Bind(&GetFakeCPUStatistics, full_cpu_usage),
885 base::Bind(&GetEmptyCPUTempInfo));
886 // Force finishing tasks posted by ctor of DeviceStatusCollector.
887 content::BrowserThread::GetBlockingPool()->FlushForTesting();
888 message_loop_.RunUntilIdle();
889 GetStatus();
890 ASSERT_EQ(1, status_.cpu_utilization_pct().size());
891 EXPECT_EQ(100, status_.cpu_utilization_pct(0));
893 // Now sample CPU usage again (active usage counters will not increase
894 // so should show 0% cpu usage).
895 status_collector_->RefreshSampleResourceUsage();
896 message_loop_.RunUntilIdle();
897 GetStatus();
898 ASSERT_EQ(2, status_.cpu_utilization_pct().size());
899 EXPECT_EQ(0, status_.cpu_utilization_pct(1));
901 // Now store a bunch of 0% cpu usage and make sure we cap the max number of
902 // samples.
903 for (int i = 0;
904 i < static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples);
905 ++i) {
906 status_collector_->RefreshSampleResourceUsage();
907 message_loop_.RunUntilIdle();
909 GetStatus();
911 // Should not be more than kMaxResourceUsageSamples, and they should all show
912 // the CPU is idle.
913 EXPECT_EQ(static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples),
914 status_.cpu_utilization_pct().size());
915 for (const auto utilization : status_.cpu_utilization_pct())
916 EXPECT_EQ(0, utilization);
918 // Turning off hardware reporting should not report CPU utilization.
919 settings_helper_.SetBoolean(chromeos::kReportDeviceHardwareStatus, false);
920 GetStatus();
921 EXPECT_EQ(0, status_.cpu_utilization_pct().size());
924 TEST_F(DeviceStatusCollectorTest, TestCPUTemp) {
925 std::vector<em::CPUTempInfo> expected_temp_info;
926 int cpu_cnt = 12;
927 for (int i = 0; i < cpu_cnt; ++i) {
928 em::CPUTempInfo info;
929 info.set_cpu_temp(i * 10 + 100);
930 info.set_cpu_label(base::StringPrintf("Core %d", i));
931 expected_temp_info.push_back(info);
934 RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo),
935 base::Bind(&GetEmptyCPUStatistics),
936 base::Bind(&GetFakeCPUTempInfo, expected_temp_info));
937 // Force finishing tasks posted by ctor of DeviceStatusCollector.
938 content::BrowserThread::GetBlockingPool()->FlushForTesting();
939 message_loop_.RunUntilIdle();
941 GetStatus();
942 EXPECT_EQ(expected_temp_info.size(),
943 static_cast<size_t>(status_.cpu_temp_info_size()));
945 // Walk the returned CPUTempInfo to make sure it matches.
946 for (const em::CPUTempInfo& expected_info : expected_temp_info) {
947 bool found = false;
948 for (const em::CPUTempInfo& info : status_.cpu_temp_info()) {
949 if (info.cpu_label() == expected_info.cpu_label()) {
950 EXPECT_EQ(expected_info.cpu_temp(), info.cpu_temp());
951 found = true;
952 break;
955 EXPECT_TRUE(found) << "No matching CPUTempInfo for "
956 << expected_info.cpu_label();
959 // Now turn off hardware status reporting - should have no data.
960 settings_helper_.SetBoolean(chromeos::kReportDeviceHardwareStatus, false);
961 GetStatus();
962 EXPECT_EQ(0, status_.cpu_temp_info_size());
965 TEST_F(DeviceStatusCollectorTest, NoSessionStatusIfNotKioskMode) {
966 // Should not report session status if we don't have an active kiosk app.
967 settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, true);
968 em::SessionStatusReportRequest session_status;
969 EXPECT_FALSE(status_collector_->GetDeviceSessionStatus(&session_status));
972 TEST_F(DeviceStatusCollectorTest, NoSessionStatusIfSessionReportingDisabled) {
973 // Should not report session status if session status reporting is disabled.
974 settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, false);
975 status_collector_->set_kiosk_account(make_scoped_ptr(
976 new policy::DeviceLocalAccount(fake_device_local_account_)).Pass());
977 // Set up a device-local account for single-app kiosk mode.
978 MockRunningKioskApp(fake_device_local_account_);
980 em::SessionStatusReportRequest session_status;
981 EXPECT_FALSE(status_collector_->GetDeviceSessionStatus(&session_status));
984 TEST_F(DeviceStatusCollectorTest, ReportSessionStatus) {
985 settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, true);
986 status_collector_->set_kiosk_account(make_scoped_ptr(
987 new policy::DeviceLocalAccount(fake_device_local_account_)).Pass());
989 // Set up a device-local account for single-app kiosk mode.
990 MockRunningKioskApp(fake_device_local_account_);
992 em::SessionStatusReportRequest session_status;
993 EXPECT_TRUE(status_collector_->GetDeviceSessionStatus(&session_status));
994 ASSERT_EQ(1, session_status.installed_apps_size());
995 EXPECT_EQ(kKioskAccountId, session_status.device_local_account_id());
996 const em::AppStatus app = session_status.installed_apps(0);
997 EXPECT_EQ(kKioskAppId, app.app_id());
998 // Test code just sets the version to the app ID.
999 EXPECT_EQ(kKioskAppId, app.extension_version());
1000 EXPECT_FALSE(app.has_status());
1001 EXPECT_FALSE(app.has_error());
1004 // Fake device state.
1005 struct FakeDeviceData {
1006 const char* device_path;
1007 const char* type;
1008 const char* object_path;
1009 const char* mac_address;
1010 const char* meid;
1011 const char* imei;
1012 int expected_type; // proto enum type value, -1 for not present.
1015 static const FakeDeviceData kFakeDevices[] = {
1016 { "/device/ethernet", shill::kTypeEthernet, "ethernet",
1017 "112233445566", "", "",
1018 em::NetworkInterface::TYPE_ETHERNET },
1019 { "/device/cellular1", shill::kTypeCellular, "cellular1",
1020 "abcdefabcdef", "A10000009296F2", "",
1021 em::NetworkInterface::TYPE_CELLULAR },
1022 { "/device/cellular2", shill::kTypeCellular, "cellular2",
1023 "abcdefabcdef", "", "352099001761481",
1024 em::NetworkInterface::TYPE_CELLULAR },
1025 { "/device/wifi", shill::kTypeWifi, "wifi",
1026 "aabbccddeeff", "", "",
1027 em::NetworkInterface::TYPE_WIFI },
1028 { "/device/bluetooth", shill::kTypeBluetooth, "bluetooth",
1029 "", "", "",
1030 em::NetworkInterface::TYPE_BLUETOOTH },
1031 { "/device/vpn", shill::kTypeVPN, "vpn",
1032 "", "", "",
1033 -1 },
1036 // Fake network state.
1037 struct FakeNetworkState {
1038 const char* name;
1039 const char* device_path;
1040 const char* type;
1041 int signal_strength;
1042 int expected_signal_strength;
1043 const char* connection_status;
1044 int expected_state;
1045 const char* address;
1046 const char* gateway;
1049 // List of fake networks - primarily used to make sure that signal strength
1050 // and connection state are properly populated in status reports. Note that
1051 // by convention shill will not report a signal strength of 0 for a visible
1052 // network, so we use 1 below.
1053 static const FakeNetworkState kFakeNetworks[] = {
1054 { "offline", "/device/wifi", shill::kTypeWifi, 35, -85,
1055 shill::kStateOffline, em::NetworkState::OFFLINE, "", "" },
1056 { "ethernet", "/device/ethernet", shill::kTypeEthernet, 0, 0,
1057 shill::kStateOnline, em::NetworkState::ONLINE,
1058 "192.168.0.1", "8.8.8.8" },
1059 { "wifi", "/device/wifi", shill::kTypeWifi, 23, -97, shill::kStatePortal,
1060 em::NetworkState::PORTAL, "", "" },
1061 { "idle", "/device/cellular1", shill::kTypeCellular, 0, 0, shill::kStateIdle,
1062 em::NetworkState::IDLE, "", "" },
1063 { "carrier", "/device/cellular1", shill::kTypeCellular, 0, 0,
1064 shill::kStateCarrier, em::NetworkState::CARRIER, "", "" },
1065 { "association", "/device/cellular1", shill::kTypeCellular, 0, 0,
1066 shill::kStateAssociation, em::NetworkState::ASSOCIATION, "", "" },
1067 { "config", "/device/cellular1", shill::kTypeCellular, 0, 0,
1068 shill::kStateConfiguration, em::NetworkState::CONFIGURATION, "", "" },
1069 // Set signal strength for this network to -20, but expected strength to 0
1070 // to test that we only report signal_strength for wifi connections.
1071 { "ready", "/device/cellular1", shill::kTypeCellular, -20, 0,
1072 shill::kStateReady, em::NetworkState::READY, "", "" },
1073 { "disconnect", "/device/wifi", shill::kTypeWifi, 1, -119,
1074 shill::kStateDisconnect, em::NetworkState::DISCONNECT, "", "" },
1075 { "failure", "/device/wifi", shill::kTypeWifi, 1, -119, shill::kStateFailure,
1076 em::NetworkState::FAILURE, "", "" },
1077 { "activation-failure", "/device/cellular1", shill::kTypeCellular, 0, 0,
1078 shill::kStateActivationFailure, em::NetworkState::ACTIVATION_FAILURE,
1079 "", "" },
1080 { "unknown", "", shill::kTypeWifi, 1, -119, "unknown",
1081 em::NetworkState::UNKNOWN, "", "" },
1084 static const FakeNetworkState kUnconfiguredNetwork = {
1085 "unconfigured", "/device/unconfigured", shill::kTypeWifi, 35, -85,
1086 shill::kStateOffline, em::NetworkState::OFFLINE, "", ""
1089 class DeviceStatusCollectorNetworkInterfacesTest
1090 : public DeviceStatusCollectorTest {
1091 protected:
1092 void SetUp() override {
1093 chromeos::DBusThreadManager::Initialize();
1094 chromeos::NetworkHandler::Initialize();
1095 chromeos::ShillDeviceClient::TestInterface* test_device_client =
1096 chromeos::DBusThreadManager::Get()->GetShillDeviceClient()->
1097 GetTestInterface();
1098 test_device_client->ClearDevices();
1099 for (size_t i = 0; i < arraysize(kFakeDevices); ++i) {
1100 const FakeDeviceData& dev = kFakeDevices[i];
1101 test_device_client->AddDevice(dev.device_path, dev.type,
1102 dev.object_path);
1103 if (*dev.mac_address) {
1104 test_device_client->SetDeviceProperty(
1105 dev.device_path, shill::kAddressProperty,
1106 base::StringValue(dev.mac_address));
1108 if (*dev.meid) {
1109 test_device_client->SetDeviceProperty(
1110 dev.device_path, shill::kMeidProperty,
1111 base::StringValue(dev.meid));
1113 if (*dev.imei) {
1114 test_device_client->SetDeviceProperty(
1115 dev.device_path, shill::kImeiProperty,
1116 base::StringValue(dev.imei));
1120 chromeos::ShillServiceClient::TestInterface* service_client =
1121 chromeos::DBusThreadManager::Get()->GetShillServiceClient()->
1122 GetTestInterface();
1123 service_client->ClearServices();
1125 // Now add services for every fake network.
1126 for (const FakeNetworkState& fake_network : kFakeNetworks) {
1127 // Shill forces non-visible networks to report a disconnected state.
1128 bool is_visible =
1129 fake_network.connection_status != shill::kStateDisconnect;
1130 service_client->AddService(
1131 fake_network.name, /* service_path */
1132 fake_network.name /* guid */,
1133 fake_network.name /* name */,
1134 fake_network.type /* type */,
1135 fake_network.connection_status,
1136 is_visible);
1137 service_client->SetServiceProperty(
1138 fake_network.name, shill::kSignalStrengthProperty,
1139 base::FundamentalValue(fake_network.signal_strength));
1140 service_client->SetServiceProperty(
1141 fake_network.name, shill::kDeviceProperty,
1142 base::StringValue(fake_network.device_path));
1143 // Set the profile so this shows up as a configured network.
1144 service_client->SetServiceProperty(
1145 fake_network.name, shill::kProfileProperty,
1146 base::StringValue(fake_network.name));
1147 if (strlen(fake_network.address) > 0) {
1148 // Set the IP config.
1149 base::DictionaryValue ip_config_properties;
1150 ip_config_properties.SetStringWithoutPathExpansion(
1151 shill::kAddressProperty, fake_network.address);
1152 ip_config_properties.SetStringWithoutPathExpansion(
1153 shill::kGatewayProperty, fake_network.gateway);
1154 chromeos::ShillIPConfigClient::TestInterface* ip_config_test =
1155 chromeos::DBusThreadManager::Get()->GetShillIPConfigClient()->
1156 GetTestInterface();
1157 const std::string kIPConfigPath = "test_ip_config";
1158 ip_config_test->AddIPConfig(kIPConfigPath, ip_config_properties);
1159 service_client->SetServiceProperty(
1160 fake_network.name, shill::kIPConfigProperty,
1161 base::StringValue(kIPConfigPath));
1165 // Now add an unconfigured network - it should not show up in the
1166 // reported list of networks because it doesn't have a profile specified.
1167 service_client->AddService(
1168 kUnconfiguredNetwork.name, /* service_path */
1169 kUnconfiguredNetwork.name /* guid */,
1170 kUnconfiguredNetwork.name /* name */,
1171 kUnconfiguredNetwork.type /* type */,
1172 kUnconfiguredNetwork.connection_status,
1173 true /* visible */);
1174 service_client->SetServiceProperty(
1175 kUnconfiguredNetwork.name, shill::kSignalStrengthProperty,
1176 base::FundamentalValue(kUnconfiguredNetwork.signal_strength));
1177 service_client->SetServiceProperty(
1178 kUnconfiguredNetwork.name, shill::kDeviceProperty,
1179 base::StringValue(kUnconfiguredNetwork.device_path));
1181 // Flush out pending state updates.
1182 base::RunLoop().RunUntilIdle();
1184 chromeos::NetworkStateHandler::NetworkStateList state_list;
1185 chromeos::NetworkStateHandler* network_state_handler =
1186 chromeos::NetworkHandler::Get()->network_state_handler();
1187 network_state_handler->GetNetworkListByType(
1188 chromeos::NetworkTypePattern::Default(),
1189 true, // configured_only
1190 false, // visible_only,
1191 0, // no limit to number of results
1192 &state_list);
1193 ASSERT_EQ(arraysize(kFakeNetworks), state_list.size());
1196 void TearDown() override {
1197 chromeos::NetworkHandler::Shutdown();
1198 chromeos::DBusThreadManager::Shutdown();
1201 void VerifyNetworkReporting() {
1202 int count = 0;
1203 for (size_t i = 0; i < arraysize(kFakeDevices); ++i) {
1204 const FakeDeviceData& dev = kFakeDevices[i];
1205 if (dev.expected_type == -1)
1206 continue;
1208 // Find the corresponding entry in reporting data.
1209 bool found_match = false;
1210 google::protobuf::RepeatedPtrField<em::NetworkInterface>::const_iterator
1211 iface;
1212 for (iface = status_.network_interface().begin();
1213 iface != status_.network_interface().end(); ++iface) {
1214 // Check whether type, field presence and field values match.
1215 if (dev.expected_type == iface->type() &&
1216 iface->has_mac_address() == !!*dev.mac_address &&
1217 iface->has_meid() == !!*dev.meid &&
1218 iface->has_imei() == !!*dev.imei &&
1219 iface->mac_address() == dev.mac_address &&
1220 iface->meid() == dev.meid && iface->imei() == dev.imei &&
1221 iface->device_path() == dev.device_path) {
1222 found_match = true;
1223 break;
1227 EXPECT_TRUE(found_match) << "No matching interface for fake device " << i;
1228 count++;
1231 EXPECT_EQ(count, status_.network_interface_size());
1233 // Now make sure network state list is correct.
1234 EXPECT_EQ(arraysize(kFakeNetworks),
1235 static_cast<size_t>(status_.network_state_size()));
1236 for (const FakeNetworkState& state : kFakeNetworks) {
1237 bool found_match = false;
1238 for (const em::NetworkState& proto_state : status_.network_state()) {
1239 // Make sure every item has a matching entry in the proto.
1240 bool should_have_signal_strength = state.expected_signal_strength != 0;
1241 if (proto_state.has_device_path() == (strlen(state.device_path) > 0) &&
1242 proto_state.has_signal_strength() == should_have_signal_strength &&
1243 proto_state.signal_strength() == state.expected_signal_strength &&
1244 proto_state.connection_state() == state.expected_state) {
1245 if (proto_state.has_ip_address())
1246 EXPECT_EQ(proto_state.ip_address(), state.address);
1247 else
1248 EXPECT_EQ(0U, strlen(state.address));
1249 if (proto_state.has_gateway())
1250 EXPECT_EQ(proto_state.gateway(), state.gateway);
1251 else
1252 EXPECT_EQ(0U, strlen(state.gateway));
1253 found_match = true;
1254 break;
1257 EXPECT_TRUE(found_match) << "No matching state for fake network "
1258 << " (" << state.name << ")";
1263 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, NoNetworkStateIfNotKiosk) {
1264 // If not in an active kiosk session, there should be network interfaces
1265 // reported, but no network state.
1266 GetStatus();
1267 EXPECT_LT(0, status_.network_interface_size());
1268 EXPECT_EQ(0, status_.network_state_size());
1271 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, NetworkInterfaces) {
1272 // Mock that we are in kiosk mode so we report network state.
1273 status_collector_->set_kiosk_account(make_scoped_ptr(
1274 new policy::DeviceLocalAccount(fake_device_local_account_)).Pass());
1276 // Interfaces should be reported by default.
1277 GetStatus();
1278 EXPECT_LT(0, status_.network_interface_size());
1279 EXPECT_LT(0, status_.network_state_size());
1281 // No interfaces should be reported if the policy is off.
1282 settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces, false);
1283 GetStatus();
1284 EXPECT_EQ(0, status_.network_interface_size());
1285 EXPECT_EQ(0, status_.network_state_size());
1287 // Switch the policy on and verify the interface list is present.
1288 settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces, true);
1289 GetStatus();
1291 VerifyNetworkReporting();
1294 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, ReportIfPublicSession) {
1295 // Report netowork state for public accounts.
1296 user_manager_->CreatePublicAccountUser(kPublicAccountId);
1297 EXPECT_CALL(*user_manager_, IsLoggedInAsPublicAccount())
1298 .WillRepeatedly(Return(true));
1300 settings_helper_.SetBoolean(chromeos::kReportDeviceNetworkInterfaces, true);
1301 GetStatus();
1302 VerifyNetworkReporting();
1305 } // namespace policy