proxy_config_service_mojo_unittest.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/network/proxy_config_service_mojo.h"
  5. #include "base/memory/raw_ptr.h"
  6. #include "base/test/task_environment.h"
  7. #include "net/proxy_resolution/proxy_config.h"
  8. #include "net/proxy_resolution/proxy_config_service.h"
  9. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  10. #include "services/network/public/mojom/proxy_config.mojom.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. namespace network {
  13. namespace {
  14. // Test class for observing proxy config changes.
  15. class TestProxyConfigServiceObserver
  16. : public net::ProxyConfigService::Observer {
  17. public:
  18. explicit TestProxyConfigServiceObserver(net::ProxyConfigService* service)
  19. : service_(service) {}
  20. TestProxyConfigServiceObserver(const TestProxyConfigServiceObserver&) =
  21. delete;
  22. TestProxyConfigServiceObserver& operator=(
  23. const TestProxyConfigServiceObserver&) = delete;
  24. ~TestProxyConfigServiceObserver() override {}
  25. void OnProxyConfigChanged(
  26. const net::ProxyConfigWithAnnotation& config,
  27. net::ProxyConfigService::ConfigAvailability availability) override {
  28. // The ProxyConfigServiceMojo only sends on availability state.
  29. EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, availability);
  30. observed_config_ = config;
  31. // The passed in config should match the one that GetLatestProxyConfig
  32. // returns.
  33. net::ProxyConfigWithAnnotation retrieved_config;
  34. EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
  35. service_->GetLatestProxyConfig(&retrieved_config));
  36. EXPECT_TRUE(observed_config_.value().Equals(retrieved_config.value()));
  37. ++config_changes_;
  38. }
  39. // Returns number of observed config changes since it was last called.
  40. int GetAndResetConfigChanges() {
  41. int result = config_changes_;
  42. config_changes_ = 0;
  43. return result;
  44. }
  45. // Returns last observed config.
  46. const net::ProxyConfigWithAnnotation& observed_config() const {
  47. return observed_config_;
  48. }
  49. private:
  50. net::ProxyConfigWithAnnotation observed_config_;
  51. const raw_ptr<net::ProxyConfigService> service_;
  52. int config_changes_ = 0;
  53. };
  54. // Test fixture for notifying ProxyConfigServiceMojo of changes through the
  55. // client interface, and watching the subsequent values it emits to registered
  56. // net::ProxyConfigService::Observers.
  57. class ProxyConfigServiceMojoTest : public testing::Test {
  58. public:
  59. ProxyConfigServiceMojoTest()
  60. : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
  61. proxy_config_service_(config_client_.BindNewPipeAndPassReceiver(),
  62. absl::optional<net::ProxyConfigWithAnnotation>(),
  63. mojo::NullRemote()),
  64. observer_(&proxy_config_service_) {
  65. proxy_config_service_.AddObserver(&observer_);
  66. }
  67. ProxyConfigServiceMojoTest(const ProxyConfigServiceMojoTest&) = delete;
  68. ProxyConfigServiceMojoTest& operator=(const ProxyConfigServiceMojoTest&) =
  69. delete;
  70. ~ProxyConfigServiceMojoTest() override {
  71. proxy_config_service_.RemoveObserver(&observer_);
  72. }
  73. protected:
  74. // After notifying a new configuration through |config_client_|, waits for the
  75. // observers to have been notified.
  76. void WaitForConfig() { task_environment_.RunUntilIdle(); }
  77. base::test::TaskEnvironment task_environment_;
  78. mojo::Remote<mojom::ProxyConfigClient> config_client_;
  79. ProxyConfigServiceMojo proxy_config_service_;
  80. TestProxyConfigServiceObserver observer_;
  81. };
  82. // Most tests of this class are in network_context_unittests.
  83. // Makes sure that a ProxyConfigService::Observer is correctly notified of
  84. // changes when the ProxyConfig changes, and is not informed of them in the case
  85. // of "changes" that result in the same ProxyConfig as before.
  86. TEST_F(ProxyConfigServiceMojoTest, ObserveProxyChanges) {
  87. net::ProxyConfigWithAnnotation temp;
  88. // The service should start without a config.
  89. EXPECT_EQ(net::ProxyConfigService::CONFIG_PENDING,
  90. proxy_config_service_.GetLatestProxyConfig(&temp));
  91. net::ProxyConfig proxy_configs[3];
  92. proxy_configs[0].proxy_rules().ParseFromString("http=foopy:80");
  93. proxy_configs[1].proxy_rules().ParseFromString("http=foopy:80;ftp=foopy2");
  94. proxy_configs[2] = net::ProxyConfig::CreateDirect();
  95. for (const auto& proxy_config : proxy_configs) {
  96. // Set the proxy configuration to something that does not match the old one.
  97. config_client_->OnProxyConfigUpdated(net::ProxyConfigWithAnnotation(
  98. proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
  99. WaitForConfig();
  100. EXPECT_EQ(1, observer_.GetAndResetConfigChanges());
  101. EXPECT_TRUE(proxy_config.Equals(observer_.observed_config().value()));
  102. net::ProxyConfigWithAnnotation retrieved_config;
  103. EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
  104. proxy_config_service_.GetLatestProxyConfig(&retrieved_config));
  105. EXPECT_TRUE(proxy_config.Equals(retrieved_config.value()));
  106. // Set the proxy configuration to the same value again. There should be not
  107. // be another proxy config changed notification.
  108. config_client_->OnProxyConfigUpdated(net::ProxyConfigWithAnnotation(
  109. proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
  110. WaitForConfig();
  111. EXPECT_EQ(0, observer_.GetAndResetConfigChanges());
  112. EXPECT_TRUE(proxy_config.Equals(observer_.observed_config().value()));
  113. EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
  114. proxy_config_service_.GetLatestProxyConfig(&retrieved_config));
  115. EXPECT_TRUE(proxy_config.Equals(retrieved_config.value()));
  116. }
  117. }
  118. // Creates a URL that has length |url::kMaxURLChars + 1|.
  119. GURL CreateLargeURL() {
  120. std::string spec;
  121. spec.reserve(url::kMaxURLChars + 1);
  122. spec.assign("http://test.invalid/");
  123. spec.append(url::kMaxURLChars + 1 - spec.size(), 'x');
  124. return GURL(spec);
  125. }
  126. // Tests what happens when ProxyConfigServiceMojo is updated to using a
  127. // ProxyConfig with a large URL. GURL does not impose size limits, however some
  128. // internals like url.mojom.Url do.
  129. TEST_F(ProxyConfigServiceMojoTest, LargePacUrlNotTruncated) {
  130. // Create a config using a large, valid, PAC URL.
  131. net::ProxyConfig orig_config;
  132. GURL large_url = CreateLargeURL();
  133. EXPECT_TRUE(large_url.is_valid());
  134. EXPECT_EQ(url::kMaxURLChars + 1, large_url.possibly_invalid_spec().size());
  135. orig_config.set_pac_url(large_url);
  136. // Notify the ProxyConfigServiceMojo of this URL through the client interface.
  137. config_client_->OnProxyConfigUpdated(net::ProxyConfigWithAnnotation(
  138. orig_config, TRAFFIC_ANNOTATION_FOR_TESTS));
  139. WaitForConfig();
  140. // Read back the ProxyConfig that was observed (which has been serialized
  141. // through a Mojo pipe).
  142. const GURL& observed_url = observer_.observed_config().value().pac_url();
  143. // The URL should be unchanged, and not changed by the Mojo serialization.
  144. EXPECT_EQ(large_url, observed_url);
  145. EXPECT_EQ(url::kMaxURLChars + 1, observed_url.possibly_invalid_spec().size());
  146. }
  147. } // namespace
  148. } // namespace network