blob: 82f793dd78b5c28d930f49842ef8af62992f4dcb [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/browser/metrics/testing/sync_metrics_test_utils.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_test_util.h"
#include "chrome/browser/sync/test/integration/sync_service_impl_harness.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/unified_consent/unified_consent_service_factory.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/metrics/log_decoder.h"
#include "components/metrics/structured/structured_events.h"
#include "components/metrics/structured/structured_metrics_features.h"
#include "components/metrics/structured/structured_metrics_service.h"
#include "components/metrics/unsent_log_store.h"
#include "components/metrics_services_manager/metrics_services_manager.h"
#include "components/sync/test/fake_server_network_resources.h"
#include "components/unified_consent/unified_consent_service.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
namespace metrics {
metrics::structured::StructuredMetricsService* GetSMService() {
return g_browser_process->GetMetricsServicesManager()
->GetStructuredMetricsService();
}
// A helper object for overriding metrics enabled state.
class MetricsConsentOverride {
public:
explicit MetricsConsentOverride(bool initial_state) : state_(initial_state) {
ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting(
&state_);
Update(initial_state);
}
~MetricsConsentOverride() {
ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting(
nullptr);
}
void Update(bool state) {
state_ = state;
// Trigger rechecking of metrics state.
g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions(
/*may_upload=*/true);
}
private:
bool state_;
};
class StructuredMetricsServiceTestBase : public InProcessBrowserTest {
public:
StructuredMetricsServiceTestBase() = default;
bool HasUnsentLogs() {
return GetSMService()->reporting_service_->log_store()->has_unsent_logs();
}
bool HasStagedLog() {
return GetSMService()->reporting_service_->log_store()->has_staged_log();
}
void Wait() { base::RunLoop().RunUntilIdle(); }
};
class TestStructuredMetricsService : public StructuredMetricsServiceTestBase {
public:
TestStructuredMetricsService() {
feature_list_.InitAndEnableFeature(
metrics::structured::kEnabledStructuredMetricsService);
}
private:
base::test::ScopedFeatureList feature_list_;
};
class TestStructuredMetricsServiceDisabled
: public StructuredMetricsServiceTestBase {
public:
TestStructuredMetricsServiceDisabled() {
feature_list_.InitAndDisableFeature(
metrics::structured::kEnabledStructuredMetricsService);
}
private:
base::test::ScopedFeatureList feature_list_;
};
IN_PROC_BROWSER_TEST_F(TestStructuredMetricsService, EnabledWithConsent) {
auto* sm_service = GetSMService();
// Enable consent for profile.
MetricsConsentOverride metrics_consent(true);
// Verify that recording and reporting are enabled.
EXPECT_TRUE(sm_service->recording_enabled());
EXPECT_TRUE(sm_service->reporting_active());
}
IN_PROC_BROWSER_TEST_F(TestStructuredMetricsService, DisabledWhenRevoked) {
auto* sm_service = GetSMService();
// Enable consent for profile.
MetricsConsentOverride metrics_consent(true);
// Verify that recording and reporting are enabled.
EXPECT_TRUE(sm_service->recording_enabled());
EXPECT_TRUE(sm_service->reporting_active());
// Revoke consent.
metrics_consent.Update(false);
// Verify that recording and reporting are disabled.
EXPECT_FALSE(sm_service->recording_enabled());
EXPECT_FALSE(sm_service->reporting_active());
}
IN_PROC_BROWSER_TEST_F(TestStructuredMetricsService,
InMemoryPurgeOnConsentRevoke) {
auto* sm_service = GetSMService();
// Enable consent for profile.
MetricsConsentOverride metrics_consent(true);
// Wait for the consent to propagate.
Wait();
// Verify that recording and reporting are enabled.
EXPECT_TRUE(sm_service->recording_enabled());
EXPECT_TRUE(sm_service->reporting_active());
// Record a couple of events and verify that they are recorded.
structured::events::v2::test_project_one::TestEventOne()
.SetTestMetricOne("metric one")
.SetTestMetricTwo(10)
.Record();
structured::events::v2::test_project_five::TestEventSix()
.SetTestMetricSix("metric six")
.Record();
// There should be at least the 2 events recorded above. There could be others
// such as login event.
EXPECT_THAT(sm_service->recorder()->events()->non_uma_events_size(),
testing::Ge(2));
// Change the consent to force a purge.
metrics_consent.Update(false);
// There shouldn't be any staged or un-staged logs and no in-memory events.
EXPECT_FALSE(HasUnsentLogs());
EXPECT_FALSE(HasStagedLog());
EXPECT_EQ(sm_service->recorder()->events()->non_uma_events_size(), 0);
EXPECT_EQ(sm_service->recorder()->events()->uma_events_size(), 0);
}
IN_PROC_BROWSER_TEST_F(TestStructuredMetricsService,
StagedLogPurgeOnConsentRevoke) {
auto* sm_service = GetSMService();
// Enable consent for profile.
MetricsConsentOverride metrics_consent(true);
// Wait for the consent to propagate.
Wait();
// Verify that recording and reporting are enabled.
EXPECT_TRUE(sm_service->recording_enabled());
EXPECT_TRUE(sm_service->reporting_active());
// Record a couple of events and verify that they are recorded.
structured::events::v2::test_project_one::TestEventOne()
.SetTestMetricOne("metric one")
.SetTestMetricTwo(10)
.Record();
structured::events::v2::test_project_five::TestEventSix()
.SetTestMetricSix("metric six")
.Record();
// There should be at least the 2 events recorded above. There could be others
// such as login event.
EXPECT_THAT(sm_service->recorder()->events()->non_uma_events_size(),
testing::Ge(2));
// Flush the in-memory events to a staged log.
sm_service->Flush(metrics::MetricsLogsEventManager::CreateReason::kUnknown);
// Change the consent to force a purge.
metrics_consent.Update(false);
// There shouldn't be any staged or un-staged logs and no in-memory events.
EXPECT_FALSE(HasUnsentLogs());
EXPECT_FALSE(HasStagedLog());
EXPECT_EQ(sm_service->recorder()->events()->non_uma_events_size(), 0);
EXPECT_EQ(sm_service->recorder()->events()->uma_events_size(), 0);
}
IN_PROC_BROWSER_TEST_F(TestStructuredMetricsServiceDisabled,
ValidStateWhenDisabled) {
auto* sm_service = GetSMService();
// Enable consent for profile.
MetricsConsentOverride metrics_consent(true);
// Everything should be null expect the recorder. The recorder is used by
// StructuredMetricsProvider when the service is disabled; therefore, it
// cannot be null.
EXPECT_THAT(sm_service->recorder(), testing::NotNull());
EXPECT_THAT(sm_service->reporting_service_.get(), testing::IsNull());
EXPECT_THAT(sm_service->scheduler_.get(), testing::IsNull());
}
} // namespace metrics