| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ash/crostini/crostini_reporting_util.h" |
| |
| #include <stdint.h> |
| #include <vector> |
| |
| #include "base/test/simple_test_clock.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/ash/crostini/crostini_pref_names.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "components/component_updater/component_updater_service.h" |
| #include "components/component_updater/mock_component_updater_service.h" |
| #include "components/prefs/pref_service.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using testing::Mock; |
| using testing::Return; |
| |
| namespace crostini { |
| |
| class CrostiniReportingUtilTest : public testing::Test { |
| public: |
| CrostiniReportingUtilTest() = default; |
| |
| CrostiniReportingUtilTest(const CrostiniReportingUtilTest&) = delete; |
| CrostiniReportingUtilTest& operator=(const CrostiniReportingUtilTest&) = |
| delete; |
| |
| protected: |
| void enable_crostini_reporting() { |
| profile_.GetPrefs()->SetBoolean(prefs::kReportCrostiniUsageEnabled, true); |
| } |
| |
| content::BrowserTaskEnvironment task_environment_; |
| base::SimpleTestClock test_clock_; |
| TestingProfile profile_; |
| component_updater::MockComponentUpdateService update_service_; |
| }; |
| |
| TEST_F(CrostiniReportingUtilTest, WriteMetricsForReportingToPrefsIfEnabled) { |
| base::Time time; |
| EXPECT_TRUE(base::Time::FromString("Sat, 1 Sep 2018 11:50:50 GMT", &time)); |
| test_clock_.SetNow(time); |
| |
| const auto component_info = component_updater::ComponentInfo( |
| "id2", "fingerprint2", u"cros-termina", base::Version("1.33.7"), ""); |
| EXPECT_CALL(update_service_, GetComponents()) |
| .Times(1) |
| .WillOnce(Return( |
| std::vector<component_updater::ComponentInfo>({component_info}))); |
| |
| PrefService* const preferences = profile_.GetPrefs(); |
| |
| // Usage reporting is disabled by default, so we expect no usage logging, |
| // which means no pref path exists and the prefs have default values: |
| WriteMetricsForReportingToPrefsIfEnabled(preferences, &update_service_, |
| &test_clock_); |
| |
| int64_t timestamp = |
| preferences->GetInt64(prefs::kCrostiniLastLaunchTimeWindowStart); |
| std::string termina_version = |
| preferences->GetString(prefs::kCrostiniLastLaunchTerminaComponentVersion); |
| EXPECT_FALSE( |
| preferences->HasPrefPath(prefs::kCrostiniLastLaunchTimeWindowStart)); |
| EXPECT_FALSE(preferences->HasPrefPath( |
| prefs::kCrostiniLastLaunchTerminaComponentVersion)); |
| EXPECT_EQ(0, timestamp); |
| EXPECT_TRUE(termina_version.empty()); |
| |
| // With usage reporting enabled, we should obtain non-default values: |
| enable_crostini_reporting(); |
| |
| WriteMetricsForReportingToPrefsIfEnabled(preferences, &update_service_, |
| &test_clock_); |
| |
| timestamp = preferences->GetInt64(prefs::kCrostiniLastLaunchTimeWindowStart); |
| termina_version = |
| preferences->GetString(prefs::kCrostiniLastLaunchTerminaComponentVersion); |
| EXPECT_EQ(1535760000000, timestamp); // 1 Sep 2018 00:00:00 GMT |
| EXPECT_EQ("1.33.7", termina_version); |
| } |
| |
| TEST_F(CrostiniReportingUtilTest, WriteMetricsIfThereIsNoTerminaVersion) { |
| base::Time time; |
| EXPECT_TRUE(base::Time::FromString("Sat, 1 Sep 2018 11:50:50 GMT", &time)); |
| test_clock_.SetNow(time); |
| PrefService* const preferences = profile_.GetPrefs(); |
| enable_crostini_reporting(); |
| |
| // We test here that reporting does not break if no Termina version |
| // can be found because the component is not registered under the |
| // expected name. |
| EXPECT_CALL(update_service_, GetComponents()) |
| .Times(1) |
| .WillOnce(Return(std::vector<component_updater::ComponentInfo>())); |
| WriteMetricsForReportingToPrefsIfEnabled(preferences, &update_service_, |
| &test_clock_); |
| |
| const int64_t timestamp = |
| preferences->GetInt64(prefs::kCrostiniLastLaunchTimeWindowStart); |
| const std::string termina_version = |
| preferences->GetString(prefs::kCrostiniLastLaunchTerminaComponentVersion); |
| EXPECT_EQ(1535760000000, timestamp); // 1 Sep 2018 00:00:00 GMT |
| EXPECT_TRUE(termina_version.empty()); |
| } |
| |
| TEST_F(CrostiniReportingUtilTest, GetThreeDayWindowStart) { |
| base::Time time; |
| EXPECT_TRUE(base::Time::FromString("Fri, 31 Aug 2018 11:50:50 GMT", &time)); |
| test_clock_.SetNow(time); |
| |
| // Time is set to the beginning of the day of the start of a |
| // three day window (for privacy reasons). |
| base::Time window_start; |
| EXPECT_TRUE( |
| base::Time::FromString("Wed, 29 Aug 2018 00:00:00 GMT", &window_start)); |
| EXPECT_EQ(window_start, GetThreeDayWindowStart(test_clock_.Now())); |
| |
| // Since a three-day period has been crossed, another time is returned |
| // for three consecutive days: |
| base::Time next_window_start; |
| EXPECT_TRUE(base::Time::FromString("Sat, 1 Sep 2018 00:00:00 GMT", |
| &next_window_start)); |
| test_clock_.Advance(base::Days(1)); |
| EXPECT_EQ(next_window_start, GetThreeDayWindowStart(test_clock_.Now())); |
| |
| test_clock_.Advance(base::Days(1)); |
| EXPECT_EQ(next_window_start, GetThreeDayWindowStart(test_clock_.Now())); |
| |
| test_clock_.Advance(base::Days(1)); |
| EXPECT_EQ(next_window_start, GetThreeDayWindowStart(test_clock_.Now())); |
| |
| // After three consecutive days logged with the same value, we now expect |
| // a three day change again: |
| base::Time three_days_later; |
| EXPECT_TRUE(base::Time::FromString("Tue, 4 Sep 2018 00:00:00 GMT", |
| &three_days_later)); |
| test_clock_.Advance(base::Days(1)); |
| EXPECT_EQ(three_days_later, GetThreeDayWindowStart(test_clock_.Now())); |
| } |
| |
| TEST_F(CrostiniReportingUtilTest, GetTerminaVersion) { |
| component_updater::MockComponentUpdateService* const update_service = |
| &update_service_; |
| EXPECT_CALL(*update_service, GetComponents()) |
| .Times(1) |
| .WillOnce(Return(std::vector<component_updater::ComponentInfo>())); |
| EXPECT_TRUE(GetTerminaVersion(update_service).empty()); |
| |
| Mock::VerifyAndClearExpectations(update_service); |
| |
| const auto component_info_1 = component_updater::ComponentInfo( |
| "id1", "fingerprint1", u"name1", base::Version("1.0"), ""); |
| const auto component_info_2 = component_updater::ComponentInfo( |
| "id2", "fingerprint2", u"cros-termina", base::Version("1.33.7"), ""); |
| const auto component_info_3 = component_updater::ComponentInfo( |
| "id3", "fingerprint3", u"name1", base::Version("1.0"), ""); |
| EXPECT_CALL(*update_service, GetComponents()) |
| .Times(1) |
| .WillOnce(Return(std::vector<component_updater::ComponentInfo>( |
| {component_info_1, component_info_2, component_info_3}))); |
| |
| EXPECT_EQ("1.33.7", GetTerminaVersion(update_service)); |
| } |
| |
| } // namespace crostini |