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

Unified Diff: chrome/browser/policy/device_status_collector_unittest.cc

Issue 10103029: Add device location reporting (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Nits addressed. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/policy/device_status_collector_unittest.cc
diff --git a/chrome/browser/policy/device_status_collector_unittest.cc b/chrome/browser/policy/device_status_collector_unittest.cc
index 3dcfb3f01b1c5a36e3eba86955cddc2dac195cac..ca4ff99dfd102782af6ae14be4d158db9455a2aa 100644
--- a/chrome/browser/policy/device_status_collector_unittest.cc
+++ b/chrome/browser/policy/device_status_collector_unittest.cc
@@ -4,21 +4,29 @@
#include "chrome/browser/policy/device_status_collector.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
-#include "base/time.h"
-#include "chrome/browser/idle.h"
#include "chrome/browser/chromeos/cros_settings.h"
#include "chrome/browser/chromeos/cros_settings_names.h"
#include "chrome/browser/chromeos/cros_settings_provider.h"
#include "chrome/browser/chromeos/stub_cros_settings_provider.h"
#include "chrome/browser/chromeos/system/mock_statistics_provider.h"
+#include "chrome/browser/chromeos/system/statistics_provider.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_pref_service.h"
+#include "content/public/browser/browser_thread.h"
#include "content/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::NotNull;
+using ::testing::Return;
+using ::testing::SetArgPointee;
using base::TimeDelta;
using base::Time;
@@ -28,13 +36,36 @@ namespace {
const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
+scoped_ptr<content::Geoposition> mock_position_to_return_next;
+
+void SetMockPositionToReturnNext(const content::Geoposition &position) {
+ mock_position_to_return_next.reset(new content::Geoposition(position));
+}
+
+void MockPositionUpdateRequester(
+ const content::GeolocationUpdateCallback& callback) {
+ if (!mock_position_to_return_next.get())
+ return;
+
+ // If the fix is invalid, the DeviceStatusCollector will immediately request
+ // another update when it receives the callback. This is desirable and safe in
+ // real life where geolocation updates arrive asynchronously. In this testing
+ // harness, the callback is invoked synchronously upon request, leading to a
+ // request-callback loop. The loop is broken by returning the mock position
+ // only once.
+ scoped_ptr<content::Geoposition> position(
+ mock_position_to_return_next.release());
+ callback.Run(*position);
+}
+
class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
public:
TestingDeviceStatusCollector(
PrefService* local_state,
chromeos::system::StatisticsProvider* provider)
- : policy::DeviceStatusCollector(local_state, provider),
- local_state_(local_state) {
+ : policy::DeviceStatusCollector(local_state,
+ provider,
+ &MockPositionUpdateRequester) {
// Set the baseline time to a fixed value (1 AM) to prevent test flakiness
// due to a single activity period spanning two days.
SetBaselineTime(Time::Now().LocalMidnight() + TimeDelta::FromHours(1));
@@ -68,14 +99,12 @@ class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
// Each time this is called, returns a time that is a fixed increment
// later than the previous time.
virtual Time GetCurrentTime() OVERRIDE {
- int poll_interval = policy::DeviceStatusCollector::kPollIntervalSeconds;
+ int poll_interval = policy::DeviceStatusCollector::kIdlePollIntervalSeconds;
return baseline_time_ +
TimeDelta::FromSeconds(poll_interval * baseline_offset_periods_++);
}
private:
- PrefService* local_state_;
-
// Baseline time for the fake times returned from GetCurrentTime().
Time baseline_time_;
@@ -97,32 +126,28 @@ int64 GetActiveMilliseconds(em::DeviceStatusReportRequest& status) {
namespace policy {
-using ::testing::_;
-using ::testing::NotNull;
-using ::testing::Return;
-using ::testing::SetArgPointee;
-
class DeviceStatusCollectorTest : public testing::Test {
public:
DeviceStatusCollectorTest()
: message_loop_(MessageLoop::TYPE_UI),
ui_thread_(content::BrowserThread::UI, &message_loop_),
file_thread_(content::BrowserThread::FILE, &message_loop_),
- status_collector_(&prefs_, &statistics_provider_) {
+ io_thread_(content::BrowserThread::IO, &message_loop_) {
+ TestingDeviceStatusCollector::RegisterPrefs(&prefs_);
- DeviceStatusCollector::RegisterPrefs(&prefs_);
EXPECT_CALL(statistics_provider_, GetMachineStatistic(_, NotNull()))
.WillRepeatedly(Return(false));
- cros_settings_ = chromeos::CrosSettings::Get();
-
// Remove the real DeviceSettingsProvider and replace it with a stub.
+ cros_settings_ = chromeos::CrosSettings::Get();
device_settings_provider_ =
cros_settings_->GetProvider(chromeos::kReportDeviceVersionInfo);
EXPECT_TRUE(device_settings_provider_ != NULL);
EXPECT_TRUE(
cros_settings_->RemoveSettingsProvider(device_settings_provider_));
cros_settings_->AddSettingsProvider(&stub_settings_provider_);
+
+ RestartStatusCollector();
}
~DeviceStatusCollectorTest() {
@@ -132,19 +157,69 @@ class DeviceStatusCollectorTest : public testing::Test {
cros_settings_->AddSettingsProvider(device_settings_provider_);
}
+ void RestartStatusCollector() {
+ status_collector_.reset(
+ new TestingDeviceStatusCollector(&prefs_, &statistics_provider_));
+ }
+
+ void GetStatus() {
+ status_.Clear();
+ status_collector_->GetStatus(&status_);
+ }
+
+ void CheckThatNoLocationIsReported() {
+ GetStatus();
+ EXPECT_FALSE(status_.has_device_location());
+ }
+
+ void CheckThatAValidLocationIsReported() {
+ // Checks that a location is being reported which matches the valid fix
+ // set using SetMockPositionToReturnNext().
+ GetStatus();
+ EXPECT_TRUE(status_.has_device_location());
+ em::DeviceLocation location = status_.device_location();
+ if (location.has_error_code())
+ EXPECT_EQ(em::DeviceLocation::ERROR_CODE_NONE, location.error_code());
+ EXPECT_TRUE(location.has_latitude());
+ EXPECT_TRUE(location.has_longitude());
+ EXPECT_TRUE(location.has_accuracy());
+ EXPECT_TRUE(location.has_timestamp());
+ EXPECT_FALSE(location.has_altitude());
+ EXPECT_FALSE(location.has_altitude_accuracy());
+ EXPECT_FALSE(location.has_heading());
+ EXPECT_FALSE(location.has_speed());
+ EXPECT_FALSE(location.has_error_message());
+ EXPECT_DOUBLE_EQ(4.3, location.latitude());
+ EXPECT_DOUBLE_EQ(-7.8, location.longitude());
+ EXPECT_DOUBLE_EQ(3., location.accuracy());
+ // Check that the timestamp is not older than ten minutes.
+ EXPECT_TRUE(Time::Now() - Time::FromDoubleT(location.timestamp() / 1000.) <
+ TimeDelta::FromMinutes(10));
+ }
+
+ void CheckThatALocationErrorIsReported() {
+ GetStatus();
+ EXPECT_TRUE(status_.has_device_location());
+ em::DeviceLocation location = status_.device_location();
+ EXPECT_TRUE(location.has_error_code());
+ EXPECT_EQ(em::DeviceLocation::ERROR_CODE_POSITION_UNAVAILABLE,
+ location.error_code());
+ }
+
protected:
// Convenience method.
int64 ActivePeriodMilliseconds() {
- return policy::DeviceStatusCollector::kPollIntervalSeconds * 1000;
+ return policy::DeviceStatusCollector::kIdlePollIntervalSeconds * 1000;
}
MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
content::TestBrowserThread file_thread_;
+ content::TestBrowserThread io_thread_;
TestingPrefService prefs_;
chromeos::system::MockStatisticsProvider statistics_provider_;
- TestingDeviceStatusCollector status_collector_;
+ scoped_ptr<TestingDeviceStatusCollector> status_collector_;
em::DeviceStatusReportRequest status_;
chromeos::CrosSettings* cros_settings_;
chromeos::CrosSettingsProvider* device_settings_provider_;
@@ -160,20 +235,20 @@ TEST_F(DeviceStatusCollectorTest, AllIdle) {
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
// Test reporting with no data.
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
// Test reporting with a single idle sample.
- status_collector_.Simulate(test_states, 1);
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states, 1);
+ GetStatus();
EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
// Test reporting with multiple consecutive idle samples.
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
}
@@ -187,16 +262,16 @@ TEST_F(DeviceStatusCollectorTest, AllActive) {
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
// Test a single active sample.
- status_collector_.Simulate(test_states, 1);
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states, 1);
+ GetStatus();
EXPECT_EQ(1, status_.active_period_size());
EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
status_.clear_active_period(); // Clear the result protobuf.
// Test multiple consecutive active samples.
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(1, status_.active_period_size());
EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -212,9 +287,9 @@ TEST_F(DeviceStatusCollectorTest, MixedStates) {
IDLE_STATE_ACTIVE
};
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -228,18 +303,17 @@ TEST_F(DeviceStatusCollectorTest, StateKeptInPref) {
IDLE_STATE_IDLE
};
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
-
- // Process the list a second time with a different collector.
- // It should be able to count the active periods found by the first
- // collector, because the results are stored in a pref.
- TestingDeviceStatusCollector second_collector(&prefs_,
- &statistics_provider_);
- second_collector.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
-
- second_collector.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+
+ // Process the list a second time after restarting the collector. It should be
+ // able to count the active periods found by the original collector, because
+ // the results are stored in a pref.
+ RestartStatusCollector();
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+
+ GetStatus();
EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -253,9 +327,9 @@ TEST_F(DeviceStatusCollectorTest, Times) {
IDLE_STATE_IDLE
};
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
}
@@ -267,41 +341,41 @@ TEST_F(DeviceStatusCollectorTest, MaxStoredPeriods) {
unsigned int max_days = 10;
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
- status_collector_.set_max_stored_past_activity_days(max_days - 1);
- status_collector_.set_max_stored_future_activity_days(1);
+ status_collector_->set_max_stored_past_activity_days(max_days - 1);
+ status_collector_->set_max_stored_future_activity_days(1);
Time baseline = Time::Now().LocalMidnight();
// Simulate 12 active periods.
for (int i = 0; i < static_cast<int>(max_days) + 2; i++) {
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
// Advance the simulated clock by a day.
baseline += TimeDelta::FromDays(1);
- status_collector_.SetBaselineTime(baseline);
+ status_collector_->SetBaselineTime(baseline);
}
// Check that we don't exceed the max number of periods.
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_EQ(static_cast<int>(max_days), status_.active_period_size());
// Simulate some future times.
for (int i = 0; i < static_cast<int>(max_days) + 2; i++) {
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
// Advance the simulated clock by a day.
baseline += TimeDelta::FromDays(1);
- status_collector_.SetBaselineTime(baseline);
+ status_collector_->SetBaselineTime(baseline);
}
// Set the clock back so the previous simulated times are in the future.
baseline -= TimeDelta::FromDays(20);
- status_collector_.SetBaselineTime(baseline);
+ status_collector_->SetBaselineTime(baseline);
// Collect one more data point to trigger pruning.
- status_collector_.Simulate(test_states, 1);
+ status_collector_->Simulate(test_states, 1);
// Check that we don't exceed the max number of periods.
status_.clear_active_period();
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_LT(status_.active_period_size(), static_cast<int>(max_days));
}
@@ -314,9 +388,9 @@ TEST_F(DeviceStatusCollectorTest, ActivityTimesDisabledByDefault) {
IDLE_STATE_ACTIVE,
IDLE_STATE_ACTIVE
};
- status_collector_.Simulate(test_states,
- sizeof(test_states) / sizeof(IdleState));
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states,
+ sizeof(test_states) / sizeof(IdleState));
+ GetStatus();
EXPECT_EQ(0, status_.active_period_size());
EXPECT_EQ(0, GetActiveMilliseconds(status_));
}
@@ -328,11 +402,11 @@ TEST_F(DeviceStatusCollectorTest, ActivityCrossingMidnight) {
cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
// Set the baseline time to 10 seconds after midnight.
- status_collector_.SetBaselineTime(
+ status_collector_->SetBaselineTime(
Time::Now().LocalMidnight() + TimeDelta::FromSeconds(10));
- status_collector_.Simulate(test_states, 1);
- status_collector_.GetStatus(&status_);
+ status_collector_->Simulate(test_states, 1);
+ GetStatus();
ASSERT_EQ(2, status_.active_period_size());
em::ActiveTimePeriod period0 = status_.active_period(0);
@@ -354,13 +428,11 @@ TEST_F(DeviceStatusCollectorTest, ActivityCrossingMidnight) {
TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) {
// Test that boot mode data is not reported if the pref is not turned on.
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(false, status_.has_boot_mode());
-
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillRepeatedly(DoAll(SetArgPointee<1>("0"), Return(true)));
- EXPECT_EQ(false, status_.has_boot_mode());
+ GetStatus();
+ EXPECT_FALSE(status_.has_boot_mode());
// Turn the pref on, and check that the status is reported iff the
// statistics provider returns valid data.
@@ -369,41 +441,41 @@ TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) {
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillOnce(DoAll(SetArgPointee<1>("(error)"), Return(true)));
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(false, status_.has_boot_mode());
+ GetStatus();
+ EXPECT_FALSE(status_.has_boot_mode());
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillOnce(DoAll(SetArgPointee<1>(" "), Return(true)));
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(false, status_.has_boot_mode());
+ GetStatus();
+ EXPECT_FALSE(status_.has_boot_mode());
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillOnce(DoAll(SetArgPointee<1>("0"), Return(true)));
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_EQ("Verified", status_.boot_mode());
EXPECT_CALL(statistics_provider_,
GetMachineStatistic("devsw_boot", NotNull()))
.WillOnce(DoAll(SetArgPointee<1>("1"), Return(true)));
- status_collector_.GetStatus(&status_);
+ GetStatus();
EXPECT_EQ("Dev", status_.boot_mode());
}
TEST_F(DeviceStatusCollectorTest, VersionInfo) {
// When the pref to collect this data is not enabled, expect that none of
// the fields are present in the protobuf.
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(false, status_.has_browser_version());
- EXPECT_EQ(false, status_.has_os_version());
- EXPECT_EQ(false, status_.has_firmware_version());
+ GetStatus();
+ EXPECT_FALSE(status_.has_browser_version());
+ EXPECT_FALSE(status_.has_os_version());
+ EXPECT_FALSE(status_.has_firmware_version());
cros_settings_->SetBoolean(chromeos::kReportDeviceVersionInfo, true);
- status_collector_.GetStatus(&status_);
- EXPECT_EQ(true, status_.has_browser_version());
- EXPECT_EQ(true, status_.has_os_version());
- EXPECT_EQ(true, status_.has_firmware_version());
+ GetStatus();
+ EXPECT_TRUE(status_.has_browser_version());
+ EXPECT_TRUE(status_.has_os_version());
+ EXPECT_TRUE(status_.has_firmware_version());
// Check that the browser version is not empty. OS version & firmware
// don't have any reasonable values inside the unit test, so those
@@ -411,4 +483,53 @@ TEST_F(DeviceStatusCollectorTest, VersionInfo) {
EXPECT_NE("", status_.browser_version());
}
+TEST_F(DeviceStatusCollectorTest, Location) {
+ content::Geoposition valid_fix;
+ valid_fix.latitude = 4.3;
+ valid_fix.longitude = -7.8;
+ valid_fix.accuracy = 3.;
+ valid_fix.timestamp = Time::Now();
+
+ content::Geoposition invalid_fix;
+ invalid_fix.error_code =
+ content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
+ invalid_fix.timestamp = Time::Now();
+
+ // Check that when device location reporting is disabled, no location is
+ // reported.
+ SetMockPositionToReturnNext(valid_fix);
+ CheckThatNoLocationIsReported();
+
+ // Check that when device location reporting is enabled and a valid fix is
+ // available, the location is reported and is stored in local state.
+ SetMockPositionToReturnNext(valid_fix);
+ cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
+ EXPECT_FALSE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
+ CheckThatAValidLocationIsReported();
+
+ // Restart the status collector. Check that the last known location has been
+ // retrieved from local state without requesting a geolocation update.
+ SetMockPositionToReturnNext(valid_fix);
+ RestartStatusCollector();
+ CheckThatAValidLocationIsReported();
+ EXPECT_TRUE(mock_position_to_return_next.get());
+
+ // Check that after disabling location reporting again, the last known
+ // location has been cleared from local state and is no longer reported.
+ SetMockPositionToReturnNext(valid_fix);
+ cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, false);
+ // Allow the new pref to propagate to the status collector.
+ message_loop_.RunAllPending();
+ EXPECT_TRUE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
+ CheckThatNoLocationIsReported();
+
+ // Check that after enabling location reporting again, an error is reported
+ // if no valid fix is available.
+ SetMockPositionToReturnNext(invalid_fix);
+ cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
+ // Allow the new pref to propagate to the status collector.
+ message_loop_.RunAllPending();
+ CheckThatALocationErrorIsReported();
+}
+
} // namespace policy
« no previous file with comments | « chrome/browser/policy/device_status_collector.cc ('k') | chrome/browser/policy/proto/device_management_backend.proto » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698