// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/preloading/prerenderer_impl.h"

#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "content/browser/preloading/prefetch/prefetch_features.h"
#include "content/browser/preloading/prefetch/prefetch_match_resolver.h"
#include "content/browser/preloading/prefetch/prefetch_service.h"
#include "content/browser/preloading/prefetch/prefetch_status.h"
#include "content/browser/preloading/prefetch/prefetch_test_util_internal.h"
#include "content/browser/preloading/preload_serving_metrics_holder.h"
#include "content/browser/preloading/preloading.h"
#include "content/browser/preloading/preloading_confidence.h"
#include "content/browser/preloading/preloading_decider.h"
#include "content/browser/preloading/prerender/prerender_features.h"
#include "content/browser/preloading/prerender/prerender_host_registry.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_client.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/prefetch_test_util.h"
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_renderer_host.h"
#include "content/shell/browser/shell.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_web_contents.h"
#include "net/dns/mock_host_resolver.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/navigation/preloading_headers.h"
#include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom.h"

namespace content {
namespace {

struct RequestPathAndSecPurposeHeader {
  std::string path;
  std::string sec_purpose_header_value;

  bool operator==(const RequestPathAndSecPurposeHeader& other) const = default;
};

std::ostream& operator<<(std::ostream& ostream,
                         const RequestPathAndSecPurposeHeader& x) {
  return ostream << "RequestPathAndSecPurposeHeader {.path = \"" << x.path
                 << "\", .sec_purpose_header_value = \""
                 << x.sec_purpose_header_value << "\"}";
}

class PrerendererImplBrowserTestBase : public ContentBrowserTest {
 public:
  PrerendererImplBrowserTestBase() = default;
  ~PrerendererImplBrowserTestBase() override = default;

  void SetUp() override {
    prerender_helper_ = std::make_unique<test::PrerenderTestHelper>(
        base::BindRepeating(
            [](PrerendererImplBrowserTestBase* that) {
              return &that->web_contents();
            },
            base::Unretained(this)),
        /*force_disable_prerender2fallback=*/false,
        /*force_enable_prerender2innewtab==*/false);

    ContentBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    https_server_ = std::make_unique<net::EmbeddedTestServer>(
        net::EmbeddedTestServer::TYPE_HTTPS);
    histogram_tester_ = std::make_unique<base::HistogramTester>();

    host_resolver()->AddRule("*", "127.0.0.1");

    https_server_->SetSSLConfig(
        net::test_server::EmbeddedTestServer::CERT_TEST_NAMES);
    https_server_->RegisterRequestMonitor(
        base::BindRepeating(&PrerendererImplBrowserTestBase::OnResourceRequest,
                            base::Unretained(this)));
    https_server_->AddDefaultHandlers(GetTestDataFilePath());
    ASSERT_TRUE(https_server_->Start());

    embedded_test_server()->RegisterRequestMonitor(
        base::BindRepeating(&PrerendererImplBrowserTestBase::OnResourceRequest,
                            base::Unretained(this)));
    embedded_test_server()->AddDefaultHandlers(GetTestDataFilePath());
    ASSERT_TRUE(embedded_test_server()->Start());

    PreloadServingMetricsHolder::SetDestructorCallbackForTesting(
        base::BindRepeating(&PrerendererImplBrowserTestBase::
                                OnPreloadServingMetricsHolderDestructor,
                            base::Unretained(this)));
  }

  void TearDownOnMainThread() override {
    PreloadServingMetricsHolder::SetDestructorCallbackForTesting({});

    ASSERT_TRUE(https_server_->ShutdownAndWaitUntilComplete());
    ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
  }

  GURL GetUrl(const std::string& path) {
    return https_server_->GetURL("a.test", path);
  }

  GURL GetCrossSiteUrl(const std::string& path) {
    return https_server_->GetURL("b.test", path);
  }

  GURL GetUrlHttp(const std::string& path) {
    return embedded_test_server()->GetURL("a.test", path);
  }

  Prefetcher& GetPrefetcher() {
    return PreloadingDecider::GetOrCreateForCurrentDocument(
               web_contents_impl().GetPrimaryMainFrame())
        ->GetPrefetcherForTesting();
  }

  PrerendererImpl& GetPrerendererImpl() {
    return static_cast<PrerendererImpl&>(
        PreloadingDecider::GetOrCreateForCurrentDocument(
            web_contents_impl().GetPrimaryMainFrame())
            ->GetPrerendererForTesting());
  }

  blink::mojom::SpeculationCandidatePtr CreateSpeculationCandidate(
      const GURL& url) {
    return blink::mojom::SpeculationCandidate::New(
        /*url=*/url,
        /*action=*/blink::mojom::SpeculationAction::kPrerender,
        /*referrer=*/blink::mojom::Referrer::New(),
        /*requires_anonymous_client_ip_when_cross_origin=*/false,
        /*target_browsing_context_name_hint=*/
        blink::mojom::SpeculationTargetHint::kNoHint,
        /*eagerness=*/blink::mojom::SpeculationEagerness::kImmediate,
        /*no_vary_search_hint=*/nullptr,
        /*injection_type=*/blink::mojom::SpeculationInjectionType::kNone,
        /*tags=*/std::vector<std::optional<std::string>>{std::nullopt});
  }

