blob: 7a8f50ebd84bec6eef46e82950fefde0f0de878c [file] [log] [blame]
// Copyright 2017 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 <string>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/guid.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/profile_network_context_service.h"
#include "chrome/browser/net/profile_network_context_service_factory.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/prefs/pref_service.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/simple_url_loader_test_helper.h"
#include "mojo/common/data_pipe_utils.h"
#include "net/base/filename_util.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.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/test/spawned_test_server/spawned_test_server.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/resource_response_info.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/test/test_url_loader_client.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char kCacheRandomPath[] = "/cacherandom";
enum class NetworkServiceState {
kDisabled,
kEnabled,
// Similar to |kEnabled|, but will simulate a crash and run tests again the
// restarted Network Service process.
kRestarted,
};
enum class NetworkContextType {
kSystem,
kProfile,
kIncognitoProfile,
};
struct TestCase {
NetworkServiceState network_service_state;
NetworkContextType network_context_type;
};
// Tests the system, profile, and incognito profile NetworkContexts.
class NetworkContextConfigurationBrowserTest
: public InProcessBrowserTest,
public testing::WithParamInterface<TestCase> {
public:
// Backing storage types that can used for various things (HTTP cache,
// cookies, etc).
enum class StorageType {
kNone,
kMemory,
kDisk,
};
NetworkContextConfigurationBrowserTest() {
embedded_test_server()->RegisterRequestHandler(
base::Bind(&NetworkContextConfigurationBrowserTest::HandleCacheRandom));
EXPECT_TRUE(embedded_test_server()->Start());
}
// Returns a cacheable response (10 hours) that is some random text.
static std::unique_ptr<net::test_server::HttpResponse> HandleCacheRandom(
const net::test_server::HttpRequest& request) {
if (request.relative_url != kCacheRandomPath)
return nullptr;
std::unique_ptr<net::test_server::BasicHttpResponse> response =
std::make_unique<net::test_server::BasicHttpResponse>();
response->set_content(base::GenerateGUID());
response->set_content_type("text/plain");
response->AddCustomHeader("Cache-Control", "max-age=60000");
return std::move(response);
}
~NetworkContextConfigurationBrowserTest() override {}
void SetUpInProcessBrowserTestFixture() override {
if (GetParam().network_service_state != NetworkServiceState::kDisabled)
feature_list_.InitAndEnableFeature(network::features::kNetworkService);
}
void SetUpOnMainThread() override {
if (GetParam().network_context_type ==
NetworkContextType::kIncognitoProfile) {
incognito_ = CreateIncognitoBrowser();
}
SimulateNetworkServiceCrashIfNecessary();
}
// Returns, as a string, a PAC script that will use the EmbeddedTestServer as
// a proxy.
std::string GetPacScript() const {
return base::StringPrintf(
"function FindProxyForURL(url, host){ return 'PROXY %s;'; }",
net::HostPortPair::FromURL(embedded_test_server()->base_url())
.ToString()
.c_str());
}
network::mojom::URLLoaderFactory* loader_factory() const {
switch (GetParam().network_context_type) {
case NetworkContextType::kSystem:
return g_browser_process->system_network_context_manager()
->GetURLLoaderFactory();
case NetworkContextType::kProfile:
return content::BrowserContext::GetDefaultStoragePartition(
browser()->profile())
->GetURLLoaderFactoryForBrowserProcess()
.get();
case NetworkContextType::kIncognitoProfile:
DCHECK(incognito_);
return content::BrowserContext::GetDefaultStoragePartition(
incognito_->profile())
->GetURLLoaderFactoryForBrowserProcess()
.get();
}
NOTREACHED();
return nullptr;
}
network::mojom::NetworkContext* network_context() const {
switch (GetParam().network_context_type) {
case NetworkContextType::kSystem:
return g_browser_process->system_network_context_manager()
->GetContext();
case NetworkContextType::kProfile:
return content::BrowserContext::GetDefaultStoragePartition(
browser()->profile())
->GetNetworkContext();
case NetworkContextType::kIncognitoProfile:
DCHECK(incognito_);
return content::BrowserContext::GetDefaultStoragePartition(
incognito_->profile())
->GetNetworkContext();
}
NOTREACHED();
return nullptr;
}
StorageType GetHttpCacheType() const {
switch (GetParam().network_context_type) {
case NetworkContextType::kSystem:
return StorageType::kNone;
case NetworkContextType::kProfile:
return StorageType::kDisk;
case NetworkContextType::kIncognitoProfile:
return StorageType::kMemory;
}
NOTREACHED();
return StorageType::kNone;
}
// Sets the proxy preference on a PrefService based on the NetworkContextType,
// and waits for it to be applied.
void SetProxyPref(const net::HostPortPair& host_port_pair) {
// Get the correct PrefService.
PrefService* pref_service = nullptr;
switch (GetParam().network_context_type) {
case NetworkContextType::kSystem:
pref_service = g_browser_process->local_state();
break;
case NetworkContextType::kProfile:
pref_service = browser()->profile()->GetPrefs();
break;
case NetworkContextType::kIncognitoProfile:
// Incognito uses the non-incognito prefs.
pref_service =
browser()->profile()->GetOffTheRecordProfile()->GetPrefs();
break;
}
pref_service->Set(proxy_config::prefs::kProxy,
*ProxyConfigDictionary::CreateFixedServers(
host_port_pair.ToString(), std::string()));
// Wait for the new ProxyConfig to be passed over the pipe. Needed because
// Mojo doesn't guarantee ordering of events on different Mojo pipes, and
// requests are sent on a separate pipe from ProxyConfigs.
switch (GetParam().network_context_type) {
case NetworkContextType::kSystem:
g_browser_process->system_network_context_manager()
->FlushProxyConfigMonitorForTesting();
break;
case NetworkContextType::kProfile:
ProfileNetworkContextServiceFactory::GetForContext(browser()->profile())
->FlushProxyConfigMonitorForTesting();
break;
case NetworkContextType::kIncognitoProfile:
ProfileNetworkContextServiceFactory::GetForContext(
browser()->profile()->GetOffTheRecordProfile())
->FlushProxyConfigMonitorForTesting();
break;
}
}
// Sends a request and expects it to be handled by embedded_test_server()
// acting as a proxy;
void TestProxyConfigured() {
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
// This URL should be directed to the test server because of the proxy.
request->url = GURL("http://jabberwocky.test:1872/echo");
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
EXPECT_EQ(net::OK, simple_loader->NetError());
ASSERT_TRUE(simple_loader_helper.response_body());
EXPECT_EQ(*simple_loader_helper.response_body(), "Echo");
}
private:
void SimulateNetworkServiceCrashIfNecessary() {
if (GetParam().network_service_state != NetworkServiceState::kRestarted)
return;
// Make sure |network_context()| is working as expected. Use '/echoheader'
// instead of '/echo' to avoid a disk_cache bug.
// See https://crbug.com/792255.
int net_error = content::LoadBasicRequest(
network_context(), embedded_test_server()->GetURL("/echoheader"));
// The error code could be |net::ERR_PROXY_CONNECTION_FAILED| if the test is
// using 'bad_server.pac'.
EXPECT_TRUE(net_error == net::OK ||
net_error == net::ERR_PROXY_CONNECTION_FAILED);
// Crash the NetworkService process. Existing interfaces should receive
// error notifications at some point.
content::SimulateNetworkServiceCrash();
// Flush the interface to make sure the error notification was received.
FlushNetworkInterface();
}
void FlushNetworkInterface() {
switch (GetParam().network_context_type) {
case NetworkContextType::kSystem:
g_browser_process->system_network_context_manager()
->FlushNetworkInterfaceForTesting();
break;
case NetworkContextType::kProfile:
content::BrowserContext::GetDefaultStoragePartition(
browser()->profile())
->FlushNetworkInterfaceForTesting();
break;
case NetworkContextType::kIncognitoProfile:
DCHECK(incognito_);
content::BrowserContext::GetDefaultStoragePartition(
incognito_->profile())
->FlushNetworkInterfaceForTesting();
break;
}
}
Browser* incognito_ = nullptr;
base::test::ScopedFeatureList feature_list_;
DISALLOW_COPY_AND_ASSIGN(NetworkContextConfigurationBrowserTest);
};
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, BasicRequest) {
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = embedded_test_server()->GetURL("/echo");
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
ASSERT_TRUE(simple_loader->ResponseInfo());
ASSERT_TRUE(simple_loader->ResponseInfo()->headers);
EXPECT_EQ(200, simple_loader->ResponseInfo()->headers->response_code());
ASSERT_TRUE(simple_loader_helper.response_body());
EXPECT_EQ("Echo", *simple_loader_helper.response_body());
}
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, DataURL) {
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = GURL("data:text/plain,foo");
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
ASSERT_TRUE(simple_loader->ResponseInfo());
// Data URLs don't have headers.
EXPECT_FALSE(simple_loader->ResponseInfo()->headers);
EXPECT_EQ("text/plain", simple_loader->ResponseInfo()->mime_type);
ASSERT_TRUE(simple_loader_helper.response_body());
EXPECT_EQ("foo", *simple_loader_helper.response_body());
}
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, FileURL) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::ScopedTempDir temp_dir_;
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath file_path;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path));
const char kFileContents[] = "This file intentionally left empty.";
ASSERT_EQ(static_cast<int>(strlen(kFileContents)),
base::WriteFile(file_path, kFileContents, strlen(kFileContents)));
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = net::FilePathToFileURL(file_path);
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
ASSERT_TRUE(simple_loader->ResponseInfo());
// File URLs don't have headers.
EXPECT_FALSE(simple_loader->ResponseInfo()->headers);
ASSERT_TRUE(simple_loader_helper.response_body());
EXPECT_EQ(kFileContents, *simple_loader_helper.response_body());
}
// Make sure a cache is used when expected.
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, Cache) {
// Make a request whose response should be cached.
GURL request_url = embedded_test_server()->GetURL("/cachetime");
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = request_url;
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
ASSERT_TRUE(simple_loader_helper.response_body());
EXPECT_GT(simple_loader_helper.response_body()->size(), 0u);
// Stop the server.
ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
// Make the request again, and make sure it's cached or not, according to
// expectations. Reuse the content::ResourceRequest, but nothing else.
std::unique_ptr<network::ResourceRequest> request2 =
std::make_unique<network::ResourceRequest>();
request2->url = request_url;
content::SimpleURLLoaderTestHelper simple_loader_helper2;
std::unique_ptr<network::SimpleURLLoader> simple_loader2 =
network::SimpleURLLoader::Create(std::move(request2),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader2->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper2.GetCallback());
simple_loader_helper2.WaitForCallback();
if (GetHttpCacheType() == StorageType::kNone) {
// If there's no cache, and not server running, the request should have
// failed.
EXPECT_FALSE(simple_loader_helper2.response_body());
EXPECT_EQ(net::ERR_CONNECTION_REFUSED, simple_loader2->NetError());
} else {
// Otherwise, the request should have succeeded, and returned the same
// result as before.
ASSERT_TRUE(simple_loader_helper2.response_body());
EXPECT_EQ(*simple_loader_helper.response_body(),
*simple_loader_helper2.response_body());
}
}
// Make sure an on-disk cache is used when expected. PRE_DiskCache populates the
// cache. DiskCache then makes sure the cache entry is still there (Or not) as
// expected.
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, PRE_DiskCache) {
// Save test URL to disk, so it can be used in the next test (Test server uses
// a random port, so need to know the port to try and retrieve it from the
// cache in the next test). The profile directory is preserved between the
// PRE_DiskCache and DiskCache run, so can just keep a file there.
GURL test_url = embedded_test_server()->GetURL(kCacheRandomPath);
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath save_url_file_path = browser()->profile()->GetPath().Append(
FILE_PATH_LITERAL("url_for_test.txt"));
// Make a request whose response should be cached.
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = test_url;
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
EXPECT_EQ(net::OK, simple_loader->NetError());
ASSERT_TRUE(simple_loader_helper.response_body());
EXPECT_FALSE(simple_loader_helper.response_body()->empty());
// Write the URL and expected response to a file.
std::string file_data =
test_url.spec() + "\n" + *simple_loader_helper.response_body();
ASSERT_EQ(
static_cast<int>(file_data.length()),
base::WriteFile(save_url_file_path, file_data.data(), file_data.size()));
EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
}
// Check if the URL loaded in PRE_DiskCache is still in the cache, across a
// browser restart.
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, DiskCache) {
// Load URL from the above test body to disk.
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath save_url_file_path = browser()->profile()->GetPath().Append(
FILE_PATH_LITERAL("url_for_test.txt"));
std::string file_data;
ASSERT_TRUE(ReadFileToString(save_url_file_path, &file_data));
size_t newline_pos = file_data.find('\n');
ASSERT_NE(newline_pos, std::string::npos);
GURL test_url = GURL(file_data.substr(0, newline_pos));
ASSERT_TRUE(test_url.is_valid()) << test_url.possibly_invalid_spec();
std::string original_response = file_data.substr(newline_pos + 1);
// Request the same test URL as may have been cached by PRE_DiskCache.
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = test_url;
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
std::string response_body = simple_loader_helper.response_body()
? *simple_loader_helper.response_body()
: "";
// The response body from the above test should only appear in the response
// if there is an on-disk cache.
if (GetHttpCacheType() != StorageType::kDisk) {
EXPECT_NE(original_response, response_body);
} else {
EXPECT_EQ(original_response, response_body);
}
}
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, ProxyConfig) {
SetProxyPref(embedded_test_server()->host_port_pair());
TestProxyConfigured();
}
class NetworkContextConfigurationFixedPortBrowserTest
: public NetworkContextConfigurationBrowserTest {
public:
NetworkContextConfigurationFixedPortBrowserTest() {}
~NetworkContextConfigurationFixedPortBrowserTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(
switches::kTestingFixedHttpPort,
base::StringPrintf("%u", embedded_test_server()->port()));
LOG(WARNING) << base::StringPrintf("%u", embedded_test_server()->port());
}
};
// Test that the command line switch makes it to the network service and is
// respected.
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationFixedPortBrowserTest,
TestingFixedPort) {
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
// This URL does not use the port the embedded test server is using. The
// command line switch should make it result in the request being directed to
// the test server anyways.
request->url = GURL("http://127.0.0.1/echo");
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
EXPECT_EQ(net::OK, simple_loader->NetError());
ASSERT_TRUE(simple_loader_helper.response_body());
EXPECT_EQ(*simple_loader_helper.response_body(), "Echo");
}
class NetworkContextConfigurationProxyOnStartBrowserTest
: public NetworkContextConfigurationBrowserTest {
public:
NetworkContextConfigurationProxyOnStartBrowserTest() {}
~NetworkContextConfigurationProxyOnStartBrowserTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(
switches::kProxyServer,
embedded_test_server()->host_port_pair().ToString());
}
private:
DISALLOW_COPY_AND_ASSIGN(NetworkContextConfigurationProxyOnStartBrowserTest);
};
// Test that when there's a proxy configuration at startup, the initial requests
// use that configuration.
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationProxyOnStartBrowserTest,
TestInitialProxyConfig) {
TestProxyConfigured();
}
// Make sure the system URLRequestContext can handle fetching PAC scripts from
// http URLs.
class NetworkContextConfigurationHttpPacBrowserTest
: public NetworkContextConfigurationBrowserTest {
public:
NetworkContextConfigurationHttpPacBrowserTest()
: pac_test_server_(net::test_server::EmbeddedTestServer::TYPE_HTTP) {}
~NetworkContextConfigurationHttpPacBrowserTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
pac_test_server_.RegisterRequestHandler(base::Bind(
&NetworkContextConfigurationHttpPacBrowserTest::HandlePacRequest,
GetPacScript()));
EXPECT_TRUE(pac_test_server_.Start());
command_line->AppendSwitchASCII(switches::kProxyPacUrl,
pac_test_server_.base_url().spec().c_str());
}
static std::unique_ptr<net::test_server::HttpResponse> HandlePacRequest(
const std::string& pac_script,
const net::test_server::HttpRequest& request) {
std::unique_ptr<net::test_server::BasicHttpResponse> response =
std::make_unique<net::test_server::BasicHttpResponse>();
response->set_content(pac_script);
return response;
}
private:
net::test_server::EmbeddedTestServer pac_test_server_;
DISALLOW_COPY_AND_ASSIGN(NetworkContextConfigurationHttpPacBrowserTest);
};
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationHttpPacBrowserTest, HttpPac) {
TestProxyConfigured();
}
// Make sure the system URLRequestContext can handle fetching PAC scripts from
// file URLs.
class NetworkContextConfigurationFilePacBrowserTest
: public NetworkContextConfigurationBrowserTest {
public:
NetworkContextConfigurationFilePacBrowserTest() {}
~NetworkContextConfigurationFilePacBrowserTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
const char kPacFileName[] = "foo.pac";
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath pac_file_path =
temp_dir_.GetPath().AppendASCII(kPacFileName);
std::string pac_script = GetPacScript();
ASSERT_EQ(
static_cast<int>(pac_script.size()),
base::WriteFile(pac_file_path, pac_script.c_str(), pac_script.size()));
command_line->AppendSwitchASCII(
switches::kProxyPacUrl, net::FilePathToFileURL(pac_file_path).spec());
}
private:
base::ScopedTempDir temp_dir_;
DISALLOW_COPY_AND_ASSIGN(NetworkContextConfigurationFilePacBrowserTest);
};
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationFilePacBrowserTest, FilePac) {
TestProxyConfigured();
}
// Make sure the system URLRequestContext can handle fetching PAC scripts from
// data URLs.
class NetworkContextConfigurationDataPacBrowserTest
: public NetworkContextConfigurationBrowserTest {
public:
NetworkContextConfigurationDataPacBrowserTest() {}
~NetworkContextConfigurationDataPacBrowserTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
std::string contents;
// Read in kPACScript contents.
command_line->AppendSwitchASCII(switches::kProxyPacUrl,
"data:," + GetPacScript());
}
private:
DISALLOW_COPY_AND_ASSIGN(NetworkContextConfigurationDataPacBrowserTest);
};
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationDataPacBrowserTest, DataPac) {
TestProxyConfigured();
}
// Make sure the system URLRequestContext can handle fetching PAC scripts from
// ftp URLs. Unlike the other PAC tests, this test uses a PAC script that
// results in an error, since the spawned test server is designed so that it can
// run remotely (So can't just write a script to a local file and have the
// server serve it).
class NetworkContextConfigurationFtpPacBrowserTest
: public NetworkContextConfigurationBrowserTest {
public:
NetworkContextConfigurationFtpPacBrowserTest()
: ftp_server_(net::SpawnedTestServer::TYPE_FTP,
base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))) {
EXPECT_TRUE(ftp_server_.Start());
}
~NetworkContextConfigurationFtpPacBrowserTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(
switches::kProxyPacUrl,
ftp_server_.GetURL("bad_server.pac").spec().c_str());
}
private:
net::SpawnedTestServer ftp_server_;
DISALLOW_COPY_AND_ASSIGN(NetworkContextConfigurationFtpPacBrowserTest);
};
IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationFtpPacBrowserTest, FtpPac) {
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
// This URL should be directed to the test server because of the proxy.
request->url = GURL("http://jabberwocky.test:1872/echo");
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
EXPECT_EQ(net::ERR_PROXY_CONNECTION_FAILED, simple_loader->NetError());
}
// |NetworkServiceTestHelper| doesn't work on browser_tests on OSX.
#if defined(OS_MACOSX)
// Instiates tests with a prefix indicating which NetworkContext is being
// tested, and a suffix of "/0" if the network service is disabled and "/1" if
// it's enabled.
#define INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(TestFixture) \
INSTANTIATE_TEST_CASE_P( \
SystemNetworkContext, TestFixture, \
::testing::Values(TestCase({NetworkServiceState::kDisabled, \
NetworkContextType::kSystem}), \
TestCase({NetworkServiceState::kEnabled, \
NetworkContextType::kSystem}))); \
\
INSTANTIATE_TEST_CASE_P( \
ProfileMainNetworkContext, TestFixture, \
::testing::Values(TestCase({NetworkServiceState::kDisabled, \
NetworkContextType::kProfile}), \
TestCase({NetworkServiceState::kEnabled, \
NetworkContextType::kProfile}))); \
\
INSTANTIATE_TEST_CASE_P( \
IncognitoProfileMainNetworkContext, TestFixture, \
::testing::Values(TestCase({NetworkServiceState::kDisabled, \
NetworkContextType::kIncognitoProfile}), \
TestCase({NetworkServiceState::kEnabled, \
NetworkContextType::kIncognitoProfile})))
#else // !defined(OS_MACOSX)
// Instiates tests with a prefix indicating which NetworkContext is being
// tested, and a suffix of "/0" if the network service is disabled, "/1" if it's
// enabled, and "/2" if it's enabled and restarted.
#define INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(TestFixture) \
INSTANTIATE_TEST_CASE_P( \
SystemNetworkContext, TestFixture, \
::testing::Values(TestCase({NetworkServiceState::kDisabled, \
NetworkContextType::kSystem}), \
TestCase({NetworkServiceState::kEnabled, \
NetworkContextType::kSystem}), \
TestCase({NetworkServiceState::kRestarted, \
NetworkContextType::kSystem}))); \
\
INSTANTIATE_TEST_CASE_P( \
ProfileMainNetworkContext, TestFixture, \
::testing::Values(TestCase({NetworkServiceState::kDisabled, \
NetworkContextType::kProfile}), \
TestCase({NetworkServiceState::kEnabled, \
NetworkContextType::kProfile}), \
TestCase({NetworkServiceState::kRestarted, \
NetworkContextType::kProfile}))); \
\
INSTANTIATE_TEST_CASE_P( \
IncognitoProfileMainNetworkContext, TestFixture, \
::testing::Values(TestCase({NetworkServiceState::kDisabled, \
NetworkContextType::kIncognitoProfile}), \
TestCase({NetworkServiceState::kEnabled, \
NetworkContextType::kIncognitoProfile}), \
TestCase({NetworkServiceState::kRestarted, \
NetworkContextType::kIncognitoProfile})))
#endif // !defined(OS_MACOSX)
INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(NetworkContextConfigurationBrowserTest);
INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(
NetworkContextConfigurationFixedPortBrowserTest);
INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(
NetworkContextConfigurationProxyOnStartBrowserTest);
INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(
NetworkContextConfigurationHttpPacBrowserTest);
INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(
NetworkContextConfigurationFilePacBrowserTest);
INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(
NetworkContextConfigurationDataPacBrowserTest);
INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(
NetworkContextConfigurationFtpPacBrowserTest);
} // namespace