123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- // 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/optimization_guide/core/prediction_model_fetcher_impl.h"
- #include <memory>
- #include <string>
- #include <vector>
- #include "base/callback.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/run_loop.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/task_environment.h"
- #include "components/optimization_guide/core/optimization_guide_features.h"
- #include "components/optimization_guide/proto/models.pb.h"
- #include "components/variations/scoped_variations_ids_provider.h"
- #include "net/base/url_util.h"
- #include "services/network/public/cpp/shared_url_loader_factory.h"
- #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
- #include "services/network/test/test_url_loader_factory.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace optimization_guide {
- constexpr char optimization_guide_service_url[] =
- "https://optimizationguideservice.com/";
- class PredictionModelFetcherTest : public testing::Test {
- public:
- PredictionModelFetcherTest()
- : task_environment_(base::test::TaskEnvironment::MainThreadType::UI),
- shared_url_loader_factory_(
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- &test_url_loader_factory_)) {
- prediction_model_fetcher_ = std::make_unique<PredictionModelFetcherImpl>(
- shared_url_loader_factory_, GURL(optimization_guide_service_url));
- }
- PredictionModelFetcherTest(const PredictionModelFetcherTest&) = delete;
- PredictionModelFetcherTest& operator=(const PredictionModelFetcherTest&) =
- delete;
- ~PredictionModelFetcherTest() override {}
- void OnModelsFetched(absl::optional<std::unique_ptr<proto::GetModelsResponse>>
- get_models_response) {
- if (get_models_response)
- models_fetched_ = true;
- }
- bool models_fetched() { return models_fetched_; }
- protected:
- bool FetchModels(const std::vector<proto::ModelInfo> models_request_info,
- proto::RequestContext request_context,
- const std::string& locale) {
- bool status =
- prediction_model_fetcher_->FetchOptimizationGuideServiceModels(
- models_request_info, request_context, locale,
- base::BindOnce(&PredictionModelFetcherTest::OnModelsFetched,
- base::Unretained(this)));
- RunUntilIdle();
- return status;
- }
- // Return a 200 response with provided content to any pending requests.
- bool SimulateResponse(const std::string& content,
- net::HttpStatusCode http_status) {
- return test_url_loader_factory_.SimulateResponseForPendingRequest(
- optimization_guide_service_url, content, http_status,
- network::TestURLLoaderFactory::kUrlMatchPrefix);
- }
- void VerifyHasPendingFetchRequests() {
- EXPECT_GE(test_url_loader_factory_.NumPending(), 1);
- std::string key_value;
- for (const auto& pending_request :
- *test_url_loader_factory_.pending_requests()) {
- EXPECT_EQ(pending_request.request.method, "POST");
- EXPECT_TRUE(net::GetValueForKeyInQuery(pending_request.request.url, "key",
- &key_value));
- }
- }
- private:
- void RunUntilIdle() {
- task_environment_.RunUntilIdle();
- base::RunLoop().RunUntilIdle();
- }
- bool models_fetched_ = false;
- base::test::TaskEnvironment task_environment_;
- variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
- variations::VariationsIdsProvider::Mode::kUseSignedInState};
- std::unique_ptr<PredictionModelFetcherImpl> prediction_model_fetcher_;
- scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
- network::TestURLLoaderFactory test_url_loader_factory_;
- };
- TEST_F(PredictionModelFetcherTest, FetchOptimizationGuideServiceModels) {
- std::string response_content;
- proto::ModelInfo model_info;
- model_info.set_optimization_target(
- proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD);
- EXPECT_TRUE(FetchModels({model_info},
- proto::RequestContext::CONTEXT_BATCH_UPDATE_MODELS,
- "en-US"));
- VerifyHasPendingFetchRequests();
- EXPECT_TRUE(SimulateResponse(response_content, net::HTTP_OK));
- EXPECT_TRUE(models_fetched());
- }
- // Tests 404 response from request.
- TEST_F(PredictionModelFetcherTest, FetchReturned404) {
- base::HistogramTester histogram_tester;
- std::string response_content;
- proto::ModelInfo model_info;
- model_info.set_optimization_target(
- proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD);
- EXPECT_TRUE(FetchModels({model_info},
- proto::RequestContext::CONTEXT_BATCH_UPDATE_MODELS,
- "en-US"));
- // Send a 404 to HintsFetcher.
- SimulateResponse(response_content, net::HTTP_NOT_FOUND);
- EXPECT_FALSE(models_fetched());
- histogram_tester.ExpectUniqueSample(
- "OptimizationGuide.PredictionModelFetcher."
- "GetModelsResponse.Status",
- net::HTTP_NOT_FOUND, 1);
- histogram_tester.ExpectUniqueSample(
- "OptimizationGuide.PredictionModelFetcher."
- "GetModelsResponse.Status.PainfulPageLoad",
- net::HTTP_NOT_FOUND, 1);
- // Net error codes are negative but UMA histograms require positive values.
- histogram_tester.ExpectUniqueSample(
- "OptimizationGuide.PredictionModelFetcher."
- "GetModelsResponse.NetErrorCode",
- -net::ERR_HTTP_RESPONSE_CODE_FAILURE, 1);
- histogram_tester.ExpectUniqueSample(
- "OptimizationGuide.PredictionModelFetcher."
- "GetModelsResponse.NetErrorCode.PainfulPageLoad",
- -net::ERR_HTTP_RESPONSE_CODE_FAILURE, 1);
- }
- TEST_F(PredictionModelFetcherTest, FetchReturnBadResponse) {
- std::string response_content = "not proto";
- proto::ModelInfo model_info;
- model_info.set_optimization_target(
- proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD);
- EXPECT_TRUE(FetchModels({model_info},
- proto::RequestContext::CONTEXT_BATCH_UPDATE_MODELS,
- "en-US"));
- VerifyHasPendingFetchRequests();
- EXPECT_TRUE(SimulateResponse(response_content, net::HTTP_OK));
- EXPECT_FALSE(models_fetched());
- }
- TEST_F(PredictionModelFetcherTest, EmptyModelInfo) {
- base::HistogramTester histogram_tester;
- std::string response_content;
- EXPECT_FALSE(FetchModels(/*models_request_info=*/{},
- proto::RequestContext::CONTEXT_BATCH_UPDATE_MODELS,
- "en-US"));
- EXPECT_FALSE(models_fetched());
- }
- } // namespace optimization_guide
|