  std::vector<RequestPathAndSecPurposeHeader> GetObservedRequests() {
    CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

    base::AutoLock auto_lock(lock_);

    std::vector<RequestPathAndSecPurposeHeader> ret;
    for (auto request : requests_) {
      ret.push_back(RequestPathAndSecPurposeHeader{
          .path = request.GetURL().PathForRequest(),
          .sec_purpose_header_value =
              request.headers[blink::kSecPurposeHeaderName],
      });
    }
    return ret;
  }

  void SetResponseDelay(base::TimeDelta duration) {
    response_delay_ = duration;
  }

  void OnPreloadServingMetricsHolderDestructor(
      std::unique_ptr<PreloadServingMetrics> log) {
    preload_serving_metrics_list_.push_back(std::move(log));
  }

  net::EmbeddedTestServer& https_server() { return *https_server_.get(); }
  base::HistogramTester& histogram_tester() { return *histogram_tester_.get(); }
  test::PrerenderTestHelper& prerender_helper() {
    return *prerender_helper_.get();
  }
  WebContents& web_contents() { return *shell()->web_contents(); }
  WebContentsImpl& web_contents_impl() {
    return static_cast<WebContentsImpl&>(web_contents());
  }
  std::vector<std::unique_ptr<PreloadServingMetrics>>&
  preload_serving_metrics_list() {
    return preload_serving_metrics_list_;
  }

 protected:
  base::test::ScopedFeatureList feature_list_;

 private:
  void OnResourceRequest(const net::test_server::HttpRequest& request) {
    // Called from a thread for EmbeddedTestServer.
    CHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI) &&
          !BrowserThread::CurrentlyOn(BrowserThread::IO));

    base::PlatformThread::Sleep(response_delay_);

    // So, we guard the field with lock.
    base::AutoLock auto_lock(lock_);

    requests_.push_back(request);
  }

  std::unique_ptr<net::EmbeddedTestServer> https_server_;
  std::unique_ptr<base::HistogramTester> histogram_tester_;
  std::unique_ptr<test::PrerenderTestHelper> prerender_helper_;

  base::TimeDelta response_delay_ = base::Seconds(0);
  base::Lock lock_;
  std::vector<net::test_server::HttpRequest> requests_ GUARDED_BY(lock_);

  std::vector<std::unique_ptr<PreloadServingMetrics>>
      preload_serving_metrics_list_;
};

class PrerendererImplBrowserTestNoPrefetchAhead
    : public PrerendererImplBrowserTestBase {
 public:
  PrerendererImplBrowserTestNoPrefetchAhead() {
    feature_list_.InitWithFeatures(
        {}, {features::kPrerender2FallbackPrefetchSpecRules,
             blink::features::kLCPTimingPredictorPrerender2});
  }
};

class PrerendererImplBrowserTestPrefetchAhead
    : public PrerendererImplBrowserTestBase,
      public ::testing::WithParamInterface<
          features::Prerender2FallbackPrefetchSchedulerPolicy> {
 public:
  PrerendererImplBrowserTestPrefetchAhead() {
    const char* prefetch_scheduler_policy = [&]() {
      switch (GetParam()) {
        case features::Prerender2FallbackPrefetchSchedulerPolicy::kNotUse:
          return "NotUse";
        case features::Prerender2FallbackPrefetchSchedulerPolicy::kPrioritize:
          return "Prioritize";
        case features::Prerender2FallbackPrefetchSchedulerPolicy::kBurst:
          return "Burst";
      }
    }();
    feature_list_.InitWithFeaturesAndParameters(
        {
            {
                features::kPrerender2FallbackPrefetchSpecRules,
                {
                    {"kPrerender2FallbackPrefetchSchedulerPolicy",
                     prefetch_scheduler_policy},
                    {"kPrerender2FallbackUsePreloadServingMetrics", "true"},
                },
            },
            {
                features::kPrefetchUseContentRefactor,
                {
                    {"prefetch_timeout_ms", "1500"},
                    {"block_until_head_timeout_moderate_prefetch", "500"},
                },
            },
        },
        {
            blink::features::kLCPTimingPredictorPrerender2,
            // `kPrefetchServiceWorker` is disabled to make the prefetch fail
            // due to ServiceWorker-related ineligibility.
            features::kPrefetchServiceWorker,
        });
  }
};

INSTANTIATE_TEST_SUITE_P(
    ParametrizedTests,
    PrerendererImplBrowserTestPrefetchAhead,
    testing::Values(
        features::Prerender2FallbackPrefetchSchedulerPolicy::kNotUse,
        features::Prerender2FallbackPrefetchSchedulerPolicy::kPrioritize,
        features::Prerender2FallbackPrefetchSchedulerPolicy::kBurst));

IN_PROC_BROWSER_TEST_F(PrerendererImplBrowserTestNoPrefetchAhead,
                       PrefetchNotTriggeredPrerenderSuccess) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});
  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  prerender_helper().NavigatePrimaryPage(prerender_url);

  histogram_tester().ExpectTotalCount(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome", 0);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);

  histogram_tester().ExpectTotalCount(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      0);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue}};
  ASSERT_EQ(expected, GetObservedRequests());
}

