blob: 902c38567b3661b964e4bf74302d465cb6bf2d54 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/federated_learning/floc_event_logger.h"
#include "base/strings/strcat.h"
#include "base/test/bind.h"
#include "build/build_config.h"
#include "chrome/browser/federated_learning/floc_remote_permission_service.h"
#include "chrome/test/base/testing_browser_process.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/federated_learning/features/features.h"
#include "components/sync/driver/test_sync_service.h"
#include "components/sync_user_events/fake_user_event_service.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace federated_learning {
class FakeFlocRemotePermissionService : public FlocRemotePermissionService {
public:
using FlocRemotePermissionService::FlocRemotePermissionService;
void QueryFlocPermission(QueryFlocPermissionCallback callback,
const net::PartialNetworkTrafficAnnotationTag&
partial_traffic_annotation) override {
++number_of_permission_queries_;
std::move(callback).Run(swaa_nac_account_enabled_);
}
size_t number_of_permission_queries() const {
return number_of_permission_queries_;
}
void set_swaa_nac_account_enabled(bool enabled) {
swaa_nac_account_enabled_ = enabled;
}
private:
size_t number_of_permission_queries_ = 0;
bool swaa_nac_account_enabled_ = true;
};
class FlocEventLoggerUnitTest : public testing::Test {
public:
FlocEventLoggerUnitTest()
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
FlocEventLoggerUnitTest(const FlocEventLoggerUnitTest&) = delete;
FlocEventLoggerUnitTest& operator=(const FlocEventLoggerUnitTest&) = delete;
~FlocEventLoggerUnitTest() override = default;
void SetUp() override {
test_sync_service_ = std::make_unique<syncer::TestSyncService>();
test_sync_service_->SetTransportState(
syncer::SyncService::TransportState::DISABLED);
fake_user_event_service_ = std::make_unique<syncer::FakeUserEventService>();
fake_floc_remote_permission_service_ =
std::make_unique<FakeFlocRemotePermissionService>(
/*url_loader_factory=*/nullptr);
floc_event_logger_ = std::make_unique<FlocEventLogger>(
test_sync_service_.get(), fake_floc_remote_permission_service_.get(),
fake_user_event_service_.get());
}
void DisableSyncHistory() {
test_sync_service_->SetTransportState(
syncer::SyncService::TransportState::DISABLED);
test_sync_service_->FireStateChanged();
}
void EnableSyncHistory() {
test_sync_service_->SetTransportState(
syncer::SyncService::TransportState::ACTIVE);
test_sync_service_->FireStateChanged();
}
void SetRemoteSwaaNacAccountEnabled(bool enabled) {
fake_floc_remote_permission_service_->set_swaa_nac_account_enabled(enabled);
}
size_t GetNumberOfRemotePermissionQueries() {
return fake_floc_remote_permission_service_->number_of_permission_queries();
}
size_t GetLoggedEventSize() const {
return fake_user_event_service_->GetRecordedUserEvents().size();
}
FlocEventLogger::Event GetEventAtIndex(size_t i) {
CHECK_LT(i, fake_user_event_service_->GetRecordedUserEvents().size());
const sync_pb::UserEventSpecifics& specifics =
fake_user_event_service_->GetRecordedUserEvents()[i];
EXPECT_EQ(sync_pb::UserEventSpecifics::kFlocIdComputedEvent,
specifics.event_case());
const sync_pb::UserEventSpecifics_FlocIdComputed& e =
specifics.floc_id_computed_event();
return {e.has_floc_id(), e.has_floc_id() ? e.floc_id() : 0,
base::Time::FromDeltaSinceWindowsEpoch(
base::Microseconds(specifics.event_time_usec()))};
}
protected:
content::BrowserTaskEnvironment task_environment_;
std::unique_ptr<syncer::TestSyncService> test_sync_service_;
std::unique_ptr<syncer::FakeUserEventService> fake_user_event_service_;
std::unique_ptr<FakeFlocRemotePermissionService>
fake_floc_remote_permission_service_;
std::unique_ptr<FlocEventLogger> floc_event_logger_;
};
TEST_F(FlocEventLoggerUnitTest, DefaultSyncDisabled_EventLogging) {
// Expect no loggings as sync is disabled.
floc_event_logger_->LogFlocComputedEvent(
{true, 33, base::Time::FromTimeT(44)});
EXPECT_EQ(0u, GetLoggedEventSize());
// After 10 seconds, still no loggings.
task_environment_.FastForwardBy(base::Seconds(10));
EXPECT_EQ(0u, GetLoggedEventSize());
}
TEST_F(FlocEventLoggerUnitTest, SyncEnabledWithinTenSeconds) {
// Expect no loggings as sync is disabled.
floc_event_logger_->LogFlocComputedEvent(
{true, 33, base::Time::FromTimeT(44)});
EXPECT_EQ(0u, GetLoggedEventSize());
task_environment_.FastForwardBy(base::Seconds(9));
EnableSyncHistory();
EXPECT_EQ(0u, GetLoggedEventSize());
// After 10 seconds, expect a logging as the previous logging is attempted for
// the second time.
task_environment_.FastForwardBy(base::Seconds(1));
EXPECT_EQ(1u, GetLoggedEventSize());
EXPECT_EQ(1u, GetNumberOfRemotePermissionQueries());
EXPECT_EQ(true, GetEventAtIndex(0).sim_hash_computed);
EXPECT_EQ(33u, GetEventAtIndex(0).sim_hash);
EXPECT_EQ(base::Time::FromTimeT(44), GetEventAtIndex(0).time);
}
TEST_F(FlocEventLoggerUnitTest, SyncEnabledAfterTenSeconds) {
// Expect no loggings as sync is disabled.
floc_event_logger_->LogFlocComputedEvent(
{true, 33, base::Time::FromTimeT(44)});
EXPECT_EQ(0u, GetLoggedEventSize());
task_environment_.FastForwardBy(base::Seconds(11));
// If sync is enabled after 10 seconds after the logging time, the event won't
// be handled.
EnableSyncHistory();
task_environment_.FastForwardBy(base::Seconds(10000));
EXPECT_EQ(0u, GetLoggedEventSize());
}
TEST_F(FlocEventLoggerUnitTest, MultipleEventsBeforeSyncEnabled) {
floc_event_logger_->LogFlocComputedEvent(
{true, 33, base::Time::FromTimeT(44)});
task_environment_.FastForwardBy(base::Seconds(5));
floc_event_logger_->LogFlocComputedEvent(
{false, 999, base::Time::FromTimeT(55)});
EXPECT_EQ(0u, GetLoggedEventSize());
EnableSyncHistory();
task_environment_.FastForwardBy(base::Seconds(5));
// At time 10, the first event will be given its second attempt.
EXPECT_EQ(1u, GetLoggedEventSize());
EXPECT_EQ(1u, GetNumberOfRemotePermissionQueries());
EXPECT_EQ(true, GetEventAtIndex(0).sim_hash_computed);
EXPECT_EQ(33u, GetEventAtIndex(0).sim_hash);
EXPECT_EQ(base::Time::FromTimeT(44), GetEventAtIndex(0).time);
// At time 15, the second event will be given its second attempt.
// The sim_hash field of the 2nd event (i.e. 999) was ignored because the
// sim_hash_computed field is false.
task_environment_.FastForwardBy(base::Seconds(15));
EXPECT_EQ(2u, GetLoggedEventSize());
EXPECT_EQ(2u, GetNumberOfRemotePermissionQueries());
EXPECT_EQ(false, GetEventAtIndex(1).sim_hash_computed);
EXPECT_EQ(0u, GetEventAtIndex(1).sim_hash);
EXPECT_EQ(base::Time::FromTimeT(55), GetEventAtIndex(1).time);
}
// Sync-enabled followed by event logging.
TEST_F(FlocEventLoggerUnitTest, SyncEnabled_EventLogging) {
// When sync gets enabled first, following requests should succeed
// immediately.
EnableSyncHistory();
EXPECT_EQ(0u, GetLoggedEventSize());
// Log an event. Expect it to be logged immediately.
floc_event_logger_->LogFlocComputedEvent(
{true, 33, base::Time::FromTimeT(44)});
EXPECT_EQ(1u, GetLoggedEventSize());
EXPECT_EQ(true, GetEventAtIndex(0).sim_hash_computed);
EXPECT_EQ(33u, GetEventAtIndex(0).sim_hash);
EXPECT_EQ(base::Time::FromTimeT(44), GetEventAtIndex(0).time);
}
// Sync is enabled but remote permission is disabled, the request should also
// fail immediately.
TEST_F(FlocEventLoggerUnitTest,
SyncEnabled_RemotePermissionDisabled_EventLogging) {
EnableSyncHistory();
SetRemoteSwaaNacAccountEnabled(false);
// Log an event. Expect it to fail immediately, as if failed the remote
// permission check.
floc_event_logger_->LogFlocComputedEvent(
{true, 33, base::Time::FromTimeT(44)});
EXPECT_EQ(0u, GetLoggedEventSize());
SetRemoteSwaaNacAccountEnabled(true);
task_environment_.FastForwardBy(base::Seconds(10));
EXPECT_EQ(0u, GetLoggedEventSize());
}
} // namespace federated_learning