blob: 101c77e89958e4b52685902210aefc45878b850d [file] [log] [blame]
// Copyright 2019 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 "components/metrics/demographic_metrics_provider.h"
#include <memory>
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/time/time.h"
#include "components/metrics/metrics_log_uploader.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/base/user_demographics.h"
#include "components/sync/driver/test_sync_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
#include "third_party/metrics_proto/ukm/report.pb.h"
namespace metrics {
namespace {
// Profile client for testing that gets fake Profile information and services.
class TestProfileClient : public DemographicMetricsProvider::ProfileClient {
public:
~TestProfileClient() override = default;
TestProfileClient(std::unique_ptr<syncer::SyncService> sync_service,
int number_of_profiles)
: sync_service_(std::move(sync_service)),
number_of_profiles_(number_of_profiles) {}
int GetNumberOfProfilesOnDisk() override { return number_of_profiles_; }
syncer::SyncService* GetSyncService() override { return sync_service_.get(); }
base::Time GetNetworkTime() const override {
base::Time time;
auto result = base::Time::FromString("17 Jun 2019 00:00:00 UDT", &time);
DCHECK(result);
return time;
}
private:
std::unique_ptr<syncer::SyncService> sync_service_;
const int number_of_profiles_;
base::SimpleTestClock clock_;
DISALLOW_COPY_AND_ASSIGN(TestProfileClient);
};
// Make arbitrary user demographics to provide.
syncer::UserDemographicsResult GetDemographics() {
syncer::UserDemographics user_demographics;
user_demographics.birth_year = 1983;
user_demographics.gender = UserDemographicsProto::GENDER_FEMALE;
return syncer::UserDemographicsResult::ForValue(std::move(user_demographics));
}
std::unique_ptr<TestProfileClient> MakeTestProfileClient(
const syncer::UserDemographicsResult& user_demographics_result,
int number_of_profiles,
bool has_sync_service) {
std::unique_ptr<syncer::TestSyncService> sync_service = nullptr;
if (has_sync_service) {
sync_service = std::make_unique<syncer::TestSyncService>();
sync_service->SetUserDemographics(user_demographics_result);
}
return std::make_unique<TestProfileClient>(std::move(sync_service),
number_of_profiles);
}
TEST(DemographicMetricsProviderTest,
ProvideSyncedUserNoisedBirthYearAndGender_FeatureEnabled) {
base::HistogramTester histogram;
// Run demographics provider.
DemographicMetricsProvider provider(
MakeTestProfileClient(GetDemographics(), /*number_of_profiles=*/1,
/*has_sync_service=*/true),
MetricsLogUploader::MetricServiceType::UMA);
ChromeUserMetricsExtension uma_proto;
provider.ProvideSyncedUserNoisedBirthYearAndGender(&uma_proto);
// Verify provided demographics.
EXPECT_EQ(GetDemographics().value().birth_year,
uma_proto.user_demographics().birth_year());
EXPECT_EQ(GetDemographics().value().gender,
uma_proto.user_demographics().gender());
// Verify histograms.
histogram.ExpectUniqueSample("UMA.UserDemographics.Status",
syncer::UserDemographicsStatus::kSuccess, 1);
}
TEST(DemographicMetricsProviderTest,
ProvideSyncedUserNoisedBirthYearAndGender_NoSyncService) {
base::HistogramTester histogram;
// Run demographics provider.
DemographicMetricsProvider provider(
MakeTestProfileClient(GetDemographics(),
/*number_of_profiles=*/1,
/*has_sync_service=*/false),
MetricsLogUploader::MetricServiceType::UMA);
ChromeUserMetricsExtension uma_proto;
provider.ProvideSyncedUserNoisedBirthYearAndGender(&uma_proto);
// Expect the proto fields to be not set and left to default.
EXPECT_FALSE(uma_proto.user_demographics().has_birth_year());
EXPECT_FALSE(uma_proto.user_demographics().has_gender());
// Verify histograms.
histogram.ExpectUniqueSample("UMA.UserDemographics.Status",
syncer::UserDemographicsStatus::kNoSyncService,
1);
}
TEST(DemographicMetricsProviderTest,
ProvideSyncedUserNoisedBirthYearAndGender_FeatureDisabled) {
// Disable demographics reporting feature.
base::test::ScopedFeatureList local_feature;
local_feature.InitAndDisableFeature(
DemographicMetricsProvider::kDemographicMetricsReporting);
base::HistogramTester histogram;
// Run demographics provider.
DemographicMetricsProvider provider(
MakeTestProfileClient(GetDemographics(), /*number_of_profiles=*/1,
/*has_sync_service=*/true),
MetricsLogUploader::MetricServiceType::UMA);
ChromeUserMetricsExtension uma_proto;
provider.ProvideSyncedUserNoisedBirthYearAndGender(&uma_proto);
// Expect that the UMA proto is untouched.
EXPECT_FALSE(uma_proto.user_demographics().has_birth_year());
EXPECT_FALSE(uma_proto.user_demographics().has_gender());
// Verify that there are no histograms for user demographics.
histogram.ExpectTotalCount("UMA.UserDemographics.Status", 0);
}
TEST(DemographicMetricsProviderTest,
ProvideSyncedUserNoisedBirthYearAndGender_NotExactlyOneProfile) {
base::HistogramTester histogram;
// Run demographics provider with not exactly one Profile on disk.
DemographicMetricsProvider provider(
MakeTestProfileClient(GetDemographics(), /*number_of_profiles=*/2,
/*has_sync_service=*/true),
MetricsLogUploader::MetricServiceType::UMA);
ChromeUserMetricsExtension uma_proto;
provider.ProvideSyncedUserNoisedBirthYearAndGender(&uma_proto);
// Expect that the UMA proto is untouched.
EXPECT_FALSE(uma_proto.user_demographics().has_birth_year());
EXPECT_FALSE(uma_proto.user_demographics().has_gender());
// Verify histograms.
histogram.ExpectUniqueSample(
"UMA.UserDemographics.Status",
syncer::UserDemographicsStatus::kMoreThanOneProfile, 1);
}
TEST(DemographicMetricsProviderTest,
ProvideSyncedUserNoisedBirthYearAndGender_NoUserDemographics) {
base::HistogramTester histogram;
// Run demographics provider with a ProfileClient that does not provide
// demographics because of some error.
DemographicMetricsProvider provider(
MakeTestProfileClient(
syncer::UserDemographicsResult::ForStatus(
syncer::UserDemographicsStatus::kIneligibleDemographicsData),
/*number_of_profiles=*/1,
/*has_sync_service=*/true),
MetricsLogUploader::MetricServiceType::UMA);
ChromeUserMetricsExtension uma_proto;
provider.ProvideSyncedUserNoisedBirthYearAndGender(&uma_proto);
// Expect that the UMA proto is untouched.
EXPECT_FALSE(uma_proto.user_demographics().has_birth_year());
EXPECT_FALSE(uma_proto.user_demographics().has_gender());
// Verify that there are no histograms for user demographics. We expect
// histograms to be logged by the sync libraries.
histogram.ExpectUniqueSample(
"UMA.UserDemographics.Status",
syncer::UserDemographicsStatus::kIneligibleDemographicsData, 1);
}
TEST(DemographicMetricsProviderTest,
ProvideSyncedUserNoisedBirthYearAndGenderToReport) {
base::HistogramTester histogram;
// Run demographics provider.
DemographicMetricsProvider provider(
MakeTestProfileClient(GetDemographics(), /*number_of_profiles=*/1,
/*has_sync_service=*/true),
MetricsLogUploader::MetricServiceType::UKM);
ukm::Report report;
provider.ProvideSyncedUserNoisedBirthYearAndGenderToReport(&report);
// Verify provided demographics.
EXPECT_EQ(GetDemographics().value().birth_year,
report.user_demographics().birth_year());
EXPECT_EQ(GetDemographics().value().gender,
report.user_demographics().gender());
// Verify histograms.
histogram.ExpectUniqueSample("UKM.UserDemographics.Status",
syncer::UserDemographicsStatus::kSuccess, 1);
}
} // namespace
} // namespace metrics