| Index: chrome/browser/engagement/site_engagement_service_unittest.cc
|
| diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc
|
| index 85e709da56e3038918725d5fd517713441c19ae2..f0a0f79e2c601dc3262afa07741d8ca58cdbba78 100644
|
| --- a/chrome/browser/engagement/site_engagement_service_unittest.cc
|
| +++ b/chrome/browser/engagement/site_engagement_service_unittest.cc
|
| @@ -20,6 +20,7 @@
|
| #include "chrome/browser/history/history_service_factory.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| #include "chrome/common/chrome_switches.h"
|
| +#include "chrome/common/pref_names.h"
|
| #include "chrome/test/base/chrome_render_view_host_test_harness.h"
|
| #include "chrome/test/base/testing_profile.h"
|
| #include "components/content_settings/core/browser/content_settings_observer.h"
|
| @@ -27,6 +28,7 @@
|
| #include "components/history/core/browser/history_database_params.h"
|
| #include "components/history/core/browser/history_service.h"
|
| #include "components/history/core/test/test_history_database.h"
|
| +#include "components/prefs/pref_service.h"
|
| #include "content/public/browser/navigation_entry.h"
|
| #include "content/public/browser/page_navigator.h"
|
| #include "content/public/browser/web_contents.h"
|
| @@ -39,7 +41,6 @@ base::FilePath g_temp_history_dir;
|
|
|
| const int kMoreAccumulationsThanNeededToMaxDailyEngagement = 40;
|
| const int kMoreDaysThanNeededToMaxTotalEngagement = 40;
|
| -const int kLessPeriodsThanNeededToDecayMaxScore = 2;
|
| const int kMorePeriodsThanNeededToDecayMaxScore = 40;
|
|
|
| // Waits until a change is observed in site engagement content settings.
|
| @@ -666,67 +667,140 @@ TEST_F(SiteEngagementServiceTest, CheckHistograms) {
|
| histograms.ExpectBucketCount(engagement_bucket_histogram_names[1], 66, 1);
|
| }
|
|
|
| -// Expect that sites that have reached zero engagement are cleaned up.
|
| +// Expect that sites that have reached zero engagement are cleaned up. Expect
|
| +// engagement times to be reset if too much time has passed since the last
|
| +// engagement.
|
| TEST_F(SiteEngagementServiceTest, CleanupEngagementScores) {
|
| base::SimpleTestClock* clock = new base::SimpleTestClock();
|
| std::unique_ptr<SiteEngagementService> service(
|
| new SiteEngagementService(profile(), base::WrapUnique(clock)));
|
|
|
| - base::Time current_day = GetReferenceTime();
|
| - clock->SetNow(current_day);
|
| + // Set the base time to be (obsoletion period + 2 * (decay period - 1 second))
|
| + // in the past. The one second offset ensures that engagement won't decay
|
| + // (yet).
|
| + base::TimeDelta one_second = base::TimeDelta::FromSeconds(1);
|
| + base::TimeDelta obsoletion_period = base::TimeDelta::FromHours(
|
| + SiteEngagementScore::GetObsoleteLastEngagementPeriodInHours());
|
| + base::TimeDelta decay_period =
|
| + base::TimeDelta::FromDays(SiteEngagementScore::GetDecayPeriodInDays());
|
| + base::TimeDelta shorter_than_decay_period = decay_period - one_second;
|
| + base::Time base_time =
|
| + GetReferenceTime() - obsoletion_period - shorter_than_decay_period * 2;
|
| + clock->SetNow(base_time);
|
|
|
| // The https and http versions of www.google.com should be separate.
|
| GURL url1("https://www.google.com/");
|
| GURL url2("http://www.google.com/");
|
| + GURL url3("http://maps.google.com/");
|
| + GURL url4("http://drive.google.com/");
|
|
|
| EXPECT_EQ(0, service->GetScore(url1));
|
| EXPECT_EQ(0, service->GetScore(url2));
|
| + EXPECT_EQ(0, service->GetScore(url3));
|
| + EXPECT_EQ(0, service->GetScore(url4));
|
|
|
| - // Add the maximum number of points for one day.
|
| + // Add the maximum number of points for one day for two origins. Leave url2
|
| + // alone after this.
|
| service->AddPoints(url1, 5.0);
|
| - EXPECT_EQ(5.0, service->GetScore(url1));
|
| service->AddPoints(url2, 5.0);
|
| + EXPECT_EQ(5.0, service->GetScore(url1));
|
| EXPECT_EQ(5.0, service->GetScore(url2));
|
|
|
| - // Add more points by moving to another day.
|
| - clock->SetNow(GetReferenceTime() + base::TimeDelta::FromDays(1));
|
| -
|
| - service->AddPoints(url1, 5.0);
|
| + // Add more points by moving to another day. This is (obsoletion_period
|
| + // + shorter_than_decay_period) in the past.
|
| + base_time += shorter_than_decay_period;
|
| + clock->SetNow(base_time);
|
| + service->AddPoints(url1, 2.5);
|
| + service->AddPoints(url3, 5.0);
|
| + EXPECT_EQ(7.5, service->GetScore(url1));
|
| + EXPECT_EQ(5.0, service->GetScore(url3));
|
| +
|
| + // Add more points by moving to another day. This is obsoletion_period in
|
| + // the past.
|
| + base_time += shorter_than_decay_period;
|
| + clock->SetNow(base_time);
|
| + service->AddPoints(url1, 2.5);
|
| + service->AddPoints(url4, 5.0);
|
| EXPECT_EQ(10.0, service->GetScore(url1));
|
| + EXPECT_EQ(5.0, service->GetScore(url4));
|
|
|
| {
|
| - // Decay one origin to zero by advancing time and expect the engagement
|
| - // score to be cleaned up. The other score was changed a day later so it
|
| - // will not have decayed at all.
|
| - clock->SetNow(
|
| - GetReferenceTime() +
|
| - base::TimeDelta::FromDays(SiteEngagementScore::GetDecayPeriodInDays()));
|
| + clock->SetNow(GetReferenceTime());
|
| + ASSERT_TRUE(service->IsLastEngagementObsolete());
|
| +
|
| + // Run a cleanup. Last engagement times will be reset relative to today.
|
| + // After the reset, url2 was last accessed > decay_period ago, so it will
|
| + // still decay. Everything else will be within a decay period and not decay.
|
| + service->CleanupEngagementScores(true);
|
|
|
| std::map<GURL, double> score_map = service->GetScoreMap();
|
| - EXPECT_EQ(2u, score_map.size());
|
| + EXPECT_EQ(3u, score_map.size());
|
| EXPECT_EQ(10, score_map[url1]);
|
| - EXPECT_EQ(0, score_map[url2]);
|
| + EXPECT_EQ(5.0, score_map[url3]);
|
| + EXPECT_EQ(5.0, score_map[url4]);
|
| + EXPECT_EQ(0, service->GetScore(url2));
|
| +
|
| + EXPECT_EQ(clock->Now(),
|
| + service->CreateEngagementScore(url1).last_engagement_time());
|
| + EXPECT_EQ(clock->Now() - shorter_than_decay_period,
|
| + service->CreateEngagementScore(url3).last_engagement_time());
|
| + EXPECT_EQ(clock->Now(),
|
| + service->CreateEngagementScore(url4).last_engagement_time());
|
| + }
|
|
|
| - service->CleanupEngagementScores();
|
| + {
|
| + // Advance time by a second and expect url3 to be decayed to zero. Run a
|
| + // cleanup without adjusting times and expect url3 to be purged.
|
| + clock->SetNow(GetReferenceTime() + one_second);
|
| + ASSERT_FALSE(service->IsLastEngagementObsolete());
|
| +
|
| + std::map<GURL, double> score_map = service->GetScoreMap();
|
| + EXPECT_EQ(3u, score_map.size());
|
| + EXPECT_EQ(10, score_map[url1]);
|
| + EXPECT_EQ(0, score_map[url3]);
|
| + EXPECT_EQ(5.0, score_map[url4]);
|
| +
|
| + service->CleanupEngagementScores(false);
|
|
|
| score_map = service->GetScoreMap();
|
| - EXPECT_EQ(1u, score_map.size());
|
| + EXPECT_EQ(2u, score_map.size());
|
| EXPECT_EQ(10, score_map[url1]);
|
| - EXPECT_EQ(0, service->GetScore(url2));
|
| + EXPECT_EQ(5.0, score_map[url4]);
|
| + EXPECT_EQ(0, service->GetScore(url3));
|
| }
|
|
|
| {
|
| - // Decay the other origin to zero by advancing time and expect the
|
| - // engagement score to be cleaned up.
|
| - clock->SetNow(GetReferenceTime() +
|
| - base::TimeDelta::FromDays(
|
| - 3 * SiteEngagementScore::GetDecayPeriodInDays()));
|
| + // Decay the final two origins to zero and expect them to be cleaned up.
|
| + // This needs to be done in two calls or else the score will be obsolete.
|
| + clock->SetNow(
|
| + GetReferenceTime() +
|
| + base::TimeDelta::FromDays(SiteEngagementScore::GetDecayPeriodInDays()) +
|
| + one_second);
|
| + ASSERT_FALSE(service->IsLastEngagementObsolete());
|
|
|
| std::map<GURL, double> score_map = service->GetScoreMap();
|
| + EXPECT_EQ(2u, score_map.size());
|
| + EXPECT_EQ(5, score_map[url1]);
|
| + EXPECT_EQ(0, score_map[url4]);
|
| +
|
| + service->CleanupEngagementScores(false);
|
| +
|
| + score_map = service->GetScoreMap();
|
| + EXPECT_EQ(1u, score_map.size());
|
| + EXPECT_EQ(5, score_map[url1]);
|
| + EXPECT_EQ(0, service->GetScore(url4));
|
| +
|
| + clock->SetNow(GetReferenceTime() +
|
| + 2 * base::TimeDelta::FromDays(
|
| + SiteEngagementScore::GetDecayPeriodInDays()) +
|
| + one_second);
|
| + ASSERT_FALSE(service->IsLastEngagementObsolete());
|
| +
|
| + score_map = service->GetScoreMap();
|
| EXPECT_EQ(1u, score_map.size());
|
| EXPECT_EQ(0, score_map[url1]);
|
|
|
| - service->CleanupEngagementScores();
|
| + service->CleanupEngagementScores(false);
|
|
|
| score_map = service->GetScoreMap();
|
| EXPECT_EQ(0u, score_map.size());
|
| @@ -1063,10 +1137,10 @@ TEST_F(SiteEngagementServiceTest, ScoreDecayHistograms) {
|
| SiteEngagementScore::kMaxPoints - SiteEngagementScore::GetDecayPoints(),
|
| 1);
|
|
|
| - // Check histograms after a few decay periods.
|
| - clock->SetNow(current_day + base::TimeDelta::FromDays(
|
| - kLessPeriodsThanNeededToDecayMaxScore *
|
| - SiteEngagementScore::GetDecayPeriodInDays()));
|
| + // Check histograms after another decay period.
|
| + clock->SetNow(current_day +
|
| + base::TimeDelta::FromDays(
|
| + 2 * SiteEngagementScore::GetDecayPeriodInDays()));
|
| // Trigger decay and histogram hit.
|
| service->AddPoints(origin1, 0.01);
|
| histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
|
| @@ -1074,34 +1148,107 @@ TEST_F(SiteEngagementServiceTest, ScoreDecayHistograms) {
|
| histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
|
| 2);
|
|
|
| - // Check decay to zero.
|
| - clock->SetNow(current_day + base::TimeDelta::FromDays(
|
| - kMorePeriodsThanNeededToDecayMaxScore *
|
| - SiteEngagementScore::GetDecayPeriodInDays()));
|
| - // Trigger decay and histogram hit.
|
| - service->AddPoints(origin1, 0.01);
|
| + // Check decay to zero. Start at the 3rd decay period (we have had two
|
| + // already). This will be 40 decays in total.
|
| + for (int i = 3; i <= kMorePeriodsThanNeededToDecayMaxScore; ++i) {
|
| + clock->SetNow(current_day +
|
| + base::TimeDelta::FromDays(
|
| + i * SiteEngagementScore::GetDecayPeriodInDays()));
|
| + // Trigger decay and histogram hit.
|
| + service->AddPoints(origin1, 0.01);
|
| + }
|
| histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
|
| - 3);
|
| + kMorePeriodsThanNeededToDecayMaxScore);
|
| histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
|
| - 3);
|
| + kMorePeriodsThanNeededToDecayMaxScore);
|
| + // It should have taken (20 - 3) = 17 of the 38 decays to get to zero, since
|
| + // we started from 95. Expect the remaining 21 decays to be to bucket 0 (and
|
| + // hence 20 from bucket 0).
|
| + histograms.ExpectBucketCount(
|
| + SiteEngagementMetrics::kScoreDecayedFromHistogram, 0, 20);
|
| histograms.ExpectBucketCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
|
| - 0, 1);
|
| + 0, 21);
|
| // Trigger decay and histogram hit for origin2, checking an independent decay.
|
| service->AddPoints(origin2, 0.01);
|
| histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
|
| - 4);
|
| + kMorePeriodsThanNeededToDecayMaxScore + 1);
|
| histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
|
| - 4);
|
| + kMorePeriodsThanNeededToDecayMaxScore + 1);
|
| histograms.ExpectBucketCount(
|
| - SiteEngagementMetrics::kScoreDecayedFromHistogram, 0, 1);
|
| + SiteEngagementMetrics::kScoreDecayedFromHistogram, 0, 21);
|
| histograms.ExpectBucketCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
|
| - 0, 2);
|
| + 0, 22);
|
|
|
| // Add more points and ensure no more samples are present.
|
| service->AddPoints(origin1, 0.01);
|
| service->AddPoints(origin2, 0.01);
|
| histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedFromHistogram,
|
| - 4);
|
| + kMorePeriodsThanNeededToDecayMaxScore + 1);
|
| histograms.ExpectTotalCount(SiteEngagementMetrics::kScoreDecayedToHistogram,
|
| - 4);
|
| + kMorePeriodsThanNeededToDecayMaxScore + 1);
|
| +}
|
| +
|
| +TEST_F(SiteEngagementServiceTest, PersistLastEngagementTime) {
|
| + // The last engagement time should start off null in prefs and in the service.
|
| + base::Time last_engagement_time = base::Time::FromInternalValue(
|
| + profile()->GetPrefs()->GetInt64(prefs::kSiteEngagementLastUpdateTime));
|
| +
|
| + ASSERT_TRUE(last_engagement_time.is_null());
|
| +
|
| + base::SimpleTestClock* clock = new base::SimpleTestClock();
|
| + std::unique_ptr<SiteEngagementService> service(
|
| + new SiteEngagementService(profile(), base::WrapUnique(clock)));
|
| +
|
| + ASSERT_TRUE(service->last_engagement_time_.is_null());
|
| +
|
| + base::Time current_day = GetReferenceTime();
|
| + clock->SetNow(current_day);
|
| +
|
| + // Add points should set the last engagement time in the service, but not
|
| + // persist it to disk.
|
| + GURL origin("http://www.google.com/");
|
| + service->AddPoints(origin, 1);
|
| +
|
| + last_engagement_time = base::Time::FromInternalValue(
|
| + profile()->GetPrefs()->GetInt64(prefs::kSiteEngagementLastUpdateTime));
|
| +
|
| + ASSERT_TRUE(last_engagement_time.is_null());
|
| + ASSERT_FALSE(service->last_engagement_time_.is_null());
|
| + EXPECT_EQ(service->last_engagement_time_, current_day);
|
| +
|
| + // Running a cleanup and updating last engagement times should persist the
|
| + // last engagement time to disk.
|
| + current_day +=
|
| + base::TimeDelta::FromHours(
|
| + SiteEngagementScore::GetObsoleteLastEngagementPeriodInHours());
|
| + clock->SetNow(current_day);
|
| + service->CleanupEngagementScores(true);
|
| +
|
| + last_engagement_time = base::Time::FromInternalValue(
|
| + profile()->GetPrefs()->GetInt64(prefs::kSiteEngagementLastUpdateTime));
|
| +
|
| + ASSERT_FALSE(last_engagement_time.is_null());
|
| + EXPECT_EQ(last_engagement_time, current_day);
|
| + EXPECT_EQ(service->last_engagement_time_, current_day);
|
| +
|
| + // Add some more points and ensure the value isn't persisted.
|
| + base::Time later_in_day = current_day + base::TimeDelta::FromSeconds(30);
|
| + clock->SetNow(later_in_day);
|
| + service->AddPoints(origin, 3);
|
| +
|
| + last_engagement_time = base::Time::FromInternalValue(
|
| + profile()->GetPrefs()->GetInt64(prefs::kSiteEngagementLastUpdateTime));
|
| +
|
| + ASSERT_FALSE(last_engagement_time.is_null());
|
| + EXPECT_EQ(last_engagement_time, current_day);
|
| + ASSERT_FALSE(service->last_engagement_time_.is_null());
|
| + EXPECT_EQ(service->last_engagement_time_, later_in_day);
|
| +
|
| + // When the service is destroyed, the time should be persisted to disk.
|
| + service.reset(nullptr);
|
| + last_engagement_time = base::Time::FromInternalValue(
|
| + profile()->GetPrefs()->GetInt64(prefs::kSiteEngagementLastUpdateTime));
|
| +
|
| + ASSERT_FALSE(last_engagement_time.is_null());
|
| + EXPECT_EQ(last_engagement_time, later_in_day);
|
| }
|
|
|