123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- // 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 "services/network/proxy_config_service_mojo.h"
- #include "base/memory/raw_ptr.h"
- #include "base/test/task_environment.h"
- #include "net/proxy_resolution/proxy_config.h"
- #include "net/proxy_resolution/proxy_config_service.h"
- #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
- #include "services/network/public/mojom/proxy_config.mojom.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace network {
- namespace {
- // Test class for observing proxy config changes.
- class TestProxyConfigServiceObserver
- : public net::ProxyConfigService::Observer {
- public:
- explicit TestProxyConfigServiceObserver(net::ProxyConfigService* service)
- : service_(service) {}
- TestProxyConfigServiceObserver(const TestProxyConfigServiceObserver&) =
- delete;
- TestProxyConfigServiceObserver& operator=(
- const TestProxyConfigServiceObserver&) = delete;
- ~TestProxyConfigServiceObserver() override {}
- void OnProxyConfigChanged(
- const net::ProxyConfigWithAnnotation& config,
- net::ProxyConfigService::ConfigAvailability availability) override {
- // The ProxyConfigServiceMojo only sends on availability state.
- EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, availability);
- observed_config_ = config;
- // The passed in config should match the one that GetLatestProxyConfig
- // returns.
- net::ProxyConfigWithAnnotation retrieved_config;
- EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
- service_->GetLatestProxyConfig(&retrieved_config));
- EXPECT_TRUE(observed_config_.value().Equals(retrieved_config.value()));
- ++config_changes_;
- }
- // Returns number of observed config changes since it was last called.
- int GetAndResetConfigChanges() {
- int result = config_changes_;
- config_changes_ = 0;
- return result;
- }
- // Returns last observed config.
- const net::ProxyConfigWithAnnotation& observed_config() const {
- return observed_config_;
- }
- private:
- net::ProxyConfigWithAnnotation observed_config_;
- const raw_ptr<net::ProxyConfigService> service_;
- int config_changes_ = 0;
- };
- // Test fixture for notifying ProxyConfigServiceMojo of changes through the
- // client interface, and watching the subsequent values it emits to registered
- // net::ProxyConfigService::Observers.
- class ProxyConfigServiceMojoTest : public testing::Test {
- public:
- ProxyConfigServiceMojoTest()
- : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
- proxy_config_service_(config_client_.BindNewPipeAndPassReceiver(),
- absl::optional<net::ProxyConfigWithAnnotation>(),
- mojo::NullRemote()),
- observer_(&proxy_config_service_) {
- proxy_config_service_.AddObserver(&observer_);
- }
- ProxyConfigServiceMojoTest(const ProxyConfigServiceMojoTest&) = delete;
- ProxyConfigServiceMojoTest& operator=(const ProxyConfigServiceMojoTest&) =
- delete;
- ~ProxyConfigServiceMojoTest() override {
- proxy_config_service_.RemoveObserver(&observer_);
- }
- protected:
- // After notifying a new configuration through |config_client_|, waits for the
- // observers to have been notified.
- void WaitForConfig() { task_environment_.RunUntilIdle(); }
- base::test::TaskEnvironment task_environment_;
- mojo::Remote<mojom::ProxyConfigClient> config_client_;
- ProxyConfigServiceMojo proxy_config_service_;
- TestProxyConfigServiceObserver observer_;
- };
- // Most tests of this class are in network_context_unittests.
- // Makes sure that a ProxyConfigService::Observer is correctly notified of
- // changes when the ProxyConfig changes, and is not informed of them in the case
- // of "changes" that result in the same ProxyConfig as before.
- TEST_F(ProxyConfigServiceMojoTest, ObserveProxyChanges) {
- net::ProxyConfigWithAnnotation temp;
- // The service should start without a config.
- EXPECT_EQ(net::ProxyConfigService::CONFIG_PENDING,
- proxy_config_service_.GetLatestProxyConfig(&temp));
- net::ProxyConfig proxy_configs[3];
- proxy_configs[0].proxy_rules().ParseFromString("http=foopy:80");
- proxy_configs[1].proxy_rules().ParseFromString("http=foopy:80;ftp=foopy2");
- proxy_configs[2] = net::ProxyConfig::CreateDirect();
- for (const auto& proxy_config : proxy_configs) {
- // Set the proxy configuration to something that does not match the old one.
- config_client_->OnProxyConfigUpdated(net::ProxyConfigWithAnnotation(
- proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
- WaitForConfig();
- EXPECT_EQ(1, observer_.GetAndResetConfigChanges());
- EXPECT_TRUE(proxy_config.Equals(observer_.observed_config().value()));
- net::ProxyConfigWithAnnotation retrieved_config;
- EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
- proxy_config_service_.GetLatestProxyConfig(&retrieved_config));
- EXPECT_TRUE(proxy_config.Equals(retrieved_config.value()));
- // Set the proxy configuration to the same value again. There should be not
- // be another proxy config changed notification.
- config_client_->OnProxyConfigUpdated(net::ProxyConfigWithAnnotation(
- proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
- WaitForConfig();
- EXPECT_EQ(0, observer_.GetAndResetConfigChanges());
- EXPECT_TRUE(proxy_config.Equals(observer_.observed_config().value()));
- EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
- proxy_config_service_.GetLatestProxyConfig(&retrieved_config));
- EXPECT_TRUE(proxy_config.Equals(retrieved_config.value()));
- }
- }
- // Creates a URL that has length |url::kMaxURLChars + 1|.
- GURL CreateLargeURL() {
- std::string spec;
- spec.reserve(url::kMaxURLChars + 1);
- spec.assign("http://test.invalid/");
- spec.append(url::kMaxURLChars + 1 - spec.size(), 'x');
- return GURL(spec);
- }
- // Tests what happens when ProxyConfigServiceMojo is updated to using a
- // ProxyConfig with a large URL. GURL does not impose size limits, however some
- // internals like url.mojom.Url do.
- TEST_F(ProxyConfigServiceMojoTest, LargePacUrlNotTruncated) {
- // Create a config using a large, valid, PAC URL.
- net::ProxyConfig orig_config;
- GURL large_url = CreateLargeURL();
- EXPECT_TRUE(large_url.is_valid());
- EXPECT_EQ(url::kMaxURLChars + 1, large_url.possibly_invalid_spec().size());
- orig_config.set_pac_url(large_url);
- // Notify the ProxyConfigServiceMojo of this URL through the client interface.
- config_client_->OnProxyConfigUpdated(net::ProxyConfigWithAnnotation(
- orig_config, TRAFFIC_ANNOTATION_FOR_TESTS));
- WaitForConfig();
- // Read back the ProxyConfig that was observed (which has been serialized
- // through a Mojo pipe).
- const GURL& observed_url = observer_.observed_config().value().pac_url();
- // The URL should be unchanged, and not changed by the Mojo serialization.
- EXPECT_EQ(large_url, observed_url);
- EXPECT_EQ(url::kMaxURLChars + 1, observed_url.possibly_invalid_spec().size());
- }
- } // namespace
- } // namespace network
|