chromium/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc

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

#include "net/proxy_resolution/configured_proxy_resolution_service.h"

#include <cstdarg>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "base/check.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
#include "net/base/mock_network_change_notifier.h"
#include "net/base/net_errors.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/network_change_notifier.h"
#include "net/base/network_isolation_key.h"
#include "net/base/proxy_chain.h"
#include "net/base/proxy_delegate.h"
#include "net/base/proxy_server.h"
#include "net/base/proxy_string_util.h"
#include "net/base/schemeful_site.h"
#include "net/base/test_completion_callback.h"
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_with_source.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_util.h"
#include "net/proxy_resolution/dhcp_pac_file_fetcher.h"
#include "net/proxy_resolution/mock_pac_file_fetcher.h"
#include "net/proxy_resolution/mock_proxy_resolver.h"
#include "net/proxy_resolution/pac_file_fetcher.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_resolution_request.h"
#include "net/proxy_resolution/proxy_resolver.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_task_environment.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

ElementsAre;
Key;

IsError;
IsOk;

// TODO(eroman): Write a test which exercises
//              ConfiguredProxyResolutionService::SuspendAllPendingRequests().
namespace net {
namespace {

// This polling policy will decide to poll every 1 ms.
class ImmediatePollPolicy
    : public ConfiguredProxyResolutionService::PacPollPolicy {};

// This polling policy chooses a fantastically large delay. In other words, it
// will never trigger a poll
class NeverPollPolicy : public ConfiguredProxyResolutionService::PacPollPolicy {};

// This polling policy starts a poll immediately after network activity.
class ImmediateAfterActivityPollPolicy
    : public ConfiguredProxyResolutionService::PacPollPolicy {};

// This test fixture is used to partially disable the background polling done by
// the ConfiguredProxyResolutionService (which it uses to detect whenever its
// PAC script contents or WPAD results have changed).
//
// We disable the feature by setting the poll interval to something really
// large, so it will never actually be reached even on the slowest bots that run
// these tests.
//
// We disable the polling in order to avoid any timing dependencies in the
// tests. If the bot were to run the tests very slowly and we hadn't disabled
// polling, then it might start a background re-try in the middle of our test
// and confuse our expectations leading to flaky failures.
//
// The tests which verify the polling code re-enable the polling behavior but
// are careful to avoid timing problems.
class ConfiguredProxyResolutionServiceTest : public ::testing::Test,
                                             public WithTaskEnvironment {};

const char kValidPacScript1[] =;
const char16_t kValidPacScript116[] =;
const char kValidPacScript2[] =;
const char16_t kValidPacScript216[] =;

class MockProxyConfigService : public ProxyConfigService {};

// A test network delegate that exercises the OnResolveProxy callback.
class TestResolveProxyDelegate : public ProxyDelegate {};

// A test network delegate that exercises the OnProxyFallback callback.
class TestProxyFallbackProxyDelegate : public ProxyDelegate {};

JobMap;

// Given a jobmap and a list of target URLs |urls|, asserts that the set of URLs
// of the jobs appearing in |list| is exactly the set of URLs in |urls|.
JobMap GetJobsForURLs(const JobMap& map, const std::vector<GURL>& urls) {}

// Given a MockAsyncProxyResolver |resolver| and some GURLs, validates that the
// set of pending request URLs for |resolver| is exactly the supplied list of
// URLs and returns a map from URLs to the corresponding pending jobs.
JobMap GetPendingJobsForURLs(const MockAsyncProxyResolver& resolver,
                             const GURL& url1 = GURL(),
                             const GURL& url2 = GURL(),
                             const GURL& url3 = GURL()) {}

// Given a MockAsyncProxyResolver |resolver| and some GURLs, validates that the
// set of cancelled request URLs for |resolver| is exactly the supplied list of
// URLs and returns a map from URLs to the corresponding cancelled jobs.
JobMap GetCancelledJobsForURLs(const MockAsyncProxyResolver& resolver,
                               const GURL& url1 = GURL(),
                               const GURL& url2 = GURL(),
                               const GURL& url3 = GURL()) {}

}  // namespace

TEST_F(ConfiguredProxyResolutionServiceTest, Direct) {}

TEST_F(ConfiguredProxyResolutionServiceTest, OnResolveProxyCallbackAddProxy) {}

TEST_F(ConfiguredProxyResolutionServiceTest,
       OnResolveProxyCallbackRemoveProxy) {}

TEST_F(ConfiguredProxyResolutionServiceTest, OnResolveProxyHasNak) {}

// Test callback that deletes an item when called.  This is used to test various
// permutations of important objects being deleted in the middle of a series of
// requests.
template <typename T>
class DeletingCallback : public TestCompletionCallbackBase {};

template <typename T>
DeletingCallback<T>::DeletingCallback(std::unique_ptr<T>* deletee)
    :{}

template <typename T>
DeletingCallback<T>::~DeletingCallback() = default;

// Test that the ConfiguredProxyResolutionService correctly handles the case
// where a request callback deletes another request.
TEST_F(ConfiguredProxyResolutionServiceTest, CallbackDeletesRequest) {}

// Test that the ConfiguredProxyResolutionService correctly handles the case
// where a request callback deletes another request.  (Triggered by the loop in
// ConfiguredProxyResolutionService's destructor).
TEST_F(ConfiguredProxyResolutionServiceTest,
       CallbackDeletesRequestDuringDestructor) {}

// Test that the ConfiguredProxyResolutionService correctly handles the case
// where a request callback deletes its own handle.
TEST_F(ConfiguredProxyResolutionServiceTest, CallbackDeletesSelf) {}

// Test that the ConfiguredProxyResolutionService correctly handles the case
// where a request callback deletes its own handle, when triggered by
// ConfiguredProxyResolutionService's destructor.
TEST_F(ConfiguredProxyResolutionServiceTest,
       CallbackDeletesSelfDuringDestructor) {}

TEST_F(ConfiguredProxyResolutionServiceTest, ProxyServiceDeletedBeforeRequest) {}

// Test that the ConfiguredProxyResolutionService correctly handles the case
// where a request callback deletes the service.
TEST_F(ConfiguredProxyResolutionServiceTest, CallbackDeletesService) {}

TEST_F(ConfiguredProxyResolutionServiceTest, PAC) {}

// Test that the proxy resolver does not see the URL's username/password
// or its reference section.
TEST_F(ConfiguredProxyResolutionServiceTest, PAC_NoIdentityOrHash) {}

TEST_F(ConfiguredProxyResolutionServiceTest, PAC_FailoverWithoutDirect) {}

// Test that if the execution of the PAC script fails (i.e. javascript runtime
// error), and the PAC settings are non-mandatory, that we fall-back to direct.
TEST_F(ConfiguredProxyResolutionServiceTest, PAC_RuntimeError) {}

// The proxy list could potentially contain the DIRECT fallback choice
// in a location other than the very end of the list, and could even
// specify it multiple times.
//
// This is not a typical usage, but we will obey it.
// (If we wanted to disallow this type of input, the right place to
// enforce it would be in parsing the PAC result string).
//
// This test will use the PAC result string:
//
//   "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
//
// For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
// then foobar:20, and then give up and error.
//
// The important check of this test is to make sure that DIRECT is not somehow
// cached as being a bad proxy.
TEST_F(ConfiguredProxyResolutionServiceTest, PAC_FailoverAfterDirect) {}

TEST_F(ConfiguredProxyResolutionServiceTest, PAC_ConfigSourcePropagates) {}

TEST_F(ConfiguredProxyResolutionServiceTest, ProxyResolverFails) {}

TEST_F(ConfiguredProxyResolutionServiceTest,
       ProxyResolverTerminatedDuringRequest) {}

TEST_F(ConfiguredProxyResolutionServiceTest,
       ProxyResolverTerminatedDuringRequestWithConcurrentRequest) {}

TEST_F(ConfiguredProxyResolutionServiceTest,
       PacFileFetcherFailsDownloadingMandatoryPac) {}

TEST_F(ConfiguredProxyResolutionServiceTest,
       ProxyResolverFailsParsingJavaScriptMandatoryPac) {}

TEST_F(ConfiguredProxyResolutionServiceTest,
       ProxyResolverFailsInJavaScriptMandatoryPac) {}

TEST_F(ConfiguredProxyResolutionServiceTest, ProxyFallback) {}

// This test is similar to ProxyFallback, but this time we have an explicit
// fallback choice to DIRECT.
TEST_F(ConfiguredProxyResolutionServiceTest, ProxyFallbackToDirect) {}

TEST_F(ConfiguredProxyResolutionServiceTest, ProxyFallback_BadConfig) {}

TEST_F(ConfiguredProxyResolutionServiceTest, ProxyFallback_BadConfigMandatory) {}

TEST_F(ConfiguredProxyResolutionServiceTest, ProxyBypassList) {}

TEST_F(ConfiguredProxyResolutionServiceTest, PerProtocolProxyTests) {}

TEST_F(ConfiguredProxyResolutionServiceTest,
       ProxyConfigTrafficAnnotationPropagates) {}

// If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
// fall back to the SOCKS proxy.
TEST_F(ConfiguredProxyResolutionServiceTest, DefaultProxyFallbackToSOCKS) {}

// Test cancellation of an in-progress request.
TEST_F(ConfiguredProxyResolutionServiceTest, CancelInProgressRequest) {}

// Test the initial PAC download for resolver that expects bytes.
TEST_F(ConfiguredProxyResolutionServiceTest, InitialPACScriptDownload) {}

// Test changing the PacFileFetcher while PAC download is in progress.
TEST_F(ConfiguredProxyResolutionServiceTest,
       ChangeScriptFetcherWhilePACDownloadInProgress) {}

// Test cancellation of a request, while the PAC script is being fetched.
TEST_F(ConfiguredProxyResolutionServiceTest, CancelWhilePACFetching) {}

// Test that if auto-detect fails, we fall-back to the custom pac.
TEST_F(ConfiguredProxyResolutionServiceTest,
       FallbackFromAutodetectToCustomPac) {}

// This is the same test as FallbackFromAutodetectToCustomPac, except
// the auto-detect script fails parsing rather than downloading.
TEST_F(ConfiguredProxyResolutionServiceTest,
       FallbackFromAutodetectToCustomPac2) {}

// Test that if all of auto-detect, a custom PAC script, and manual settings
// are given, then we will try them in that order.
TEST_F(ConfiguredProxyResolutionServiceTest,
       FallbackFromAutodetectToCustomToManual) {}

// Test that the bypass rules are NOT applied when using autodetect.
TEST_F(ConfiguredProxyResolutionServiceTest, BypassDoesntApplyToPac) {}

// Delete the ConfiguredProxyResolutionService while InitProxyResolver has an
// outstanding request to the script fetcher. When run under valgrind, should
// not have any memory errors (used to be that the PacFileFetcher was being
// deleted prior to the InitProxyResolver).
TEST_F(ConfiguredProxyResolutionServiceTest,
       DeleteWhileInitProxyResolverHasOutstandingFetch) {}

// Delete the ConfiguredProxyResolutionService while InitProxyResolver has an
// outstanding request to the proxy resolver. When run under valgrind, should
// not have any memory errors (used to be that the ProxyResolver was being
// deleted prior to the InitProxyResolver).
TEST_F(ConfiguredProxyResolutionServiceTest,
       DeleteWhileInitProxyResolverHasOutstandingSet) {}

// Test that when going from a configuration that required PAC to one
// that does NOT, we unset the variable |should_use_proxy_resolver_|.
TEST_F(ConfiguredProxyResolutionServiceTest, UpdateConfigFromPACToDirect) {}

TEST_F(ConfiguredProxyResolutionServiceTest, NetworkChangeTriggersPacRefetch) {}

// This test verifies that the PAC script specified by the settings is
// periodically polled for changes. Specifically, if the initial fetch fails due
// to a network error, we will eventually re-configure the service to use the
// script once it becomes available.
TEST_F(ConfiguredProxyResolutionServiceTest, PACScriptRefetchAfterFailure) {}

// This test verifies that the PAC script specified by the settings is
// periodically polled for changes. Specifically, if the initial fetch succeeds,
// however at a later time its *contents* change, we will eventually
// re-configure the service to use the new script.
TEST_F(ConfiguredProxyResolutionServiceTest,
       PACScriptRefetchAfterContentChange) {}

// This test verifies that the PAC script specified by the settings is
// periodically polled for changes. Specifically, if the initial fetch succeeds
// and so does the next poll, however the contents of the downloaded script
// have NOT changed, then we do not bother to re-initialize the proxy resolver.
TEST_F(ConfiguredProxyResolutionServiceTest,
       PACScriptRefetchAfterContentUnchanged) {}

// This test verifies that the PAC script specified by the settings is
// periodically polled for changes. Specifically, if the initial fetch succeeds,
// however at a later time it starts to fail, we should re-configure the
// ConfiguredProxyResolutionService to stop using that PAC script.
TEST_F(ConfiguredProxyResolutionServiceTest, PACScriptRefetchAfterSuccess) {}

// Tests that the code which decides at what times to poll the PAC
// script follows the expected policy.
TEST_F(ConfiguredProxyResolutionServiceTest, PACScriptPollingPolicy) {}

// This tests the polling of the PAC script. Specifically, it tests that
// polling occurs in response to user activity.
TEST_F(ConfiguredProxyResolutionServiceTest, PACScriptRefetchAfterActivity) {}

TEST_F(ConfiguredProxyResolutionServiceTest, IpAddressChangeResetsProxy) {}

TEST_F(ConfiguredProxyResolutionServiceTest, DnsChangeTriggersPoll) {}

TEST_F(ConfiguredProxyResolutionServiceTest, DnsChangeNoopWithoutResolver) {}

// Helper class to exercise URL sanitization by submitting URLs to the
// ConfiguredProxyResolutionService and returning the URL passed to the
// ProxyResolver.
class SanitizeUrlHelper {};

// Tests that input URLs to proxy resolution are sanitized before being passed
// on to the ProxyResolver (i.e. PAC script evaluator). For instance PAC
// scripts should not be able to see the path for https:// URLs.
TEST_F(ConfiguredProxyResolutionServiceTest, SanitizeUrlForPacScript) {}

TEST_F(ConfiguredProxyResolutionServiceTest, OnShutdownWithLiveRequest) {}

TEST_F(ConfiguredProxyResolutionServiceTest, OnShutdownFollowedByRequest) {}

const char* kImplicityBypassedHosts[] =;

const char* kUrlSchemes[] =;

TEST_F(ConfiguredProxyResolutionServiceTest,
       ImplicitlyBypassWithManualSettings) {}

// Test that the when using a PAC script (sourced via auto-detect) certain
// localhost names are implicitly bypassed.
TEST_F(ConfiguredProxyResolutionServiceTest, ImplicitlyBypassWithPac) {}

TEST_F(ConfiguredProxyResolutionServiceTest,
       CastToConfiguredProxyResolutionService) {}

}  // namespace net