blob: 0757b282410da3534e48b193ac47fd1d01511e66 [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 <memory>
#include <string>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "chrome/browser/availability/availability_prober.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/network_service_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/network_connection_change_simulator.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/mojom/network_service_test.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
namespace {
void WaitForCompletedProbe(AvailabilityProber* prober) {
while (true) {
if (prober->LastProbeWasSuccessful().has_value())
return;
base::RunLoop().RunUntilIdle();
}
}
} // namespace
class TestDelegate : public AvailabilityProber::Delegate {
public:
TestDelegate() = default;
~TestDelegate() = default;
bool ShouldSendNextProbe() override { return should_send_next_probe_; }
bool IsResponseSuccess(net::Error net_error,
const network::mojom::URLResponseHead* head,
std::unique_ptr<std::string> body) override {
got_head_ = head;
return net_error == net::OK && head &&
head->headers->response_code() == net::HTTP_OK;
}
void set_should_send_next_probe(bool should_send_next_probe) {
should_send_next_probe_ = should_send_next_probe;
}
bool got_head() const { return got_head_; }
private:
bool should_send_next_probe_ = true;
bool got_head_ = false;
};
class AvailabilityProberBrowserTest : public InProcessBrowserTest {
public:
AvailabilityProberBrowserTest() = default;
~AvailabilityProberBrowserTest() override = default;
void SetUpOnMainThread() override {
https_server_ = std::make_unique<net::EmbeddedTestServer>(
net::EmbeddedTestServer::TYPE_HTTPS);
https_server_->RegisterRequestHandler(base::BindRepeating(
&AvailabilityProberBrowserTest::HandleRequest, base::Unretained(this)));
ASSERT_TRUE(https_server_->Start());
}
void SetUpCommandLine(base::CommandLine* cmd) override {
cmd->AppendSwitchASCII("host-rules", "MAP test.com 127.0.0.1");
}
void TearDownOnMainThread() override {
EXPECT_TRUE(https_server_->ShutdownAndWaitUntilComplete());
InProcessBrowserTest::TearDownOnMainThread();
}
GURL TestURLWithPath(const std::string& path) const {
return https_server_->GetURL("test.com", path);
}
private:
std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
const net::test_server::HttpRequest& request) {
std::string path = request.GetURL().path();
if (path == "/ok") {
std::unique_ptr<net::test_server::BasicHttpResponse> response =
std::make_unique<net::test_server::BasicHttpResponse>();
response->set_code(net::HTTP_OK);
return response;
}
if (path == "/timeout") {
std::unique_ptr<net::test_server::HungResponse> response =
std::make_unique<net::test_server::HungResponse>();
return response;
}
NOTREACHED() << path << " is not handled";
return nullptr;
}
std::unique_ptr<net::EmbeddedTestServer> https_server_;
DISALLOW_COPY_AND_ASSIGN(AvailabilityProberBrowserTest);
};
IN_PROC_BROWSER_TEST_F(AvailabilityProberBrowserTest, OK) {
GURL url = TestURLWithPath("/ok");
TestDelegate delegate;
net::HttpRequestHeaders headers;
AvailabilityProber::RetryPolicy retry_policy;
AvailabilityProber::TimeoutPolicy timeout_policy;
AvailabilityProber prober(
&delegate, browser()->profile()->GetURLLoaderFactory(),
browser()->profile()->GetPrefs(),
AvailabilityProber::ClientName::kIsolatedPrerenderOriginCheck, url,
AvailabilityProber::HttpMethod::kGet, headers, retry_policy,
timeout_policy, TRAFFIC_ANNOTATION_FOR_TESTS, 1,
base::TimeDelta::FromDays(1));
prober.SendNowIfInactive(false);
WaitForCompletedProbe(&prober);
EXPECT_TRUE(prober.LastProbeWasSuccessful().value());
}
IN_PROC_BROWSER_TEST_F(AvailabilityProberBrowserTest, Timeout) {
GURL url = TestURLWithPath("/timeout");
TestDelegate delegate;
net::HttpRequestHeaders headers;
AvailabilityProber::RetryPolicy retry_policy;
retry_policy.max_retries = 0;
AvailabilityProber::TimeoutPolicy timeout_policy;
timeout_policy.base_timeout = base::TimeDelta::FromMilliseconds(1);
AvailabilityProber prober(
&delegate, browser()->profile()->GetURLLoaderFactory(),
browser()->profile()->GetPrefs(),
AvailabilityProber::ClientName::kIsolatedPrerenderOriginCheck, url,
AvailabilityProber::HttpMethod::kGet, headers, retry_policy,
timeout_policy, TRAFFIC_ANNOTATION_FOR_TESTS, 1,
base::TimeDelta::FromDays(1));
prober.SendNowIfInactive(false);
WaitForCompletedProbe(&prober);
EXPECT_FALSE(prober.LastProbeWasSuccessful().value());
}
IN_PROC_BROWSER_TEST_F(AvailabilityProberBrowserTest, NetworkChange) {
content::NetworkConnectionChangeSimulator().SetConnectionType(
network::mojom::ConnectionType::CONNECTION_2G);
GURL url = TestURLWithPath("/ok");
TestDelegate delegate;
net::HttpRequestHeaders headers;
AvailabilityProber::RetryPolicy retry_policy;
AvailabilityProber::TimeoutPolicy timeout_policy;
AvailabilityProber prober(
&delegate, browser()->profile()->GetURLLoaderFactory(),
browser()->profile()->GetPrefs(),
AvailabilityProber::ClientName::kIsolatedPrerenderOriginCheck, url,
AvailabilityProber::HttpMethod::kGet, headers, retry_policy,
timeout_policy, TRAFFIC_ANNOTATION_FOR_TESTS, 1,
base::TimeDelta::FromDays(1));
content::NetworkConnectionChangeSimulator().SetConnectionType(
network::mojom::ConnectionType::CONNECTION_4G);
WaitForCompletedProbe(&prober);
EXPECT_TRUE(prober.LastProbeWasSuccessful().value());
}
IN_PROC_BROWSER_TEST_F(AvailabilityProberBrowserTest, BadServer) {
GURL url("https://invalid.com");
TestDelegate delegate;
net::HttpRequestHeaders headers;
AvailabilityProber::RetryPolicy retry_policy;
AvailabilityProber::TimeoutPolicy timeout_policy;
AvailabilityProber prober(
&delegate, browser()->profile()->GetURLLoaderFactory(),
browser()->profile()->GetPrefs(),
AvailabilityProber::ClientName::kIsolatedPrerenderOriginCheck, url,
AvailabilityProber::HttpMethod::kGet, headers, retry_policy,
timeout_policy, TRAFFIC_ANNOTATION_FOR_TESTS, 1,
base::TimeDelta::FromDays(1));
prober.SendNowIfInactive(false);
WaitForCompletedProbe(&prober);
EXPECT_FALSE(delegate.got_head());
EXPECT_FALSE(prober.LastProbeWasSuccessful().value());
}