IN_PROC_BROWSER_TEST_F(PrerendererImplBrowserTestNoPrefetchAhead,
                       PrefetchNotTriggeredPrerenderFailure) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});
  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  // Make prerender failure by calling a forbidden API.
  test::PrerenderHostObserver observer(web_contents(), prerender_url);
  RenderFrameHost* rfh =
      prerender_helper().GetPrerenderedMainFrameHost(prerender_url);
  ASSERT_TRUE(rfh);
  const char* script = "navigator.getGamepads();";
  rfh->ExecuteJavaScriptForTests(base::UTF8ToUTF16(script),
                                 base::NullCallback(),
                                 ISOLATED_WORLD_ID_GLOBAL);
  observer.WaitForDestroyed();

  prerender_helper().NavigatePrimaryPage(prerender_url);

  histogram_tester().ExpectTotalCount(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome", 0);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue},
      {.path = "/title1.html", .sec_purpose_header_value = ""},
  };
  ASSERT_EQ(expected, GetObservedRequests());
}

IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchSuccessPrerenderSuccess) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));
  preload_serving_metrics_list().clear();

  const GURL prerender_url = GetUrl("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});
  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  prerender_helper().NavigatePrimaryPage(prerender_url);

  // TODO(https://crbug.com/342089066): Record prefetch as
  // kTriggeredButUpgradedToPrerender.
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);

  histogram_tester().ExpectTotalCount(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      0);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue}};
  ASSERT_EQ(expected, GetObservedRequests());

  ASSERT_EQ(2u, preload_serving_metrics_list().size());

  auto& prerender_initial_preload_serving_metrics =
      preload_serving_metrics_list()[0];
  // Taken and used to record UMAs.
  ASSERT_FALSE(prerender_initial_preload_serving_metrics);

  auto& preload_serving_metrics = preload_serving_metrics_list()[1];
  ASSERT_TRUE(preload_serving_metrics);
  ASSERT_EQ(0u, preload_serving_metrics->prefetch_match_metrics_list.size());
  ASSERT_TRUE(
      preload_serving_metrics->prerender_initial_preload_serving_metrics);
  ASSERT_EQ(1u,
            preload_serving_metrics->prerender_initial_preload_serving_metrics
                ->prefetch_match_metrics_list.size());
  ASSERT_TRUE(preload_serving_metrics->prerender_initial_preload_serving_metrics
                  ->prefetch_match_metrics_list[0]);
  ASSERT_EQ(1,
            preload_serving_metrics->prerender_initial_preload_serving_metrics
                ->prefetch_match_metrics_list[0]
                ->n_initial_candidates);
  ASSERT_EQ(1,
            preload_serving_metrics->prerender_initial_preload_serving_metrics
                ->prefetch_match_metrics_list[0]
                ->n_initial_candidates_block_until_head);
  ASSERT_TRUE(preload_serving_metrics->prerender_initial_preload_serving_metrics
                  ->prefetch_match_metrics_list[0]
                  ->prefetch_container_metrics);
  ASSERT_TRUE(preload_serving_metrics->prerender_initial_preload_serving_metrics
                  ->prefetch_match_metrics_list[0]
                  ->prefetch_container_metrics
                  ->time_header_determined_successfully.has_value());
  ASSERT_TRUE(preload_serving_metrics->prerender_initial_preload_serving_metrics
                  ->prefetch_match_metrics_list[0]
                  ->prefetch_container_metrics_ahead_of_prerender);
  ASSERT_TRUE(
      preload_serving_metrics->prerender_initial_preload_serving_metrics
          ->prefetch_match_metrics_list[0]
          ->prefetch_potential_candidate_serving_result_ahead_of_prerender);
}

IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchSuccessPrerenderNotEligible) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  test::TestPrefetchWatcher watcher;
  const GURL prerender_url = GetCrossSiteUrl("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});
  watcher.WaitUntilPrefetchResponseCompleted(
      web_contents_impl().GetPrimaryMainFrame()->GetDocumentToken(),
      prerender_url);

  prerender_helper().NavigatePrimaryPage(prerender_url);

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kUnspecified, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kCrossSiteNavigationInInitialNavigation, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue},
  };
  ASSERT_EQ(expected, GetObservedRequests());
}

IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchSuccessPrerenderFailure) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));
  preload_serving_metrics_list().clear();

  const GURL prerender_url = GetUrl("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});
  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  // Make prerender failure by calling a forbidden API.
  test::PrerenderHostObserver observer(web_contents(), prerender_url);
  RenderFrameHost* rfh =
      prerender_helper().GetPrerenderedMainFrameHost(prerender_url);
  ASSERT_TRUE(rfh);
  const char* script = "navigator.getGamepads();";
  rfh->ExecuteJavaScriptForTests(base::UTF8ToUTF16(script),
                                 base::NullCallback(),
                                 ISOLATED_WORLD_ID_GLOBAL);
  observer.WaitForDestroyed();

  prerender_helper().NavigatePrimaryPage(prerender_url);

  // TODO(https://crbug.com/342089066): Record prefetch as
  // kTriggeredButUpgradedToPrerender.
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kMojoBinderPolicy, 1);

  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      1, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue},
  };
  ASSERT_EQ(expected, GetObservedRequests());

  ASSERT_EQ(2u, preload_serving_metrics_list().size());

  auto& prerender_initial_preload_serving_metrics =
      preload_serving_metrics_list()[0];
  // Taken and used to record UMAs.
  ASSERT_FALSE(prerender_initial_preload_serving_metrics);

  auto& preload_serving_metrics = preload_serving_metrics_list()[1];
  ASSERT_TRUE(preload_serving_metrics);
  ASSERT_EQ(1u, preload_serving_metrics->prefetch_match_metrics_list.size());
  ASSERT_EQ(1u, preload_serving_metrics->prefetch_match_metrics_list[0]
                    ->n_initial_candidates);
  ASSERT_EQ(0u, preload_serving_metrics->prefetch_match_metrics_list[0]
                    ->n_initial_candidates_block_until_head);
  ASSERT_TRUE(preload_serving_metrics->prefetch_match_metrics_list[0]
                  ->prefetch_container_metrics);
  ASSERT_TRUE(preload_serving_metrics->prefetch_match_metrics_list[0]
                  ->prefetch_container_metrics
                  ->time_header_determined_successfully.has_value());
  ASSERT_FALSE(preload_serving_metrics->prefetch_match_metrics_list[0]
                   ->prefetch_container_metrics_ahead_of_prerender);
  ASSERT_FALSE(
      preload_serving_metrics->prefetch_match_metrics_list[0]
          ->prefetch_potential_candidate_serving_result_ahead_of_prerender);
  ASSERT_FALSE(
      preload_serving_metrics->prerender_initial_preload_serving_metrics);
}

IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchNotEligiblePrerenderFailure) {
  // Make eligibility check fail with `kHostIsNonUnique`.
  auto& prefetch_service = *PrefetchService::GetFromFrameTreeNodeId(
      web_contents().GetPrimaryMainFrame()->GetFrameTreeNodeId());
  prefetch_service.SetInjectedEligibilityCheckForTesting(base::BindRepeating(
      [](PrefetchService::InjectedEligibilityCheckResultCallbackForTesting
             callback) {
        std::move(callback).Run(PreloadingEligibility::kHostIsNonUnique);
      }));

  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});

  // Here we shouldn't call
  // `prerender_helper().WaitForPrerenderLoadCompletion(prerender_url)` since
  // this eligibility check of prefetch synchronously fails and the call first
  // tries to get `PrerenderHost`, which has been already destructed.

  ASSERT_TRUE(NavigateToURL(shell(), prerender_url));

  prefetch_service.SetInjectedEligibilityCheckForTesting(base::NullCallback());

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kUnspecified, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kPrerenderFailedDuringPrefetch, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrefetchAheadOfPrerenderFailed.PrefetchStatus."
      "SpeculationRule",
      PrefetchStatus::kPrefetchIneligibleHostIsNonUnique, 1);

  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      1, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html", .sec_purpose_header_value = ""},
  };
  ASSERT_EQ(expected, GetObservedRequests());
}

IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchNotEligibleNonHttpsPrerenderSuccess) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrlHttp("/empty.html")));

  const GURL prerender_url = GetUrlHttp("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});
  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  prerender_helper().NavigatePrimaryPage(prerender_url);

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kUnspecified, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);

  histogram_tester().ExpectTotalCount(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      0);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue},
  };
  ASSERT_EQ(expected, GetObservedRequests());
}

IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchNotEligibleNonHttpsPrerenderSuccessWithDelay) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrlHttp("/empty.html")));

  PrefetchServiceInjectedEligibilityCheckFuture
      eligibility_check_callback_future(
          *PrefetchService::GetFromFrameTreeNodeId(
              web_contents().GetPrimaryMainFrame()->GetFrameTreeNodeId()));

  const GURL prerender_url = GetUrlHttp("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});

  base::PlatformThread::Sleep(base::Milliseconds(101));

  // Proceed to the eligibility check.
  eligibility_check_callback_future->Take().Run(
      PreloadingEligibility::kEligible);

  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  prerender_helper().NavigatePrimaryPage(prerender_url);

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kUnspecified, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);

  histogram_tester().ExpectTotalCount(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      0);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue},
  };
  ASSERT_EQ(expected, GetObservedRequests());
}

// Scenario:
//
// - URL U has a service worker.
// - Trigger prefetch ahead of prerender A for URL U.
// - A failed in eligibility check due to SW.
// - Trigger prerender A' for URL U.
//   - A' falls back to non-prefetch navigation.
// - Navigation is started. A' is used.
IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchNotEligibleServiceWorkerPrerenderSuccess) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/prerender/empty.html")));

  std::string script = R"(
    (async () => {
      await navigator.serviceWorker.register('./sw_fallback.js');
      await navigator.serviceWorker.ready;
      return true;
    })();
  )";
  EXPECT_TRUE(ExecJs(web_contents().GetPrimaryMainFrame(), script));

  const GURL prerender_url = GetUrl("/prerender/empty.html?2");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});
  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  prerender_helper().NavigatePrimaryPage(prerender_url);

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kUnspecified, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);

  histogram_tester().ExpectTotalCount(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      0);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/prerender/empty.html", .sec_purpose_header_value = ""},
      {.path = "/prerender/sw_fallback.js", .sec_purpose_header_value = ""},
      {.path = "/prerender/empty.html?2",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue},
  };
  ASSERT_EQ(expected, GetObservedRequests());
}

