Commit 30d51c39 authored by Yao Xiao's avatar Yao Xiao Committed by Commit Bot

Set a pending recompute event to run after the in-progress one finishes

Why: Before this patch we'd ignore any recompute event coming during
an in-progress computation. That assumes the history query callback is
the last task to run before the computation completes. However, since
we are going to add SortingLSH based computation after the history
callback, and the check (i.e. file read) is async, the original
assumption no longer holds. And there could be races.

What: This CL handles of recompute that comes during an in-progress
computation. We'll use a member variable to keep track of the last
recompute event (trigger) that we weren't able to handle. After the
current one completes, we'll ignore its result, and we'll recompute
again using that pending trigger.


Bug: 1062736
Change-Id: I3e30d26d47352480faa39494b0f6b4171f361456
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2437782Reviewed-by: default avatarJosh Karlin <jkarlin@chromium.org>
Commit-Queue: Yao Xiao <yaoxia@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811827}
parent fdaf667d
...@@ -332,7 +332,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest, ...@@ -332,7 +332,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest,
EXPECT_EQ(1u, GetHistoryUrls().size()); EXPECT_EQ(1u, GetHistoryUrls().size());
EXPECT_EQ(GetFlocId().ToDebugHeaderValue(), FlocId().ToDebugHeaderValue()); EXPECT_EQ(GetFlocId(), FlocId());
InitializeBlocklist({}); InitializeBlocklist({});
...@@ -362,7 +362,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest, ...@@ -362,7 +362,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest,
EXPECT_EQ(1u, GetHistoryUrls().size()); EXPECT_EQ(1u, GetHistoryUrls().size());
EXPECT_EQ(GetFlocId().ToDebugHeaderValue(), FlocId().ToDebugHeaderValue()); EXPECT_EQ(GetFlocId(), FlocId());
InitializeBlocklist({}); InitializeBlocklist({});
...@@ -382,7 +382,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest, ...@@ -382,7 +382,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest,
EXPECT_EQ(1u, GetHistoryUrls().size()); EXPECT_EQ(1u, GetHistoryUrls().size());
EXPECT_EQ(GetFlocId().ToDebugHeaderValue(), FlocId().ToDebugHeaderValue()); EXPECT_EQ(GetFlocId(), FlocId());
InitializeBlocklist({}); InitializeBlocklist({});
...@@ -419,7 +419,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest, ...@@ -419,7 +419,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest,
EXPECT_EQ(1u, GetHistoryUrls().size()); EXPECT_EQ(1u, GetHistoryUrls().size());
EXPECT_EQ(GetFlocId().ToDebugHeaderValue(), FlocId().ToDebugHeaderValue()); EXPECT_EQ(GetFlocId(), FlocId());
// Load a blocklist that would block the upcoming floc. // Load a blocklist that would block the upcoming floc.
InitializeBlocklist({FlocId::CreateFromHistory({test_host()}).ToUint64()}); InitializeBlocklist({FlocId::CreateFromHistory({test_host()}).ToUint64()});
...@@ -440,7 +440,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest, ...@@ -440,7 +440,7 @@ IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest,
EXPECT_EQ(1u, GetHistoryUrls().size()); EXPECT_EQ(1u, GetHistoryUrls().size());
EXPECT_EQ(GetFlocId().ToDebugHeaderValue(), FlocId().ToDebugHeaderValue()); EXPECT_EQ(GetFlocId(), FlocId());
// Load a blocklist that would block a floc different from the upcoming floc. // Load a blocklist that would block a floc different from the upcoming floc.
InitializeBlocklist({FlocId::CreateFromHistory({"b.test"}).ToUint64()}); InitializeBlocklist({FlocId::CreateFromHistory({"b.test"}).ToUint64()});
......
...@@ -80,6 +80,33 @@ std::string FlocIdProviderImpl::GetInterestCohortForJsApi( ...@@ -80,6 +80,33 @@ std::string FlocIdProviderImpl::GetInterestCohortForJsApi(
return floc_id_.ToString(); return floc_id_.ToString();
} }
void FlocIdProviderImpl::OnComputeFlocCompleted(ComputeFlocTrigger trigger,
FlocId floc_id) {
DCHECK(floc_computation_in_progress_);
floc_computation_in_progress_ = false;
// Some recompute event came in when this computation was in progress. Ignore
// this computation completely. Handle the pending one.
if (pending_recompute_event_) {
ComputeFlocTrigger recompute_trigger = pending_recompute_event_.value();
pending_recompute_event_.reset();
ComputeFloc(recompute_trigger);
return;
}
if (floc_id_ != floc_id) {
floc_id_ = floc_id;
NotifyFlocUpdated(trigger);
}
// Abandon the scheduled task if any, and schedule a new compute-floc task
// that is |kFlocScheduledUpdateInterval| from now.
compute_floc_timer_.Start(
FROM_HERE, kFlocScheduledUpdateInterval,
base::BindOnce(&FlocIdProviderImpl::OnComputeFlocScheduledUpdate,
weak_ptr_factory_.GetWeakPtr()));
}
void FlocIdProviderImpl::NotifyFlocUpdated(ComputeFlocTrigger trigger) { void FlocIdProviderImpl::NotifyFlocUpdated(ComputeFlocTrigger trigger) {
if (!base::FeatureList::IsEnabled(features::kFlocIdComputedEventLogging)) if (!base::FeatureList::IsEnabled(features::kFlocIdComputedEventLogging))
return; return;
...@@ -115,64 +142,6 @@ void FlocIdProviderImpl::NotifyFlocUpdated(ComputeFlocTrigger trigger) { ...@@ -115,64 +142,6 @@ void FlocIdProviderImpl::NotifyFlocUpdated(ComputeFlocTrigger trigger) {
user_event_service_->RecordUserEvent(std::move(specifics)); user_event_service_->RecordUserEvent(std::move(specifics));
} }
bool FlocIdProviderImpl::IsSyncHistoryEnabled() const {
syncer::SyncUserSettings* setting = sync_service_->GetUserSettings();
DCHECK(setting);
return sync_service_->IsSyncFeatureActive() &&
sync_service_->GetActiveDataTypes().Has(
syncer::HISTORY_DELETE_DIRECTIVES);
}
bool FlocIdProviderImpl::AreThirdPartyCookiesAllowed() const {
return !cookie_settings_->ShouldBlockThirdPartyCookies();
}
void FlocIdProviderImpl::IsSwaaNacAccountEnabled(
CanComputeFlocCallback callback) {
if (!last_swaa_nac_account_enabled_query_time_.is_null() &&
last_swaa_nac_account_enabled_query_time_ +
kSwaaNacAccountEnabledCachePeriod >
base::TimeTicks::Now()) {
std::move(callback).Run(cached_swaa_nac_account_enabled_);
return;
}
net::PartialNetworkTrafficAnnotationTag partial_traffic_annotation =
net::DefinePartialNetworkTrafficAnnotation(
"floc_id_provider_impl", "floc_remote_permission_service",
R"(
semantics {
description:
"Queries google to find out if user has enabled 'web and app "
"activity' and 'ad personalization', and if the account type is "
"NOT a child account. Those permission bits will be checked before "
"computing the FLoC (Federated Learning of Cohorts) ID - an "
"anonymous similarity hash value of user’s navigation history. "
"This ensures that the FLoC ID is derived from data that Google "
"already owns and the user has explicitly granted permission on "
"what they will be used for."
trigger:
"This request is sent at each time a FLoC (Federated Learning of "
"Cohorts) ID is to be computed. A FLoC ID is an anonymous "
"similarity hash value of user’s navigation history. It'll be "
"computed at the start of each browser profile session and will be "
"refreshed every 24 hours during that session."
data:
"Google credentials if user is signed in."
}
policy {
setting:
"This feature cannot be disabled in settings, but disabling sync "
"or third-party cookies will prevent it."
})");
floc_remote_permission_service_->QueryFlocPermission(
base::BindOnce(&FlocIdProviderImpl::OnCheckSwaaNacAccountEnabledCompleted,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
partial_traffic_annotation);
}
void FlocIdProviderImpl::Shutdown() { void FlocIdProviderImpl::Shutdown() {
if (sync_service_) if (sync_service_)
sync_service_->RemoveObserver(this); sync_service_->RemoveObserver(this);
...@@ -188,6 +157,14 @@ void FlocIdProviderImpl::Shutdown() { ...@@ -188,6 +157,14 @@ void FlocIdProviderImpl::Shutdown() {
void FlocIdProviderImpl::OnURLsDeleted( void FlocIdProviderImpl::OnURLsDeleted(
history::HistoryService* history_service, history::HistoryService* history_service,
const history::DeletionInfo& deletion_info) { const history::DeletionInfo& deletion_info) {
// Set a pending event or override the existing one, that will get run when
// the in-progress computation finishes.
if (floc_computation_in_progress_) {
DCHECK(first_floc_computation_triggered_);
pending_recompute_event_ = ComputeFlocTrigger::kHistoryDelete;
return;
}
if (!first_floc_computation_triggered_ || !floc_id_.IsValid()) if (!first_floc_computation_triggered_ || !floc_id_.IsValid())
return; return;
...@@ -228,24 +205,23 @@ void FlocIdProviderImpl::MaybeTriggerFirstFlocComputation() { ...@@ -228,24 +205,23 @@ void FlocIdProviderImpl::MaybeTriggerFirstFlocComputation() {
ComputeFloc(ComputeFlocTrigger::kBrowserStart); ComputeFloc(ComputeFlocTrigger::kBrowserStart);
} }
void FlocIdProviderImpl::OnComputeFlocScheduledUpdate() {
// It's fine to skip the scheduled update as long as there's one in progress.
// We won't be losing the recomputing frequency, as the in-progress one only
// occurs sooner and when it finishes a new compute-floc task will be
// scheduled.
if (floc_computation_in_progress_)
return;
DCHECK(!pending_recompute_event_);
ComputeFloc(ComputeFlocTrigger::kScheduledUpdate);
}
void FlocIdProviderImpl::ComputeFloc(ComputeFlocTrigger trigger) { void FlocIdProviderImpl::ComputeFloc(ComputeFlocTrigger trigger) {
DCHECK_NE(trigger == ComputeFlocTrigger::kBrowserStart, DCHECK_NE(trigger == ComputeFlocTrigger::kBrowserStart,
first_floc_computation_triggered_); first_floc_computation_triggered_);
DCHECK(!floc_computation_in_progress_);
DCHECK(trigger != ComputeFlocTrigger::kBrowserStart ||
!floc_computation_in_progress_);
// It's fine to skip computing as long as there's one in progress:
// 1) If the incoming computation was triggered by history deletion, then the
// in-progress one must haven't got its history query result (if it would
// reach that stage), so the history query result wouldn't contain the
// deleted entries anyway.
// 2) If the incoming computation was triggered by scheduled update and is
// ignored, we won't be losing the recomputing frequency, as the
// in-progress one only occurs sooner and when it finishes a new
// compute-floc task will be scheduled.
if (floc_computation_in_progress_)
return;
floc_computation_in_progress_ = true; floc_computation_in_progress_ = true;
first_floc_computation_triggered_ = true; first_floc_computation_triggered_ = true;
...@@ -260,25 +236,6 @@ void FlocIdProviderImpl::ComputeFloc(ComputeFlocTrigger trigger) { ...@@ -260,25 +236,6 @@ void FlocIdProviderImpl::ComputeFloc(ComputeFlocTrigger trigger) {
std::move(compute_floc_completed_callback))); std::move(compute_floc_completed_callback)));
} }
void FlocIdProviderImpl::OnComputeFlocCompleted(ComputeFlocTrigger trigger,
FlocId floc_id) {
DCHECK(floc_computation_in_progress_);
floc_computation_in_progress_ = false;
if (floc_id_ != floc_id) {
floc_id_ = floc_id;
NotifyFlocUpdated(trigger);
}
// Abandon the scheduled task if any, and schedule a new compute-floc task
// that is |kFlocScheduledUpdateInterval| from now.
compute_floc_timer_.Start(
FROM_HERE, kFlocScheduledUpdateInterval,
base::BindOnce(&FlocIdProviderImpl::ComputeFloc,
weak_ptr_factory_.GetWeakPtr(),
ComputeFlocTrigger::kScheduledUpdate));
}
void FlocIdProviderImpl::CheckCanComputeFloc(CanComputeFlocCallback callback) { void FlocIdProviderImpl::CheckCanComputeFloc(CanComputeFlocCallback callback) {
if (!IsSyncHistoryEnabled() || !AreThirdPartyCookiesAllowed()) { if (!IsSyncHistoryEnabled() || !AreThirdPartyCookiesAllowed()) {
std::move(callback).Run(false); std::move(callback).Run(false);
...@@ -301,6 +258,64 @@ void FlocIdProviderImpl::OnCheckCanComputeFlocCompleted( ...@@ -301,6 +258,64 @@ void FlocIdProviderImpl::OnCheckCanComputeFlocCompleted(
weak_ptr_factory_.GetWeakPtr(), std::move(callback))); weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
} }
bool FlocIdProviderImpl::IsSyncHistoryEnabled() const {
syncer::SyncUserSettings* setting = sync_service_->GetUserSettings();
DCHECK(setting);
return sync_service_->IsSyncFeatureActive() &&
sync_service_->GetActiveDataTypes().Has(
syncer::HISTORY_DELETE_DIRECTIVES);
}
bool FlocIdProviderImpl::AreThirdPartyCookiesAllowed() const {
return !cookie_settings_->ShouldBlockThirdPartyCookies();
}
void FlocIdProviderImpl::IsSwaaNacAccountEnabled(
CanComputeFlocCallback callback) {
if (!last_swaa_nac_account_enabled_query_time_.is_null() &&
last_swaa_nac_account_enabled_query_time_ +
kSwaaNacAccountEnabledCachePeriod >
base::TimeTicks::Now()) {
std::move(callback).Run(cached_swaa_nac_account_enabled_);
return;
}
net::PartialNetworkTrafficAnnotationTag partial_traffic_annotation =
net::DefinePartialNetworkTrafficAnnotation(
"floc_id_provider_impl", "floc_remote_permission_service",
R"(
semantics {
description:
"Queries google to find out if user has enabled 'web and app "
"activity' and 'ad personalization', and if the account type is "
"NOT a child account. Those permission bits will be checked before "
"computing the FLoC (Federated Learning of Cohorts) ID - an "
"anonymous similarity hash value of user’s navigation history. "
"This ensures that the FLoC ID is derived from data that Google "
"already owns and the user has explicitly granted permission on "
"what they will be used for."
trigger:
"This request is sent at each time a FLoC (Federated Learning of "
"Cohorts) ID is to be computed. A FLoC ID is an anonymous "
"similarity hash value of user’s navigation history. It'll be "
"computed at the start of each browser profile session and will be "
"refreshed every 24 hours during that session."
data:
"Google credentials if user is signed in."
}
policy {
setting:
"This feature cannot be disabled in settings, but disabling sync "
"or third-party cookies will prevent it."
})");
floc_remote_permission_service_->QueryFlocPermission(
base::BindOnce(&FlocIdProviderImpl::OnCheckSwaaNacAccountEnabledCompleted,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
partial_traffic_annotation);
}
void FlocIdProviderImpl::OnCheckSwaaNacAccountEnabledCompleted( void FlocIdProviderImpl::OnCheckSwaaNacAccountEnabledCompleted(
CanComputeFlocCallback callback, CanComputeFlocCallback callback,
bool enabled) { bool enabled) {
...@@ -336,11 +351,22 @@ void FlocIdProviderImpl::OnGetRecentlyVisitedURLsCompleted( ...@@ -336,11 +351,22 @@ void FlocIdProviderImpl::OnGetRecentlyVisitedURLsCompleted(
? FlocId::CreateFromHistory(domains) ? FlocId::CreateFromHistory(domains)
: FlocId(); : FlocId();
if (floc_id.IsValid() && ApplyAdditionalFiltering(std::move(callback), floc_id);
base::FeatureList::IsEnabled(features::kFlocIdBlocklistFiltering) && }
void FlocIdProviderImpl::ApplyAdditionalFiltering(
ComputeFlocCompletedCallback callback,
const FlocId& floc_id) {
if (!floc_id.IsValid()) {
std::move(callback).Run(floc_id);
return;
}
if (base::FeatureList::IsEnabled(features::kFlocIdBlocklistFiltering) &&
g_browser_process->floc_blocklist_service()->ShouldBlockFloc( g_browser_process->floc_blocklist_service()->ShouldBlockFloc(
floc_id.ToUint64())) { floc_id.ToUint64())) {
floc_id = FlocId(); std::move(callback).Run(FlocId());
return;
} }
std::move(callback).Run(floc_id); std::move(callback).Run(floc_id);
......
...@@ -75,10 +75,9 @@ class FlocIdProviderImpl : public FlocIdProvider, ...@@ -75,10 +75,9 @@ class FlocIdProviderImpl : public FlocIdProvider,
protected: protected:
// protected virtual for testing. // protected virtual for testing.
virtual void OnComputeFlocCompleted(ComputeFlocTrigger trigger,
FlocId floc_id);
virtual void NotifyFlocUpdated(ComputeFlocTrigger trigger); virtual void NotifyFlocUpdated(ComputeFlocTrigger trigger);
virtual bool IsSyncHistoryEnabled() const;
virtual bool AreThirdPartyCookiesAllowed() const;
virtual void IsSwaaNacAccountEnabled(CanComputeFlocCallback callback);
private: private:
friend class FlocIdProviderUnitTest; friend class FlocIdProviderUnitTest;
...@@ -102,13 +101,18 @@ class FlocIdProviderImpl : public FlocIdProvider, ...@@ -102,13 +101,18 @@ class FlocIdProviderImpl : public FlocIdProvider,
void MaybeTriggerFirstFlocComputation(); void MaybeTriggerFirstFlocComputation();
void OnComputeFlocScheduledUpdate();
void ComputeFloc(ComputeFlocTrigger trigger); void ComputeFloc(ComputeFlocTrigger trigger);
void OnComputeFlocCompleted(ComputeFlocTrigger trigger, FlocId floc_id);
void CheckCanComputeFloc(CanComputeFlocCallback callback); void CheckCanComputeFloc(CanComputeFlocCallback callback);
void OnCheckCanComputeFlocCompleted(ComputeFlocCompletedCallback callback, void OnCheckCanComputeFlocCompleted(ComputeFlocCompletedCallback callback,
bool can_compute_floc); bool can_compute_floc);
bool IsSyncHistoryEnabled() const;
bool AreThirdPartyCookiesAllowed() const;
void IsSwaaNacAccountEnabled(CanComputeFlocCallback callback);
void OnCheckSwaaNacAccountEnabledCompleted(CanComputeFlocCallback callback, void OnCheckSwaaNacAccountEnabledCompleted(CanComputeFlocCallback callback,
bool enabled); bool enabled);
...@@ -116,10 +120,20 @@ class FlocIdProviderImpl : public FlocIdProvider, ...@@ -116,10 +120,20 @@ class FlocIdProviderImpl : public FlocIdProvider,
void OnGetRecentlyVisitedURLsCompleted(ComputeFlocCompletedCallback callback, void OnGetRecentlyVisitedURLsCompleted(ComputeFlocCompletedCallback callback,
history::QueryResults results); history::QueryResults results);
// Apply any additional filtering or transformation on a floc computed from
// history. For example, invalidate it if it's in the blocklist.
void ApplyAdditionalFiltering(ComputeFlocCompletedCallback callback,
const FlocId& floc_id);
FlocId floc_id_; FlocId floc_id_;
bool floc_computation_in_progress_ = false; bool floc_computation_in_progress_ = false;
bool first_floc_computation_triggered_ = false; bool first_floc_computation_triggered_ = false;
// We store a pending event if it arrives during an in-progress computation.
// When the in-progress one finishes, we would disregard the result (no
// loggings, updates, etc.), and compute again.
base::Optional<ComputeFlocTrigger> pending_recompute_event_;
bool first_blocklist_loaded_seen_ = false; bool first_blocklist_loaded_seen_ = false;
bool first_sync_history_enabled_seen_ = false; bool first_sync_history_enabled_seen_ = false;
......
...@@ -30,6 +30,8 @@ namespace federated_learning { ...@@ -30,6 +30,8 @@ namespace federated_learning {
namespace { namespace {
using ComputeFlocTrigger = FlocIdProviderImpl::ComputeFlocTrigger;
class FakeFlocRemotePermissionService : public FlocRemotePermissionService { class FakeFlocRemotePermissionService : public FlocRemotePermissionService {
public: public:
using FlocRemotePermissionService::FlocRemotePermissionService; using FlocRemotePermissionService::FlocRemotePermissionService;
...@@ -85,18 +87,74 @@ class MockFlocIdProvider : public FlocIdProviderImpl { ...@@ -85,18 +87,74 @@ class MockFlocIdProvider : public FlocIdProviderImpl {
public: public:
using FlocIdProviderImpl::FlocIdProviderImpl; using FlocIdProviderImpl::FlocIdProviderImpl;
void NotifyFlocUpdated( void OnComputeFlocCompleted(ComputeFlocTrigger trigger,
FlocIdProviderImpl::ComputeFlocTrigger trigger) override { FlocId floc_id) override {
if (should_pause_before_compute_floc_completed_) {
DCHECK(!paused_);
paused_ = true;
paused_trigger_ = trigger;
paused_floc_id_ = floc_id;
return;
}
++compute_floc_completed_count_;
FlocIdProviderImpl::OnComputeFlocCompleted(trigger, floc_id);
}
void ContinueLastOnComputeFlocCompleted() {
DCHECK(paused_);
paused_ = false;
++compute_floc_completed_count_;
FlocIdProviderImpl::OnComputeFlocCompleted(paused_trigger_,
paused_floc_id_);
}
void NotifyFlocUpdated(ComputeFlocTrigger trigger) override {
++floc_update_notification_count_; ++floc_update_notification_count_;
last_notification_trigger_ = trigger;
FlocIdProviderImpl::NotifyFlocUpdated(trigger); FlocIdProviderImpl::NotifyFlocUpdated(trigger);
} }
size_t compute_floc_completed_count() const {
return compute_floc_completed_count_;
}
size_t floc_update_notification_count() const { size_t floc_update_notification_count() const {
return floc_update_notification_count_; return floc_update_notification_count_;
} }
void set_should_pause_before_compute_floc_completed(bool should_pause) {
should_pause_before_compute_floc_completed_ = should_pause;
}
FlocId paused_floc_id() const {
DCHECK(paused_);
return paused_floc_id_;
}
ComputeFlocTrigger paused_trigger() const {
DCHECK(paused_);
return paused_trigger_;
}
ComputeFlocTrigger last_notification_trigger() const {
DCHECK_LT(0u, floc_update_notification_count_);
return last_notification_trigger_;
}
private: private:
base::OnceCallback<void()> callback_before_compute_floc_completed_;
// Add the support to be able to pause on the OnComputeFlocCompleted
// execution and let it yield to other tasks posted to the same task runner.
bool should_pause_before_compute_floc_completed_ = false;
bool paused_ = false;
ComputeFlocTrigger paused_trigger_;
FlocId paused_floc_id_;
size_t compute_floc_completed_count_ = 0u;
size_t floc_update_notification_count_ = 0u; size_t floc_update_notification_count_ = 0u;
ComputeFlocTrigger last_notification_trigger_;
}; };
} // namespace } // namespace
...@@ -109,7 +167,7 @@ class FlocIdProviderUnitTest : public testing::Test { ...@@ -109,7 +167,7 @@ class FlocIdProviderUnitTest : public testing::Test {
~FlocIdProviderUnitTest() override = default; ~FlocIdProviderUnitTest() override = default;
void SetUp() override { void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
content_settings::ContentSettingsRegistry::GetInstance()->ResetForTest(); content_settings::ContentSettingsRegistry::GetInstance()->ResetForTest();
content_settings::CookieSettings::RegisterProfilePrefs(prefs_.registry()); content_settings::CookieSettings::RegisterProfilePrefs(prefs_.registry());
...@@ -166,8 +224,7 @@ class FlocIdProviderUnitTest : public testing::Test { ...@@ -166,8 +224,7 @@ class FlocIdProviderUnitTest : public testing::Test {
floc_id_provider_->OnURLsDeleted(history_service, deletion_info); floc_id_provider_->OnURLsDeleted(history_service, deletion_info);
} }
void OnGetRecentlyVisitedURLsCompleted( void OnGetRecentlyVisitedURLsCompleted(ComputeFlocTrigger trigger,
FlocIdProviderImpl::ComputeFlocTrigger trigger,
history::QueryResults results) { history::QueryResults results) {
auto compute_floc_completed_callback = auto compute_floc_completed_callback =
base::BindOnce(&FlocIdProviderImpl::OnComputeFlocCompleted, base::BindOnce(&FlocIdProviderImpl::OnComputeFlocCompleted,
...@@ -178,11 +235,10 @@ class FlocIdProviderUnitTest : public testing::Test { ...@@ -178,11 +235,10 @@ class FlocIdProviderUnitTest : public testing::Test {
} }
void ExpireHistoryBefore(base::Time end_time) { void ExpireHistoryBefore(base::Time end_time) {
base::RunLoop run_loop;
base::CancelableTaskTracker tracker; base::CancelableTaskTracker tracker;
base::RunLoop run_loop;
history_service_->ExpireHistoryBeforeForTesting( history_service_->ExpireHistoryBeforeForTesting(
end_time, base::BindLambdaForTesting([&]() { run_loop.Quit(); }), end_time, run_loop.QuitClosure(), &tracker);
&tracker);
run_loop.Run(); run_loop.Run();
} }
...@@ -213,10 +269,18 @@ class FlocIdProviderUnitTest : public testing::Test { ...@@ -213,10 +269,18 @@ class FlocIdProviderUnitTest : public testing::Test {
floc_id_provider_->floc_id_ = floc_id; floc_id_provider_->floc_id_ = floc_id;
} }
base::Optional<ComputeFlocTrigger> pending_recompute_event() {
return floc_id_provider_->pending_recompute_event_;
}
void SetRemoteSwaaNacAccountEnabled(bool enabled) { void SetRemoteSwaaNacAccountEnabled(bool enabled) {
fake_floc_remote_permission_service_->set_swaa_nac_account_enabled(enabled); fake_floc_remote_permission_service_->set_swaa_nac_account_enabled(enabled);
} }
void ForceScheduledUpdate() {
floc_id_provider_->OnComputeFlocScheduledUpdate();
}
void OnBlocklistLoaded(const std::unordered_set<uint64_t>& blocklist) { void OnBlocklistLoaded(const std::unordered_set<uint64_t>& blocklist) {
g_browser_process->floc_blocklist_service()->OnBlocklistLoadResult( g_browser_process->floc_blocklist_service()->OnBlocklistLoadResult(
blocklist); blocklist);
...@@ -255,9 +319,10 @@ TEST_F(FlocIdProviderUnitTest, QualifiedInitialHistory) { ...@@ -255,9 +319,10 @@ TEST_F(FlocIdProviderUnitTest, QualifiedInitialHistory) {
// Expect that the floc computation hasn't started, as the floc_id_provider // Expect that the floc computation hasn't started, as the floc_id_provider
// hasn't been notified about state of the sync_service. // hasn't been notified about state of the sync_service.
ASSERT_EQ(0u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(0u, floc_id_provider_->compute_floc_completed_count());
ASSERT_FALSE(floc_id().IsValid()); EXPECT_EQ(0u, floc_id_provider_->floc_update_notification_count());
ASSERT_FALSE(first_floc_computation_triggered()); EXPECT_FALSE(floc_id().IsValid());
EXPECT_FALSE(first_floc_computation_triggered());
// Trigger the 1st floc computation. // Trigger the 1st floc computation.
test_sync_service_->SetTransportState( test_sync_service_->SetTransportState(
...@@ -267,18 +332,19 @@ TEST_F(FlocIdProviderUnitTest, QualifiedInitialHistory) { ...@@ -267,18 +332,19 @@ TEST_F(FlocIdProviderUnitTest, QualifiedInitialHistory) {
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
// Expect a floc id update notification. // Expect a floc id update notification.
ASSERT_EQ(1u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
ASSERT_TRUE(floc_id().IsValid()); EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
ASSERT_EQ(FlocId::CreateFromHistory({domain}).ToDebugHeaderValue(), EXPECT_TRUE(floc_id().IsValid());
floc_id().ToDebugHeaderValue()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id());
ASSERT_TRUE(first_floc_computation_triggered()); EXPECT_TRUE(first_floc_computation_triggered());
// Advance the clock by 1 day. Expect a floc id update notification, as // Advance the clock by 1 day. Expect a floc id update notification, as
// there's no history in the last 7 days so the id has been reset to empty. // there's no history in the last 7 days so the id has been reset to empty.
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
ASSERT_EQ(2u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count());
ASSERT_FALSE(floc_id().IsValid()); EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count());
EXPECT_FALSE(floc_id().IsValid());
} }
TEST_F(FlocIdProviderUnitTest, UnqualifiedInitialHistory) { TEST_F(FlocIdProviderUnitTest, UnqualifiedInitialHistory) {
...@@ -295,9 +361,10 @@ TEST_F(FlocIdProviderUnitTest, UnqualifiedInitialHistory) { ...@@ -295,9 +361,10 @@ TEST_F(FlocIdProviderUnitTest, UnqualifiedInitialHistory) {
// Expect that the floc computation hasn't started, as the floc_id_provider // Expect that the floc computation hasn't started, as the floc_id_provider
// hasn't been notified about state of the sync_service. // hasn't been notified about state of the sync_service.
ASSERT_EQ(0u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(0u, floc_id_provider_->compute_floc_completed_count());
ASSERT_FALSE(floc_id().IsValid()); EXPECT_EQ(0u, floc_id_provider_->floc_update_notification_count());
ASSERT_FALSE(first_floc_computation_triggered()); EXPECT_FALSE(floc_id().IsValid());
EXPECT_FALSE(first_floc_computation_triggered());
// Trigger the 1st floc computation. // Trigger the 1st floc computation.
test_sync_service_->SetTransportState( test_sync_service_->SetTransportState(
...@@ -308,8 +375,9 @@ TEST_F(FlocIdProviderUnitTest, UnqualifiedInitialHistory) { ...@@ -308,8 +375,9 @@ TEST_F(FlocIdProviderUnitTest, UnqualifiedInitialHistory) {
// Expect no floc id update notification, as there is no qualified history // Expect no floc id update notification, as there is no qualified history
// entry. However, the 1st computation should already have started. // entry. However, the 1st computation should already have started.
ASSERT_EQ(0u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
ASSERT_TRUE(first_floc_computation_triggered()); EXPECT_EQ(0u, floc_id_provider_->floc_update_notification_count());
EXPECT_TRUE(first_floc_computation_triggered());
// Add a history entry with a timestamp 6 days back from now. // Add a history entry with a timestamp 6 days back from now.
add_page_args.time = base::Time::Now() - base::TimeDelta::FromDays(6); add_page_args.time = base::Time::Now() - base::TimeDelta::FromDays(6);
...@@ -319,17 +387,18 @@ TEST_F(FlocIdProviderUnitTest, UnqualifiedInitialHistory) { ...@@ -319,17 +387,18 @@ TEST_F(FlocIdProviderUnitTest, UnqualifiedInitialHistory) {
// as the id refresh interval is 24 hours. // as the id refresh interval is 24 hours.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(23)); task_environment_.FastForwardBy(base::TimeDelta::FromHours(23));
ASSERT_EQ(0u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
EXPECT_EQ(0u, floc_id_provider_->floc_update_notification_count());
// Advance the clock by 1 hour. Expect a floc id update notification, as the // Advance the clock by 1 hour. Expect a floc id update notification, as the
// refresh time is reached and there's a valid history entry in the last 7 // refresh time is reached and there's a valid history entry in the last 7
// days. // days.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1)); task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
ASSERT_EQ(1u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count());
ASSERT_TRUE(floc_id().IsValid()); EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
ASSERT_EQ(FlocId::CreateFromHistory({domain}).ToDebugHeaderValue(), EXPECT_TRUE(floc_id().IsValid());
floc_id().ToDebugHeaderValue()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id());
} }
TEST_F(FlocIdProviderUnitTest, HistoryDeleteAndScheduledUpdate) { TEST_F(FlocIdProviderUnitTest, HistoryDeleteAndScheduledUpdate) {
...@@ -358,14 +427,15 @@ TEST_F(FlocIdProviderUnitTest, HistoryDeleteAndScheduledUpdate) { ...@@ -358,14 +427,15 @@ TEST_F(FlocIdProviderUnitTest, HistoryDeleteAndScheduledUpdate) {
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
// Expect a floc id update notification. // Expect a floc id update notification.
ASSERT_EQ(1u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
ASSERT_TRUE(floc_id().IsValid()); EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
ASSERT_EQ(FlocId::CreateFromHistory({domain1, domain2}).ToDebugHeaderValue(), EXPECT_TRUE(floc_id().IsValid());
floc_id().ToDebugHeaderValue()); EXPECT_EQ(FlocId::CreateFromHistory({domain1, domain2}), floc_id());
// Advance the clock by 12 hours. Expect no floc id update notification. // Advance the clock by 12 hours. Expect no floc id update notification.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(12)); task_environment_.FastForwardBy(base::TimeDelta::FromHours(12));
ASSERT_EQ(1u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
// Expire the oldest history entry. // Expire the oldest history entry.
ExpireHistoryBefore(base::Time::Now() - base::TimeDelta::FromDays(7)); ExpireHistoryBefore(base::Time::Now() - base::TimeDelta::FromDays(7));
...@@ -373,22 +443,24 @@ TEST_F(FlocIdProviderUnitTest, HistoryDeleteAndScheduledUpdate) { ...@@ -373,22 +443,24 @@ TEST_F(FlocIdProviderUnitTest, HistoryDeleteAndScheduledUpdate) {
// Expect a floc id update notification as it was just recomputed due to the // Expect a floc id update notification as it was just recomputed due to the
// history deletion. // history deletion.
ASSERT_EQ(2u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count());
ASSERT_TRUE(floc_id().IsValid()); EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count());
ASSERT_EQ(FlocId::CreateFromHistory({domain2}).ToDebugHeaderValue(), EXPECT_TRUE(floc_id().IsValid());
floc_id().ToDebugHeaderValue()); EXPECT_EQ(FlocId::CreateFromHistory({domain2}), floc_id());
// Advance the clock by 23 hours. Expect no floc id update notification as the // Advance the clock by 23 hours. Expect no floc id update notification as the
// timer has been reset due to the recomputation from history deletion. // timer has been reset due to the recomputation from history deletion.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(23)); task_environment_.FastForwardBy(base::TimeDelta::FromHours(23));
ASSERT_EQ(2u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count());
EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count());
// Advance the clock by 1 hour. Expect an floc id update notification as the // Advance the clock by 1 hour. Expect an floc id update notification as the
// scheduled time is reached. Expect an invalid floc id as there is no history // scheduled time is reached. Expect an invalid floc id as there is no history
// in the past 7 days. // in the past 7 days.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1)); task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
ASSERT_EQ(3u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(3u, floc_id_provider_->compute_floc_completed_count());
ASSERT_FALSE(floc_id().IsValid()); EXPECT_EQ(3u, floc_id_provider_->floc_update_notification_count());
EXPECT_FALSE(floc_id().IsValid());
} }
TEST_F(FlocIdProviderUnitTest, ScheduledUpdateSameFloc_NoNotification) { TEST_F(FlocIdProviderUnitTest, ScheduledUpdateSameFloc_NoNotification) {
...@@ -411,13 +483,15 @@ TEST_F(FlocIdProviderUnitTest, ScheduledUpdateSameFloc_NoNotification) { ...@@ -411,13 +483,15 @@ TEST_F(FlocIdProviderUnitTest, ScheduledUpdateSameFloc_NoNotification) {
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
// Expect a floc id update notification. // Expect a floc id update notification.
ASSERT_EQ(1u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
// Advance the clock by 1 day. Expect no additional floc id update // Advance the clock by 1 day. Expect no additional floc id update
// notification, as the floc didn't change. // notification, as the floc didn't change.
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
ASSERT_EQ(1u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count());
EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
} }
TEST_F(FlocIdProviderUnitTest, CheckCanComputeFloc_Success) { TEST_F(FlocIdProviderUnitTest, CheckCanComputeFloc_Success) {
...@@ -425,7 +499,7 @@ TEST_F(FlocIdProviderUnitTest, CheckCanComputeFloc_Success) { ...@@ -425,7 +499,7 @@ TEST_F(FlocIdProviderUnitTest, CheckCanComputeFloc_Success) {
syncer::SyncService::TransportState::ACTIVE); syncer::SyncService::TransportState::ACTIVE);
base::OnceCallback<void(bool)> cb = base::BindOnce( base::OnceCallback<void(bool)> cb = base::BindOnce(
[](bool can_compute_floc) { ASSERT_TRUE(can_compute_floc); }); [](bool can_compute_floc) { EXPECT_TRUE(can_compute_floc); });
CheckCanComputeFloc(std::move(cb)); CheckCanComputeFloc(std::move(cb));
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
...@@ -433,7 +507,7 @@ TEST_F(FlocIdProviderUnitTest, CheckCanComputeFloc_Success) { ...@@ -433,7 +507,7 @@ TEST_F(FlocIdProviderUnitTest, CheckCanComputeFloc_Success) {
TEST_F(FlocIdProviderUnitTest, CheckCanComputeFloc_Failure_SyncDisabled) { TEST_F(FlocIdProviderUnitTest, CheckCanComputeFloc_Failure_SyncDisabled) {
base::OnceCallback<void(bool)> cb = base::BindOnce( base::OnceCallback<void(bool)> cb = base::BindOnce(
[](bool can_compute_floc) { ASSERT_FALSE(can_compute_floc); }); [](bool can_compute_floc) { EXPECT_FALSE(can_compute_floc); });
CheckCanComputeFloc(std::move(cb)); CheckCanComputeFloc(std::move(cb));
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
...@@ -447,7 +521,7 @@ TEST_F(FlocIdProviderUnitTest, ...@@ -447,7 +521,7 @@ TEST_F(FlocIdProviderUnitTest,
fake_cookie_settings_->set_should_block_third_party_cookies(true); fake_cookie_settings_->set_should_block_third_party_cookies(true);
base::OnceCallback<void(bool)> cb = base::BindOnce( base::OnceCallback<void(bool)> cb = base::BindOnce(
[](bool can_compute_floc) { ASSERT_FALSE(can_compute_floc); }); [](bool can_compute_floc) { EXPECT_FALSE(can_compute_floc); });
CheckCanComputeFloc(std::move(cb)); CheckCanComputeFloc(std::move(cb));
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
...@@ -461,7 +535,7 @@ TEST_F(FlocIdProviderUnitTest, ...@@ -461,7 +535,7 @@ TEST_F(FlocIdProviderUnitTest,
SetRemoteSwaaNacAccountEnabled(false); SetRemoteSwaaNacAccountEnabled(false);
base::OnceCallback<void(bool)> cb = base::BindOnce( base::OnceCallback<void(bool)> cb = base::BindOnce(
[](bool can_compute_floc) { ASSERT_FALSE(can_compute_floc); }); [](bool can_compute_floc) { EXPECT_FALSE(can_compute_floc); });
CheckCanComputeFloc(std::move(cb)); CheckCanComputeFloc(std::move(cb));
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
...@@ -469,7 +543,7 @@ TEST_F(FlocIdProviderUnitTest, ...@@ -469,7 +543,7 @@ TEST_F(FlocIdProviderUnitTest,
TEST_F(FlocIdProviderUnitTest, SwaaNacAccountEnabledUseCacheStatus) { TEST_F(FlocIdProviderUnitTest, SwaaNacAccountEnabledUseCacheStatus) {
base::OnceCallback<void(bool)> assert_enabled_callback_1 = base::BindOnce( base::OnceCallback<void(bool)> assert_enabled_callback_1 = base::BindOnce(
[](bool can_compute_floc) { ASSERT_TRUE(can_compute_floc); }); [](bool can_compute_floc) { EXPECT_TRUE(can_compute_floc); });
// The permission status in the fake_floc_remote_premission_service_ is by // The permission status in the fake_floc_remote_premission_service_ is by
// default enabled. // default enabled.
...@@ -480,7 +554,7 @@ TEST_F(FlocIdProviderUnitTest, SwaaNacAccountEnabledUseCacheStatus) { ...@@ -480,7 +554,7 @@ TEST_F(FlocIdProviderUnitTest, SwaaNacAccountEnabledUseCacheStatus) {
SetRemoteSwaaNacAccountEnabled(false); SetRemoteSwaaNacAccountEnabled(false);
base::OnceCallback<void(bool)> assert_enabled_callback_2 = base::BindOnce( base::OnceCallback<void(bool)> assert_enabled_callback_2 = base::BindOnce(
[](bool can_compute_floc) { ASSERT_TRUE(can_compute_floc); }); [](bool can_compute_floc) { EXPECT_TRUE(can_compute_floc); });
// Fast forward by 11 hours. The cache is still valid. // Fast forward by 11 hours. The cache is still valid.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(11)); task_environment_.FastForwardBy(base::TimeDelta::FromHours(11));
...@@ -494,7 +568,7 @@ TEST_F(FlocIdProviderUnitTest, SwaaNacAccountEnabledUseCacheStatus) { ...@@ -494,7 +568,7 @@ TEST_F(FlocIdProviderUnitTest, SwaaNacAccountEnabledUseCacheStatus) {
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1)); task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
base::OnceCallback<void(bool)> assert_disabled_callback = base::BindOnce( base::OnceCallback<void(bool)> assert_disabled_callback = base::BindOnce(
[](bool can_compute_floc) { ASSERT_FALSE(can_compute_floc); }); [](bool can_compute_floc) { EXPECT_FALSE(can_compute_floc); });
// The permission status should be obtained from the server again, and it's // The permission status should be obtained from the server again, and it's
// now disabled. // now disabled.
...@@ -507,10 +581,9 @@ TEST_F(FlocIdProviderUnitTest, EventLogging) { ...@@ -507,10 +581,9 @@ TEST_F(FlocIdProviderUnitTest, EventLogging) {
feature_list.InitAndEnableFeature(features::kFlocIdComputedEventLogging); feature_list.InitAndEnableFeature(features::kFlocIdComputedEventLogging);
set_floc_id(FlocId(12345ULL)); set_floc_id(FlocId(12345ULL));
floc_id_provider_->NotifyFlocUpdated( floc_id_provider_->NotifyFlocUpdated(ComputeFlocTrigger::kBrowserStart);
FlocIdProviderImpl::ComputeFlocTrigger::kBrowserStart);
ASSERT_EQ(1u, fake_user_event_service_->GetRecordedUserEvents().size()); EXPECT_EQ(1u, fake_user_event_service_->GetRecordedUserEvents().size());
const sync_pb::UserEventSpecifics& specifics1 = const sync_pb::UserEventSpecifics& specifics1 =
fake_user_event_service_->GetRecordedUserEvents()[0]; fake_user_event_service_->GetRecordedUserEvents()[0];
EXPECT_EQ(specifics1.event_time_usec(), EXPECT_EQ(specifics1.event_time_usec(),
...@@ -528,10 +601,9 @@ TEST_F(FlocIdProviderUnitTest, EventLogging) { ...@@ -528,10 +601,9 @@ TEST_F(FlocIdProviderUnitTest, EventLogging) {
task_environment_.FastForwardBy(base::TimeDelta::FromDays(3)); task_environment_.FastForwardBy(base::TimeDelta::FromDays(3));
set_floc_id(FlocId(999ULL)); set_floc_id(FlocId(999ULL));
floc_id_provider_->NotifyFlocUpdated( floc_id_provider_->NotifyFlocUpdated(ComputeFlocTrigger::kScheduledUpdate);
FlocIdProviderImpl::ComputeFlocTrigger::kScheduledUpdate);
ASSERT_EQ(2u, fake_user_event_service_->GetRecordedUserEvents().size()); EXPECT_EQ(2u, fake_user_event_service_->GetRecordedUserEvents().size());
const sync_pb::UserEventSpecifics& specifics2 = const sync_pb::UserEventSpecifics& specifics2 =
fake_user_event_service_->GetRecordedUserEvents()[1]; fake_user_event_service_->GetRecordedUserEvents()[1];
EXPECT_EQ(specifics2.event_time_usec(), EXPECT_EQ(specifics2.event_time_usec(),
...@@ -546,10 +618,9 @@ TEST_F(FlocIdProviderUnitTest, EventLogging) { ...@@ -546,10 +618,9 @@ TEST_F(FlocIdProviderUnitTest, EventLogging) {
EXPECT_EQ(999ULL, event2.floc_id()); EXPECT_EQ(999ULL, event2.floc_id());
set_floc_id(FlocId()); set_floc_id(FlocId());
floc_id_provider_->NotifyFlocUpdated( floc_id_provider_->NotifyFlocUpdated(ComputeFlocTrigger::kScheduledUpdate);
FlocIdProviderImpl::ComputeFlocTrigger::kScheduledUpdate);
ASSERT_EQ(3u, fake_user_event_service_->GetRecordedUserEvents().size()); EXPECT_EQ(3u, fake_user_event_service_->GetRecordedUserEvents().size());
const sync_pb::UserEventSpecifics& specifics3 = const sync_pb::UserEventSpecifics& specifics3 =
fake_user_event_service_->GetRecordedUserEvents()[2]; fake_user_event_service_->GetRecordedUserEvents()[2];
EXPECT_EQ(specifics3.event_time_usec(), EXPECT_EQ(specifics3.event_time_usec(),
...@@ -564,10 +635,9 @@ TEST_F(FlocIdProviderUnitTest, EventLogging) { ...@@ -564,10 +635,9 @@ TEST_F(FlocIdProviderUnitTest, EventLogging) {
EXPECT_FALSE(event3.has_floc_id()); EXPECT_FALSE(event3.has_floc_id());
set_floc_id(FlocId(555)); set_floc_id(FlocId(555));
floc_id_provider_->NotifyFlocUpdated( floc_id_provider_->NotifyFlocUpdated(ComputeFlocTrigger::kHistoryDelete);
FlocIdProviderImpl::ComputeFlocTrigger::kHistoryDelete);
ASSERT_EQ(4u, fake_user_event_service_->GetRecordedUserEvents().size()); EXPECT_EQ(4u, fake_user_event_service_->GetRecordedUserEvents().size());
const sync_pb::UserEventSpecifics& specifics4 = const sync_pb::UserEventSpecifics& specifics4 =
fake_user_event_service_->GetRecordedUserEvents()[3]; fake_user_event_service_->GetRecordedUserEvents()[3];
EXPECT_EQ(specifics4.event_time_usec(), EXPECT_EQ(specifics4.event_time_usec(),
...@@ -594,13 +664,13 @@ TEST_F(FlocIdProviderUnitTest, HistoryDelete_AllHistory) { ...@@ -594,13 +664,13 @@ TEST_F(FlocIdProviderUnitTest, HistoryDelete_AllHistory) {
set_first_floc_computation_triggered(true); set_first_floc_computation_triggered(true);
set_floc_computation_in_progress(true); set_floc_computation_in_progress(true);
OnGetRecentlyVisitedURLsCompleted( OnGetRecentlyVisitedURLsCompleted(ComputeFlocTrigger::kBrowserStart,
FlocIdProviderImpl::ComputeFlocTrigger::kBrowserStart,
std::move(query_results)); std::move(query_results));
ASSERT_TRUE(floc_id().IsValid()); EXPECT_FALSE(floc_computation_in_progress());
EXPECT_TRUE(floc_id().IsValid());
OnURLsDeleted(history_service_.get(), history::DeletionInfo::ForAllHistory()); OnURLsDeleted(history_service_.get(), history::DeletionInfo::ForAllHistory());
ASSERT_FALSE(floc_id().IsValid()); EXPECT_FALSE(floc_id().IsValid());
} }
TEST_F(FlocIdProviderUnitTest, HistoryDelete_InvalidTimeRange) { TEST_F(FlocIdProviderUnitTest, HistoryDelete_InvalidTimeRange) {
...@@ -617,16 +687,16 @@ TEST_F(FlocIdProviderUnitTest, HistoryDelete_InvalidTimeRange) { ...@@ -617,16 +687,16 @@ TEST_F(FlocIdProviderUnitTest, HistoryDelete_InvalidTimeRange) {
set_first_floc_computation_triggered(true); set_first_floc_computation_triggered(true);
set_floc_computation_in_progress(true); set_floc_computation_in_progress(true);
OnGetRecentlyVisitedURLsCompleted( OnGetRecentlyVisitedURLsCompleted(ComputeFlocTrigger::kBrowserStart,
FlocIdProviderImpl::ComputeFlocTrigger::kBrowserStart,
std::move(query_results)); std::move(query_results));
ASSERT_TRUE(floc_id().IsValid()); EXPECT_FALSE(floc_computation_in_progress());
EXPECT_TRUE(floc_id().IsValid());
OnURLsDeleted(history_service_.get(), OnURLsDeleted(history_service_.get(),
history::DeletionInfo::ForUrls( history::DeletionInfo::ForUrls(
{history::URLResult(url_a, base::Time())}, {})); {history::URLResult(url_a, base::Time())}, {}));
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
ASSERT_FALSE(floc_id().IsValid()); EXPECT_FALSE(floc_id().IsValid());
} }
TEST_F(FlocIdProviderUnitTest, HistoryDelete_TimeRange) { TEST_F(FlocIdProviderUnitTest, HistoryDelete_TimeRange) {
...@@ -641,10 +711,10 @@ TEST_F(FlocIdProviderUnitTest, HistoryDelete_TimeRange) { ...@@ -641,10 +711,10 @@ TEST_F(FlocIdProviderUnitTest, HistoryDelete_TimeRange) {
set_first_floc_computation_triggered(true); set_first_floc_computation_triggered(true);
set_floc_computation_in_progress(true); set_floc_computation_in_progress(true);
OnGetRecentlyVisitedURLsCompleted( OnGetRecentlyVisitedURLsCompleted(ComputeFlocTrigger::kBrowserStart,
FlocIdProviderImpl::ComputeFlocTrigger::kBrowserStart,
std::move(query_results)); std::move(query_results));
ASSERT_TRUE(floc_id().IsValid()); EXPECT_FALSE(floc_computation_in_progress());
EXPECT_TRUE(floc_id().IsValid());
history::DeletionInfo deletion_info(history::DeletionTimeRange(time, time), history::DeletionInfo deletion_info(history::DeletionTimeRange(time, time),
false, {}, {}, false, {}, {},
...@@ -652,7 +722,7 @@ TEST_F(FlocIdProviderUnitTest, HistoryDelete_TimeRange) { ...@@ -652,7 +722,7 @@ TEST_F(FlocIdProviderUnitTest, HistoryDelete_TimeRange) {
OnURLsDeleted(history_service_.get(), deletion_info); OnURLsDeleted(history_service_.get(), deletion_info);
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
ASSERT_FALSE(floc_id().IsValid()); EXPECT_FALSE(floc_id().IsValid());
} }
TEST_F(FlocIdProviderUnitTest, HistoryEntriesWithPrivateIP) { TEST_F(FlocIdProviderUnitTest, HistoryEntriesWithPrivateIP) {
...@@ -664,11 +734,10 @@ TEST_F(FlocIdProviderUnitTest, HistoryEntriesWithPrivateIP) { ...@@ -664,11 +734,10 @@ TEST_F(FlocIdProviderUnitTest, HistoryEntriesWithPrivateIP) {
set_first_floc_computation_triggered(true); set_first_floc_computation_triggered(true);
set_floc_computation_in_progress(true); set_floc_computation_in_progress(true);
OnGetRecentlyVisitedURLsCompleted( OnGetRecentlyVisitedURLsCompleted(ComputeFlocTrigger::kBrowserStart,
FlocIdProviderImpl::ComputeFlocTrigger::kBrowserStart,
std::move(query_results)); std::move(query_results));
ASSERT_FALSE(floc_id().IsValid()); EXPECT_FALSE(floc_id().IsValid());
} }
TEST_F(FlocIdProviderUnitTest, MultipleHistoryEntries) { TEST_F(FlocIdProviderUnitTest, MultipleHistoryEntries) {
...@@ -691,13 +760,10 @@ TEST_F(FlocIdProviderUnitTest, MultipleHistoryEntries) { ...@@ -691,13 +760,10 @@ TEST_F(FlocIdProviderUnitTest, MultipleHistoryEntries) {
set_first_floc_computation_triggered(true); set_first_floc_computation_triggered(true);
set_floc_computation_in_progress(true); set_floc_computation_in_progress(true);
OnGetRecentlyVisitedURLsCompleted( OnGetRecentlyVisitedURLsCompleted(ComputeFlocTrigger::kBrowserStart,
FlocIdProviderImpl::ComputeFlocTrigger::kBrowserStart,
std::move(query_results)); std::move(query_results));
ASSERT_EQ( EXPECT_EQ(FlocId::CreateFromHistory({"a.test", "b.test"}), floc_id());
FlocId::CreateFromHistory({"a.test", "b.test"}).ToDebugHeaderValue(),
floc_id().ToDebugHeaderValue());
} }
TEST_F(FlocIdProviderUnitTest, TEST_F(FlocIdProviderUnitTest,
...@@ -769,9 +835,9 @@ TEST_F(FlocIdProviderUnitTest, BlocklistFilteringEnabled_BlockedFloc) { ...@@ -769,9 +835,9 @@ TEST_F(FlocIdProviderUnitTest, BlocklistFilteringEnabled_BlockedFloc) {
// Expect a floc id update notification. The floc should be equal to the // Expect a floc id update notification. The floc should be equal to the
// sim-hash of the history. // sim-hash of the history.
ASSERT_EQ(1u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
ASSERT_EQ(FlocId::CreateFromHistory({domain}).ToDebugHeaderValue(), EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
floc_id().ToDebugHeaderValue()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id());
// Insert the current floc to blocklist and reload it. // Insert the current floc to blocklist and reload it.
blocklist.insert(FlocId::CreateFromHistory({domain}).ToUint64()); blocklist.insert(FlocId::CreateFromHistory({domain}).ToUint64());
...@@ -781,8 +847,9 @@ TEST_F(FlocIdProviderUnitTest, BlocklistFilteringEnabled_BlockedFloc) { ...@@ -781,8 +847,9 @@ TEST_F(FlocIdProviderUnitTest, BlocklistFilteringEnabled_BlockedFloc) {
// Expect a floc id update notification, with an invalid floc because was // Expect a floc id update notification, with an invalid floc because was
// blocked. // blocked.
ASSERT_EQ(2u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count());
ASSERT_EQ(FlocId().ToDebugHeaderValue(), floc_id().ToDebugHeaderValue()); EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count());
EXPECT_EQ(FlocId(), floc_id());
// Reset and reload the blocklist. // Reset and reload the blocklist.
blocklist.clear(); blocklist.clear();
...@@ -792,9 +859,9 @@ TEST_F(FlocIdProviderUnitTest, BlocklistFilteringEnabled_BlockedFloc) { ...@@ -792,9 +859,9 @@ TEST_F(FlocIdProviderUnitTest, BlocklistFilteringEnabled_BlockedFloc) {
// Expect a floc id update notification. The floc should be equal to the // Expect a floc id update notification. The floc should be equal to the
// sim-hash of the history. // sim-hash of the history.
ASSERT_EQ(3u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(3u, floc_id_provider_->compute_floc_completed_count());
ASSERT_EQ(FlocId::CreateFromHistory({domain}).ToDebugHeaderValue(), EXPECT_EQ(3u, floc_id_provider_->floc_update_notification_count());
floc_id().ToDebugHeaderValue()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id());
} }
TEST_F(FlocIdProviderUnitTest, TurnSyncOffAndOn) { TEST_F(FlocIdProviderUnitTest, TurnSyncOffAndOn) {
...@@ -816,9 +883,9 @@ TEST_F(FlocIdProviderUnitTest, TurnSyncOffAndOn) { ...@@ -816,9 +883,9 @@ TEST_F(FlocIdProviderUnitTest, TurnSyncOffAndOn) {
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
// Expect a floc id update notification. // Expect a floc id update notification.
ASSERT_EQ(1u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
ASSERT_EQ(FlocId::CreateFromHistory({domain}).ToDebugHeaderValue(), EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
floc_id().ToDebugHeaderValue()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id());
// Turn off sync. // Turn off sync.
test_sync_service_->SetTransportState( test_sync_service_->SetTransportState(
...@@ -828,8 +895,9 @@ TEST_F(FlocIdProviderUnitTest, TurnSyncOffAndOn) { ...@@ -828,8 +895,9 @@ TEST_F(FlocIdProviderUnitTest, TurnSyncOffAndOn) {
// the sync was turned off so the id has been reset to empty. // the sync was turned off so the id has been reset to empty.
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
ASSERT_EQ(2u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count());
ASSERT_FALSE(floc_id().IsValid()); EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count());
EXPECT_FALSE(floc_id().IsValid());
// Turn on sync. // Turn on sync.
test_sync_service_->SetTransportState( test_sync_service_->SetTransportState(
...@@ -839,9 +907,9 @@ TEST_F(FlocIdProviderUnitTest, TurnSyncOffAndOn) { ...@@ -839,9 +907,9 @@ TEST_F(FlocIdProviderUnitTest, TurnSyncOffAndOn) {
// valid floc id. // valid floc id.
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
ASSERT_EQ(3u, floc_id_provider_->floc_update_notification_count()); EXPECT_EQ(3u, floc_id_provider_->compute_floc_completed_count());
ASSERT_EQ(FlocId::CreateFromHistory({domain}).ToDebugHeaderValue(), EXPECT_EQ(3u, floc_id_provider_->floc_update_notification_count());
floc_id().ToDebugHeaderValue()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id());
} }
TEST_F(FlocIdProviderUnitTest, GetInterestCohortForJsApiMethod) { TEST_F(FlocIdProviderUnitTest, GetInterestCohortForJsApiMethod) {
...@@ -898,4 +966,114 @@ TEST_F(FlocIdProviderUnitTest, ...@@ -898,4 +966,114 @@ TEST_F(FlocIdProviderUnitTest,
/*requesting_origin=*/{}, /*site_for_cookies=*/{})); /*requesting_origin=*/{}, /*site_for_cookies=*/{}));
} }
TEST_F(FlocIdProviderUnitTest, HistoryDeleteDuringInProgressComputation) {
std::string domain1 = "foo.com";
std::string domain2 = "bar.com";
std::string domain3 = "baz.com";
// Add a history entry with a timestamp exactly 7 days back from now.
history::HistoryAddPageArgs add_page_args;
add_page_args.url = GURL(base::StrCat({"https://www.", domain1}));
add_page_args.time = base::Time::Now() - base::TimeDelta::FromDays(7);
add_page_args.publicly_routable = true;
history_service_->AddPage(add_page_args);
// Add a history entry with a timestamp exactly 6 days back from now.
add_page_args.url = GURL(base::StrCat({"https://www.", domain2}));
add_page_args.time = base::Time::Now() - base::TimeDelta::FromDays(6);
history_service_->AddPage(add_page_args);
// Add a history entry with a timestamp exactly 5 days back from now.
add_page_args.url = GURL(base::StrCat({"https://www.", domain3}));
add_page_args.time = base::Time::Now() - base::TimeDelta::FromDays(5);
history_service_->AddPage(add_page_args);
// Trigger the 1st floc computation.
test_sync_service_->SetTransportState(
syncer::SyncService::TransportState::ACTIVE);
test_sync_service_->FireStateChanged();
task_environment_.RunUntilIdle();
// Expect a floc id update notification.
EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
EXPECT_TRUE(floc_id().IsValid());
EXPECT_EQ(FlocId::CreateFromHistory({domain1, domain2, domain3}), floc_id());
// Advance the clock by 1 day. The "domain1" should expire. However, we pause
// before the computation completes.
floc_id_provider_->set_should_pause_before_compute_floc_completed(true);
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
EXPECT_TRUE(floc_computation_in_progress());
EXPECT_FALSE(pending_recompute_event().has_value());
EXPECT_EQ(FlocId::CreateFromHistory({domain1, domain2, domain3}), floc_id());
EXPECT_EQ(FlocId::CreateFromHistory({domain2, domain3}),
floc_id_provider_->paused_floc_id());
EXPECT_EQ(ComputeFlocTrigger::kScheduledUpdate,
floc_id_provider_->paused_trigger());
// Expire the "domain2" history entry right before the floc computation
// completes. Since the computation is still considered to be
// in-progress, a new recompute event due to this delete will be
// scheduled to happen right after this computation completes.
ExpireHistoryBefore(base::Time::Now() - base::TimeDelta::FromDays(7));
EXPECT_TRUE(pending_recompute_event().has_value());
EXPECT_EQ(ComputeFlocTrigger::kHistoryDelete,
pending_recompute_event().value());
floc_id_provider_->set_should_pause_before_compute_floc_completed(false);
floc_id_provider_->ContinueLastOnComputeFlocCompleted();
task_environment_.RunUntilIdle();
// Expect 2 more compute completion events and 1 more update notification.
// This is because we won't send update notification if there's a recompute
// event scheduled.
EXPECT_EQ(3u, floc_id_provider_->compute_floc_completed_count());
EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count());
EXPECT_EQ(ComputeFlocTrigger::kHistoryDelete,
floc_id_provider_->last_notification_trigger());
EXPECT_FALSE(pending_recompute_event().has_value());
// The final floc should be derived from "domain3".
EXPECT_TRUE(floc_id().IsValid());
EXPECT_EQ(FlocId::CreateFromHistory({domain3}), floc_id());
}
TEST_F(FlocIdProviderUnitTest, ScheduledUpdateDuringInProgressComputation) {
std::string domain1 = "foo.com";
std::string domain2 = "bar.com";
std::string domain3 = "baz.com";
// Add a history entry with a timestamp exactly 7 days back from now.
history::HistoryAddPageArgs add_page_args;
add_page_args.url = GURL(base::StrCat({"https://www.", domain1}));
add_page_args.time = base::Time::Now() - base::TimeDelta::FromDays(7);
add_page_args.publicly_routable = true;
history_service_->AddPage(add_page_args);
// Trigger the 1st floc computation.
test_sync_service_->SetTransportState(
syncer::SyncService::TransportState::ACTIVE);
test_sync_service_->FireStateChanged();
EXPECT_TRUE(floc_computation_in_progress());
EXPECT_FALSE(pending_recompute_event().has_value());
// Scheduled update during an in-progress computation won't set the pending
// event.
ForceScheduledUpdate();
EXPECT_FALSE(pending_recompute_event().has_value());
task_environment_.RunUntilIdle();
// Expect a floc id update notification.
EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count());
EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count());
EXPECT_TRUE(floc_id().IsValid());
EXPECT_EQ(FlocId::CreateFromHistory({domain1}), floc_id());
}
} // namespace federated_learning } // namespace federated_learning
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment