123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- // Copyright 2022 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 "base/test/gmock_callback_support.h"
- #include "base/test/scoped_feature_list.h"
- #include "build/build_config.h"
- #include "chrome/browser/browser_process.h"
- #include "chrome/browser/history/history_service_factory.h"
- #include "chrome/browser/profiles/profile.h"
- #include "chrome/browser/segmentation_platform/segmentation_platform_service_factory.h"
- #include "chrome/browser/segmentation_platform/ukm_data_manager_test_utils.h"
- #include "chrome/browser/segmentation_platform/ukm_database_client.h"
- #include "chrome/browser/ui/browser.h"
- #include "chrome/test/base/in_process_browser_test.h"
- #include "components/metrics_services_manager/metrics_services_manager.h"
- #include "components/prefs/pref_change_registrar.h"
- #include "components/prefs/pref_observer.h"
- #include "components/prefs/pref_service.h"
- #include "components/segmentation_platform/internal/constants.h"
- #include "components/segmentation_platform/internal/execution/mock_model_provider.h"
- #include "components/segmentation_platform/public/config.h"
- #include "components/segmentation_platform/public/features.h"
- #include "components/segmentation_platform/public/segment_selection_result.h"
- #include "components/segmentation_platform/public/segmentation_platform_service.h"
- #include "components/ukm/ukm_service.h"
- #include "content/public/test/browser_test.h"
- namespace segmentation_platform {
- using ::base::test::RunOnceCallback;
- using ::testing::_;
- using ::testing::Invoke;
- using ::testing::Return;
- using ::testing::SaveArg;
- constexpr SegmentId kSegmentId =
- SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_CHROME_LOW_USER_ENGAGEMENT;
- constexpr char kSqlFeatureQuery[] = "SELECT COUNT(*) from metrics";
- class SegmentationPlatformTest : public InProcessBrowserTest {
- public:
- SegmentationPlatformTest() {
- feature_list_.InitWithFeaturesAndParameters(
- {base::test::ScopedFeatureList::FeatureAndParams(
- features::kSegmentationPlatformFeature, {}),
- base::test::ScopedFeatureList::FeatureAndParams(
- features::kSegmentationStructuredMetricsFeature, {}),
- base::test::ScopedFeatureList::FeatureAndParams(
- features::kSegmentationPlatformUkmEngine, {}),
- base::test::ScopedFeatureList::FeatureAndParams(
- features::kSegmentationPlatformLowEngagementFeature,
- {{"enable_default_model", "true"}})},
- {});
- }
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitch("segmentation-platform-refresh-results");
- }
- bool HasResultPref(base::StringPiece segmentation_key) {
- const base::Value::Dict& dictionary =
- browser()->profile()->GetPrefs()->GetValueDict(kSegmentationResultPref);
- return !!dictionary.FindByDottedPath(segmentation_key);
- }
- void OnResultPrefUpdated() {
- if (!wait_for_pref_callback_.is_null() &&
- HasResultPref(kChromeLowUserEngagementSegmentationKey)) {
- std::move(wait_for_pref_callback_).Run();
- }
- }
- void WaitForPrefUpdate() {
- if (HasResultPref(kChromeLowUserEngagementSegmentationKey))
- return;
- base::RunLoop wait_for_pref;
- wait_for_pref_callback_ = wait_for_pref.QuitClosure();
- pref_registrar_.Init(browser()->profile()->GetPrefs());
- pref_registrar_.Add(
- kSegmentationResultPref,
- base::BindRepeating(&SegmentationPlatformTest::OnResultPrefUpdated,
- weak_ptr_factory_.GetWeakPtr()));
- wait_for_pref.Run();
- pref_registrar_.RemoveAll();
- }
- void WaitForPlatformInit() {
- base::RunLoop wait_for_init;
- SegmentationPlatformService* service = segmentation_platform::
- SegmentationPlatformServiceFactory::GetForProfile(browser()->profile());
- while (!service->IsPlatformInitialized()) {
- wait_for_init.RunUntilIdle();
- }
- }
- void ExpectSegmentSelectionResult(const std::string& segmentation_key,
- bool result_expected) {
- SegmentationPlatformService* service = segmentation_platform::
- SegmentationPlatformServiceFactory::GetForProfile(browser()->profile());
- base::RunLoop wait_for_segment;
- service->GetSelectedSegment(
- segmentation_key, base::BindOnce(
- [](bool result_expected, base::OnceClosure quit,
- const SegmentSelectionResult& result) {
- EXPECT_EQ(result_expected, result.is_ready);
- std::move(quit).Run();
- },
- result_expected, wait_for_segment.QuitClosure()));
- wait_for_segment.Run();
- }
- protected:
- base::test::ScopedFeatureList feature_list_;
- PrefChangeRegistrar pref_registrar_;
- base::OnceClosure wait_for_pref_callback_;
- base::WeakPtrFactory<SegmentationPlatformTest> weak_ptr_factory_{this};
- };
- IN_PROC_BROWSER_TEST_F(SegmentationPlatformTest, PRE_RunDefaultModel) {
- WaitForPlatformInit();
- // The default model is executed and result stored in prefs.
- WaitForPrefUpdate();
- // The result from platform is not available since it only returns result from
- // a previous session.
- ExpectSegmentSelectionResult(kChromeLowUserEngagementSegmentationKey,
- /*result_expected=*/false);
- }
- IN_PROC_BROWSER_TEST_F(SegmentationPlatformTest, RunDefaultModel) {
- WaitForPlatformInit();
- // Result is available from previous session's selection.
- ExpectSegmentSelectionResult(kChromeLowUserEngagementSegmentationKey,
- /*result_expected=*/true);
- // This session runs default model and updates again.
- WaitForPrefUpdate();
- }
- class SegmentationPlatformUkmModelTest : public SegmentationPlatformTest {
- public:
- SegmentationPlatformUkmModelTest() : utils_(&ukm_recorder_) {}
- void CreatedBrowserMainParts(content::BrowserMainParts* parts) override {
- InProcessBrowserTest::CreatedBrowserMainParts(parts);
- utils_.PreProfileInit({kSegmentId});
- }
- void PreRunTestOnMainThread() override {
- SegmentationPlatformTest::PreRunTestOnMainThread();
- utils_.set_history_service(HistoryServiceFactory::GetForProfile(
- browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS));
- }
- protected:
- ukm::TestUkmRecorder ukm_recorder_;
- UkmDataManagerTestUtils utils_;
- };
- // This test is disabled in CrOS because CrOS creates a signin profile that uses
- // incognito mode. This disables the segmentation platform data collection.
- // TODO(ssid): Fix this test for CrOS by waiting for signin profile to be
- // deleted at startup before adding metrics.
- #if BUILDFLAG(IS_CHROMEOS)
- #define MAYBE_PRE_RunUkmBasedModel DISABLED_PRE_RunUkmBasedModel
- #define MAYBE_RunUkmBasedModel DISABLED_RunUkmBasedModel
- #else
- #define MAYBE_PRE_RunUkmBasedModel PRE_RunUkmBasedModel
- #define MAYBE_RunUkmBasedModel RunUkmBasedModel
- #endif
- IN_PROC_BROWSER_TEST_F(SegmentationPlatformUkmModelTest,
- MAYBE_PRE_RunUkmBasedModel) {
- const GURL kUrl1("https://www.url1.com");
- MockModelProvider* provider = utils_.GetDefaultOverride(kSegmentId);
- EXPECT_CALL(*provider, ExecuteModelWithInput(_, _))
- .WillRepeatedly(Invoke([&](const std::vector<float>& inputs,
- ModelProvider::ExecutionCallback callback) {
- // There are no UKM metrics written to the database, count = 0.
- EXPECT_EQ(std::vector<float>({0}), inputs);
- std::move(callback).Run(0.5);
- }));
- WaitForPlatformInit();
- utils_.WaitForModelRequestAndUpdateWith(
- kSegmentId, utils_.GetSamplePageLoadMetadata(kSqlFeatureQuery));
- // Wait for the default model to run and save results to prefs.
- WaitForPrefUpdate();
- // Record page load UKM that should be recorded in the database, persisted
- // across sessions.
- utils_.RecordPageLoadUkm(kUrl1, base::Time::Now());
- while (!utils_.IsUrlInDatabase(kUrl1)) {
- base::RunLoop().RunUntilIdle();
- }
- }
- IN_PROC_BROWSER_TEST_F(SegmentationPlatformUkmModelTest,
- MAYBE_RunUkmBasedModel) {
- const GURL kUrl1("https://www.url1.com");
- MockModelProvider* provider = utils_.GetDefaultOverride(kSegmentId);
- EXPECT_CALL(*provider, ExecuteModelWithInput(_, _))
- .WillRepeatedly(Invoke([](const std::vector<float>& inputs,
- ModelProvider::ExecutionCallback callback) {
- // Expected input is 2 since we recorded 2 UKM metrics in the previous
- // session.
- EXPECT_EQ(std::vector<float>({2}), inputs);
- std::move(callback).Run(0.5);
- }));
- WaitForPlatformInit();
- // Verify that the URL recorded in last session is still in database.
- EXPECT_TRUE(utils_.IsUrlInDatabase(kUrl1));
- // Result is available from previous session's selection.
- ExpectSegmentSelectionResult(kChromeLowUserEngagementSegmentationKey,
- /*result_expected=*/true);
- utils_.WaitForModelRequestAndUpdateWith(
- kSegmentId, utils_.GetSamplePageLoadMetadata(kSqlFeatureQuery));
- WaitForPrefUpdate();
- }
- } // namespace segmentation_platform
|