// Variant of PrefetchNotEligibleServiceWorkerPrerenderSuccess.
// Eligibility check with delay.
//
// Scenario:
//
// - URL U has a service worker.
// - Trigger prefetch ahead of prerender A for URL U.
// - Trigger prerender A' for URL U.
//   - A blocks A'.
// - A failed in eligibility check due to SW.
//   - A' falls back to non-prefetch navigation.
// - Navigation is started. A' is used.
IN_PROC_BROWSER_TEST_P(
    PrerendererImplBrowserTestPrefetchAhead,
    PrefetchNotEligibleServiceWorkerPrerenderSuccessWithDelay) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/prerender/empty.html")));

  std::string script = R"(
    (async () => {
      await navigator.serviceWorker.register('./sw_fallback.js');
      await navigator.serviceWorker.ready;
      return true;
    })();
  )";
  EXPECT_TRUE(ExecJs(web_contents().GetPrimaryMainFrame(), script));

  PrefetchServiceInjectedEligibilityCheckFuture
      eligibility_check_callback_future(
          *PrefetchService::GetFromFrameTreeNodeId(
              web_contents().GetPrimaryMainFrame()->GetFrameTreeNodeId()));

  const GURL prerender_url = GetUrl("/prerender/empty.html?2");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});

  base::PlatformThread::Sleep(base::Milliseconds(101));

  // Proceed to the eligibility check.
  eligibility_check_callback_future->Take().Run(
      PreloadingEligibility::kEligible);

  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  prerender_helper().NavigatePrimaryPage(prerender_url);

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kUnspecified, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);

  histogram_tester().ExpectTotalCount(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      0);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/prerender/empty.html", .sec_purpose_header_value = ""},
      {.path = "/prerender/sw_fallback.js", .sec_purpose_header_value = ""},
      {.path = "/prerender/empty.html?2",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue},
  };
  ASSERT_EQ(expected, GetObservedRequests());
}

// Scenario:
//
// - Trigger prefetch ahead of prerender A for URL U.
// - Trigger prerender A' for URL U.
//   - A blocks A'.
// - A failed due to timeout.
//   - The failure is propagated to A'.
// - Navigation is started. No preloads are used.
IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchTimeoutPrerenderFailure) {
  // Prefetch will fail as
  // `prefetch_timeout_ms = 1500 < response_delay_ = 1500 + 1000`.
  SetResponseDelay(base::Milliseconds(1500 + 1000));

  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));
  preload_serving_metrics_list().clear();

  const GURL prerender_url = GetUrl("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});
  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  ASSERT_TRUE(NavigateToURL(shell(), prerender_url));

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kPrerenderFailedDuringPrefetch, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrefetchAheadOfPrerenderFailed.PrefetchStatus."
      "SpeculationRule",
      PrefetchStatus::kPrefetchNotFinishedInTime, 1);

  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      1, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      // Prefetch and prerender, timed out and aborted.
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue},
      // Normal navigation.
      {.path = "/title1.html", .sec_purpose_header_value = ""}};
  ASSERT_EQ(expected, GetObservedRequests());

  ASSERT_EQ(2u, preload_serving_metrics_list().size());

  auto& prerender_initial_preload_serving_metrics =
      preload_serving_metrics_list()[0];
  // Taken and used to record UMAs.
  ASSERT_FALSE(prerender_initial_preload_serving_metrics);

  auto& preload_serving_metrics = preload_serving_metrics_list()[1];
  ASSERT_TRUE(preload_serving_metrics);
  ASSERT_EQ(1u, preload_serving_metrics->prefetch_match_metrics_list.size());
  ASSERT_EQ(0u, preload_serving_metrics->prefetch_match_metrics_list[0]
                    ->n_initial_candidates);
  ASSERT_EQ(0u, preload_serving_metrics->prefetch_match_metrics_list[0]
                    ->n_initial_candidates_block_until_head);
  ASSERT_FALSE(preload_serving_metrics->prefetch_match_metrics_list[0]
                   ->prefetch_container_metrics);
  ASSERT_FALSE(preload_serving_metrics->prefetch_match_metrics_list[0]
                   ->prefetch_container_metrics_ahead_of_prerender);
  ASSERT_FALSE(
      preload_serving_metrics->prefetch_match_metrics_list[0]
          ->prefetch_potential_candidate_serving_result_ahead_of_prerender);
  ASSERT_FALSE(
      preload_serving_metrics->prerender_initial_preload_serving_metrics);
}

// A variant of PrefetchTimeoutPrerenderFailure, where the navigation is started
// while prefetch is ongoing and thus the prefetch-ahead-prerender failure
// occurs during the navigation.
//
// Scenario:
//
// - Trigger prefetch ahead of prerender A for URL U.
// - Trigger prerender A' for URL U.
//   - A blocks A'.
// - Navigation is started.
//   - A' blocks it.
// - A failed due to timeout.
//   - The failure is propagated to A'.
//   - It unblocks the navigation.
// - No preloads are used.
IN_PROC_BROWSER_TEST_P(
    PrerendererImplBrowserTestPrefetchAhead,
    PrefetchTimeoutNavigationStartedWithoutWaitForPrerenderPrerenderFailure) {
  // Prefetch will fail as
  // `prefetch_timeout_ms = 1500 < response_delay_ = 1500 + 1000`.
  SetResponseDelay(base::Milliseconds(1500 + 1000));

  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));
  preload_serving_metrics_list().clear();

  const GURL prerender_url = GetUrl("/title1.html");
  blink::mojom::SpeculationCandidatePtr candidate =
      CreateSpeculationCandidate(prerender_url);
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                      PreloadingConfidence{100});
  // Don't `prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);`
  // here, different from PrefetchTimeoutPrerenderFailure.

  ASSERT_TRUE(NavigateToURLFromRenderer(shell(), prerender_url));

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kPrerenderFailedDuringPrefetch, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrefetchAheadOfPrerenderFailed.PrefetchStatus."
      "SpeculationRule",
      PrefetchStatus::kPrefetchNotFinishedInTime, 1);

  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      1, 1);
  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.IsPotentialMatch",
      true, 1);
  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.PotentialMatchThen.NumberOfInitialCandidates",
      1, 1);
  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.PotentialMatchThen."
      "NumberOfInitialCandidatesBlockUntilHead",
      1, 1);
  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.PotentialMatchThen.IsActualMatch",
      false, 1);
  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.IsPotentialMatch.WithAheadOfPrerender",
      true, 1);
  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.PotentialMatchThen.WithAheadOfPrerender."
      "PotentialCandidateServingResult",
      PrefetchPotentialCandidateServingResult::kNotServedBlockUntilHeadTimeout,
      1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      // Prefetch and prerender, timed out and aborted.
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue},
      // Normal navigation.
      {.path = "/title1.html", .sec_purpose_header_value = ""}};
  ASSERT_EQ(expected, GetObservedRequests());

  ASSERT_EQ(2u, preload_serving_metrics_list().size());

  auto& prerender_initial_preload_serving_metrics =
      preload_serving_metrics_list()[0];
  // Taken and used to record UMAs.
  ASSERT_FALSE(prerender_initial_preload_serving_metrics);

  auto& preload_serving_metrics = preload_serving_metrics_list()[1];
  ASSERT_EQ(1u, preload_serving_metrics->prefetch_match_metrics_list.size());
  ASSERT_EQ(1u, preload_serving_metrics->prefetch_match_metrics_list[0]
                    ->n_initial_candidates);
  ASSERT_EQ(1u, preload_serving_metrics->prefetch_match_metrics_list[0]
                    ->n_initial_candidates_block_until_head);
  ASSERT_FALSE(preload_serving_metrics->prefetch_match_metrics_list[0]
                   ->prefetch_container_metrics);
  ASSERT_FALSE(preload_serving_metrics->prefetch_match_metrics_list[0]
                   ->prefetch_container_metrics_ahead_of_prerender);
  ASSERT_FALSE(
      preload_serving_metrics->prefetch_match_metrics_list[0]
          ->prefetch_potential_candidate_serving_result_ahead_of_prerender);
  ASSERT_FALSE(
      preload_serving_metrics->prerender_initial_preload_serving_metrics);
}

// Consider a case that a site uses a SpecRules containing prefetch and
// prerender for a URL U.
//
// Scenario:
//
// - Trigger prefetch A a URL U.
// - Trigger prefetch ahead of prerender B for URL U.
//   - B is migrated into A. A inherits `PreloadPipelineInfo` and is considered
//     as `IsLikelyAheadOfPrerender`.
// - Trigger prerender B' for URL U.
//   - A blocks B'.
// - Navigation is started. B' is used.
IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchMigratedPrefetchSuccessPrerenderSuccess) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    candidate->action = blink::mojom::SpeculationAction::kPrefetch;
    GetPrefetcher().MaybePrefetch(std::move(candidate), enacting_predictor);
  }
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                        PreloadingConfidence{100});
  }

  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  prerender_helper().NavigatePrimaryPage(prerender_url);

  EXPECT_THAT(
      histogram_tester().GetAllSamples(
          "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome"),
      testing::ElementsAre(
          base::Bucket(PreloadingTriggeringOutcome::kUnspecified, 1),
          base::Bucket(PreloadingTriggeringOutcome::kSuccess, 1)));
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);

  histogram_tester().ExpectTotalCount(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      0);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value = blink::kSecPurposePrefetchHeaderValue}};
  ASSERT_EQ(expected, GetObservedRequests());
}

// Variant of PrefetchMigratedPrefetchSuccessPrerenderSuccess.
// The order of migration and prefetch completion is reversed.
IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchSuccessPrefetchMigratedPrerenderSuccess) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  {
    test::TestPrefetchWatcher watcher;
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    candidate->action = blink::mojom::SpeculationAction::kPrefetch;
    GetPrefetcher().MaybePrefetch(std::move(candidate), enacting_predictor);
    watcher.WaitUntilPrefetchResponseCompleted(
        web_contents_impl().GetPrimaryMainFrame()->GetDocumentToken(),
        prerender_url);
  }
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                        PreloadingConfidence{100});
  }

  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  prerender_helper().NavigatePrimaryPage(prerender_url);

  EXPECT_THAT(
      histogram_tester().GetAllSamples(
          "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome"),
      testing::ElementsAre(
          base::Bucket(PreloadingTriggeringOutcome::kUnspecified, 1),
          base::Bucket(PreloadingTriggeringOutcome::kSuccess, 1)));
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kSuccess, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kActivated, 1);

  histogram_tester().ExpectTotalCount(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      0);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value = blink::kSecPurposePrefetchHeaderValue}};
  ASSERT_EQ(expected, GetObservedRequests());
}

// Scenario:
//
// - Trigger prefetch A a URL U.
// - Eligibility check for A is done.
// - Trigger prefetch ahead of prerender B for URL U.
//   - B is migrated into A. A inherits `PreloadPipelineInfo` and is considered
//     as `IsLikelyAheadOfPrerender`. Eligibility of A is propagated to the
//     `PreloadPipelineInfo`.
// - Trigger prerender B' for URL U.
//   - A blocks B'.
// - A fails by timeout.
// - Navigation is started. No preloads are used.
//
// This shows the necessity of eligibility propagation in
// `PrefetchContainer::MigrateNewlyAdded()`.
IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchMigratedPrefetchFailurePrerenderFailure) {
  // Prefetch will fail as
  // `prefetch_timeout_ms = 1500 < response_delay_ = 1500 + 1000`.
  SetResponseDelay(base::Milliseconds(1500 + 1000));

  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    candidate->action = blink::mojom::SpeculationAction::kPrefetch;
    GetPrefetcher().MaybePrefetch(std::move(candidate), enacting_predictor);
  }

  // Ensure that eligibility check is done.
  base::PlatformThread::Sleep(base::Milliseconds(101));

  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                        PreloadingConfidence{100});
  }

  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  ASSERT_TRUE(NavigateToURL(shell(), prerender_url));

  EXPECT_THAT(
      histogram_tester().GetAllSamples(
          "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome"),
      testing::ElementsAre(
          base::Bucket(PreloadingTriggeringOutcome::kUnspecified, 1),
          base::Bucket(PreloadingTriggeringOutcome::kFailure, 1)));
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kPrerenderFailedDuringPrefetch, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrefetchAheadOfPrerenderFailed.PrefetchStatus."
      "SpeculationRule",
      PrefetchStatus::kPrefetchNotFinishedInTime, 1);

  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      1, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value = blink::kSecPurposePrefetchHeaderValue},
      {.path = "/title1.html", .sec_purpose_header_value = ""}};
  ASSERT_EQ(expected, GetObservedRequests());
}

// Scenario:
//
// - Trigger prefetch A.
// - Trigger prefetch ahead of prerender B for URL U.
//   - B is migrated into A. A inherits `PreloadPipelineInfo` and is considered
//     as `IsLikelyAheadOfPrerender`.
// - Trigger prerender B' for URL U.
// - A fails in eligibility check.
//   - B' fails as the ineligibility is not admissible.
// - Navigation is started. No preloads are used.
IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchMigratedPrefetchNotEligiblePrerenderFailure) {
  PrefetchServiceInjectedEligibilityCheckFuture
      eligibility_check_callback_future(
          *PrefetchService::GetFromFrameTreeNodeId(
              web_contents().GetPrimaryMainFrame()->GetFrameTreeNodeId()));

  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    candidate->action = blink::mojom::SpeculationAction::kPrefetch;
    GetPrefetcher().MaybePrefetch(std::move(candidate), enacting_predictor);
  }
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                        PreloadingConfidence{100});
  }

  // Resume the eligibility check of the first prefetch and make it fail with
  // `kHostIsNonUnique`.
  eligibility_check_callback_future->Take().Run(
      PreloadingEligibility::kHostIsNonUnique);

  // Here we shouldn't call
  // `prerender_helper().WaitForPrerenderLoadCompletion(prerender_url)` since
  // the call first tries to get `PrerenderHost`, which has been already
  // destructed.

  prerender_helper().NavigatePrimaryPage(prerender_url);

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kUnspecified, 2);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kPrerenderFailedDuringPrefetch, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrefetchAheadOfPrerenderFailed.PrefetchStatus."
      "SpeculationRule",
      PrefetchStatus::kPrefetchIneligibleHostIsNonUnique, 1);

  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      1, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html", .sec_purpose_header_value = ""},
  };
  ASSERT_EQ(expected, GetObservedRequests());
}

// Consider a case that a site uses a SpecRules containing prefetch and
// prerender for a URL U.
//
// Scenario:
//
// - Trigger prefetch A a URL U.
// - Trigger prefetch ahead of prerender B for URL U.
//   - B is migrated into A. A inherits `PreloadPipelineInfo` and is considered
//     as `IsLikelyAheadOfPrerender`.
// - Trigger prerender B' for URL U.
//   - A blocks B'.
// - A failed due to timeout.
//   - The failure is propagated to B'.
// - Navigation is started. No preloads are used.
IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrefetchMigratedPrefetchTimeoutPrerenderFailure) {
  // Prefetch will fail as
  // `prefetch_timeout_ms = 1500 < response_delay_ = 1500 + 1000`.
  SetResponseDelay(base::Milliseconds(1500 + 1000));

  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    candidate->action = blink::mojom::SpeculationAction::kPrefetch;
    GetPrefetcher().MaybePrefetch(std::move(candidate), enacting_predictor);
  }
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                        PreloadingConfidence{100});
  }

  prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

  ASSERT_TRUE(NavigateToURL(shell(), prerender_url));

  EXPECT_THAT(
      histogram_tester().GetAllSamples(
          "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome"),
      testing::ElementsAre(
          base::Bucket(PreloadingTriggeringOutcome::kUnspecified, 1),
          base::Bucket(PreloadingTriggeringOutcome::kFailure, 1)));
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kPrerenderFailedDuringPrefetch, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrefetchAheadOfPrerenderFailed.PrefetchStatus."
      "SpeculationRule",
      PrefetchStatus::kPrefetchNotFinishedInTime, 1);

  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      1, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      // Prefetch and prerender, timed out and aborted.
      {.path = "/title1.html",
       .sec_purpose_header_value = blink::kSecPurposePrefetchHeaderValue},
      // Normal navigation.
      {.path = "/title1.html", .sec_purpose_header_value = ""}};
  ASSERT_EQ(expected, GetObservedRequests());
}

// Scenario:
//
// - Trigger prefetch ahead of prerender A for URL U.
// - Trigger prerender A' for URL U.
//   - A blocks A'.
// - Prefetch matching process ended due to timeout. A' is aborted.
// - A received response and succeeded.
// - Navigation is started. A is used.
//
// TODO(crbug.com/372851198): The scenario described does not seem to work as
// desired. A second request is made to /title1.html, and
// `PrefetchContainer::Reader::OnPrefetchProbeResult()` is not called. Before
// https://chromium-review.googlesource.com/c/chromium/src/+/6056830, the second
// request was avoided due to the HTTP cache, but after that change the overall
// brokenness of the scenario is revealed. It is likely that the /title1.html
// response is not making it into the speculation rules prefetch cache.
IN_PROC_BROWSER_TEST_P(
    PrerendererImplBrowserTestPrefetchAhead,
    DISABLED_PrefetchSuccessPrefetchMatchResolverTimeoutPrerenderFailure) {
  SetResponseDelay(base::Milliseconds(1000));

  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  {
    test::TestPrefetchWatcher watcher;

    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    // Use `kModerate` to trigger `PrefetchMatchResolver::OnTimeout()`.
    // Note that `block_until_head_timeout_moderate_prefetch = 500 <
    // response_delay_ = 1000 < prefetch_timeout_ms = 1500`.
    candidate->eagerness = blink::mojom::SpeculationEagerness::kModerate;
    PreloadingPredictor enacting_predictor =
        GetPredictorForPreloadingTriggerType(
            PreloadingTriggerType::kSpeculationRule);
    GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                        PreloadingConfidence{100});

    prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

    watcher.WaitUntilPrefetchResponseCompleted(
        web_contents_impl().GetPrimaryMainFrame()->GetDocumentToken(),
        prerender_url);
  }

  ASSERT_TRUE(NavigateToURL(shell(), prerender_url));

  histogram_tester().ExpectUniqueSample(
      "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kReady, 1);
  histogram_tester().ExpectUniqueSample(
      "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome",
      PreloadingTriggeringOutcome::kFailure, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
      PrerenderFinalStatus::kPrerenderFailedDuringPrefetch, 1);
  histogram_tester().ExpectUniqueSample(
      "Prerender.Experimental.PrefetchAheadOfPrerenderFailed.PrefetchStatus."
      "SpeculationRule",
      PrefetchStatus::kPrefetchNotFinishedInTime, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      // Prerender is aborted, but prefetch is success and used.
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue}};
  ASSERT_EQ(expected, GetObservedRequests());
}

// Consider a case that a site inserted a SpecRules for prerender, removed it,
// and inserted again.
//
// Scenario:
//
// - Trigger prefetch ahead of prerender A for URL U.
// - Trigger prerender A' for URL U.
//   - A' uses A.
// - A' is cancelled.
// - Trigger prefetch ahead of prerender B for URL U.
//   - B is migrated into A. A inherits `PreloadPipelineInfo`.
// - Trigger prerender B' for URL U.
//   - B' uses A.
// - Navigation is started. B' is used.
IN_PROC_BROWSER_TEST_P(PrerendererImplBrowserTestPrefetchAhead,
                       PrerenderSuccessCancelledAnotherPrerenderSuccess) {
  ASSERT_TRUE(NavigateToURL(shell(), GetUrl("/empty.html")));

  const GURL prerender_url = GetUrl("/title1.html");
  PreloadingPredictor enacting_predictor = GetPredictorForPreloadingTriggerType(
      PreloadingTriggerType::kSpeculationRule);
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                        PreloadingConfidence{100});
    prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);

    GetPrerendererImpl().CancelStartedPrerendersForTesting();
  }
  {
    blink::mojom::SpeculationCandidatePtr candidate =
        CreateSpeculationCandidate(prerender_url);
    GetPrerendererImpl().MaybePrerender(candidate, enacting_predictor,
                                        PreloadingConfidence{100});
    prerender_helper().WaitForPrerenderLoadCompletion(prerender_url);
  }

  prerender_helper().NavigatePrimaryPage(prerender_url);

  EXPECT_THAT(
      histogram_tester().GetAllSamples(
          "Preloading.Prefetch.Attempt.SpeculationRules.TriggeringOutcome"),
      testing::ElementsAre(
          base::Bucket(PreloadingTriggeringOutcome::kSuccess, 1)));
  EXPECT_THAT(
      histogram_tester().GetAllSamples(
          "Preloading.Prerender.Attempt.SpeculationRules.TriggeringOutcome"),
      testing::ElementsAre(
          base::Bucket(PreloadingTriggeringOutcome::kReady, 1),
          base::Bucket(PreloadingTriggeringOutcome::kSuccess, 1)));
  EXPECT_THAT(
      histogram_tester().GetAllSamples(
          "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule"),
      testing::ElementsAre(
          base::Bucket(PrerenderFinalStatus::kActivated, 1),
          base::Bucket(PrerenderFinalStatus::kTriggerDestroyed, 1)));

  histogram_tester().ExpectUniqueSample(
      "PreloadServingMetrics.ForPrerenderInitialNavigationFailed."
      "PrefetchMatchMetrics.Count",
      1, 1);

  std::vector<RequestPathAndSecPurposeHeader> expected{
      {.path = "/empty.html", .sec_purpose_header_value = ""},
      {.path = "/title1.html",
       .sec_purpose_header_value =
           blink::kSecPurposePrefetchPrerenderHeaderValue}};
  ASSERT_EQ(expected, GetObservedRequests());
}

}  // namespace
}  // namespace content
