pref_proxy_config_tracker_impl_unittest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. // Copyright (c) 2011 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 "components/proxy_config/pref_proxy_config_tracker_impl.h"
  5. #include <memory>
  6. #include <string>
  7. #include "base/files/file_path.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/run_loop.h"
  10. #include "base/test/task_environment.h"
  11. #include "base/threading/thread_task_runner_handle.h"
  12. #include "components/prefs/pref_registry_simple.h"
  13. #include "components/prefs/testing_pref_service.h"
  14. #include "components/proxy_config/proxy_config_dictionary.h"
  15. #include "components/proxy_config/proxy_config_pref_names.h"
  16. #include "net/base/proxy_string_util.h"
  17. #include "net/proxy_resolution/proxy_info.h"
  18. #include "net/proxy_resolution/proxy_list.h"
  19. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  20. #include "testing/gmock/include/gmock/gmock.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. #include "url/gurl.h"
  23. using testing::_;
  24. using testing::Mock;
  25. namespace {
  26. const char kFixedPacUrl[] = "http://chromium.org/fixed_pac_url";
  27. // Testing proxy config service that allows us to fire notifications at will.
  28. class TestProxyConfigService : public net::ProxyConfigService {
  29. public:
  30. TestProxyConfigService(const net::ProxyConfigWithAnnotation& config,
  31. ConfigAvailability availability)
  32. : config_(config), availability_(availability) {}
  33. void SetProxyConfig(const net::ProxyConfig config,
  34. ConfigAvailability availability) {
  35. config_ =
  36. net::ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS);
  37. availability_ = availability;
  38. for (net::ProxyConfigService::Observer& observer : observers_)
  39. observer.OnProxyConfigChanged(config_, availability);
  40. }
  41. private:
  42. void AddObserver(net::ProxyConfigService::Observer* observer) override {
  43. observers_.AddObserver(observer);
  44. }
  45. void RemoveObserver(net::ProxyConfigService::Observer* observer) override {
  46. observers_.RemoveObserver(observer);
  47. }
  48. net::ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
  49. net::ProxyConfigWithAnnotation* config) override {
  50. *config = config_;
  51. return availability_;
  52. }
  53. net::ProxyConfigWithAnnotation config_;
  54. ConfigAvailability availability_;
  55. base::ObserverList<net::ProxyConfigService::Observer, true>::Unchecked
  56. observers_;
  57. };
  58. // A mock observer for capturing callbacks.
  59. class MockObserver : public net::ProxyConfigService::Observer {
  60. public:
  61. MOCK_METHOD2(OnProxyConfigChanged,
  62. void(const net::ProxyConfigWithAnnotation&,
  63. net::ProxyConfigService::ConfigAvailability));
  64. };
  65. class PrefProxyConfigTrackerImplTest : public testing::Test {
  66. protected:
  67. PrefProxyConfigTrackerImplTest() {}
  68. // Initializes the proxy config service. The delegate config service has the
  69. // specified initial config availability.
  70. void InitConfigService(net::ProxyConfigService::ConfigAvailability
  71. delegate_config_availability) {
  72. pref_service_ = std::make_unique<TestingPrefServiceSimple>();
  73. PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service_->registry());
  74. net::ProxyConfig proxy_config;
  75. proxy_config.set_pac_url(GURL(kFixedPacUrl));
  76. fixed_config_ = net::ProxyConfigWithAnnotation(
  77. proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS);
  78. delegate_service_ =
  79. new TestProxyConfigService(fixed_config_, delegate_config_availability);
  80. proxy_config_tracker_ = std::make_unique<PrefProxyConfigTrackerImpl>(
  81. pref_service_.get(), base::ThreadTaskRunnerHandle::Get());
  82. proxy_config_service_ =
  83. proxy_config_tracker_->CreateTrackingProxyConfigService(
  84. std::unique_ptr<net::ProxyConfigService>(delegate_service_));
  85. }
  86. ~PrefProxyConfigTrackerImplTest() override {
  87. proxy_config_tracker_->DetachFromPrefService();
  88. base::RunLoop().RunUntilIdle();
  89. proxy_config_tracker_.reset();
  90. proxy_config_service_.reset();
  91. }
  92. base::test::SingleThreadTaskEnvironment task_environment_;
  93. std::unique_ptr<TestingPrefServiceSimple> pref_service_;
  94. raw_ptr<TestProxyConfigService> delegate_service_; // weak
  95. std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
  96. net::ProxyConfigWithAnnotation fixed_config_;
  97. std::unique_ptr<PrefProxyConfigTrackerImpl> proxy_config_tracker_;
  98. };
  99. TEST_F(PrefProxyConfigTrackerImplTest, BaseConfiguration) {
  100. InitConfigService(net::ProxyConfigService::CONFIG_VALID);
  101. net::ProxyConfigWithAnnotation actual_config;
  102. EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
  103. proxy_config_service_->GetLatestProxyConfig(&actual_config));
  104. EXPECT_EQ(GURL(kFixedPacUrl), actual_config.value().pac_url());
  105. }
  106. TEST_F(PrefProxyConfigTrackerImplTest, DynamicPrefOverrides) {
  107. InitConfigService(net::ProxyConfigService::CONFIG_VALID);
  108. pref_service_->SetManagedPref(
  109. proxy_config::prefs::kProxy,
  110. std::make_unique<base::Value>(ProxyConfigDictionary::CreateFixedServers(
  111. "http://example.com:3128", std::string())));
  112. base::RunLoop().RunUntilIdle();
  113. net::ProxyConfigWithAnnotation actual_config;
  114. EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
  115. proxy_config_service_->GetLatestProxyConfig(&actual_config));
  116. EXPECT_FALSE(actual_config.value().auto_detect());
  117. EXPECT_EQ(net::ProxyConfig::ProxyRules::Type::PROXY_LIST,
  118. actual_config.value().proxy_rules().type);
  119. EXPECT_EQ(actual_config.value().proxy_rules().single_proxies.Get(),
  120. net::ProxyUriToProxyServer("http://example.com:3128",
  121. net::ProxyServer::SCHEME_HTTP));
  122. pref_service_->SetManagedPref(
  123. proxy_config::prefs::kProxy,
  124. std::make_unique<base::Value>(ProxyConfigDictionary::CreateAutoDetect()));
  125. base::RunLoop().RunUntilIdle();
  126. EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
  127. proxy_config_service_->GetLatestProxyConfig(&actual_config));
  128. EXPECT_TRUE(actual_config.value().auto_detect());
  129. }
  130. // Compares proxy configurations, but allows different sources.
  131. MATCHER_P(ProxyConfigMatches, config, "") {
  132. net::ProxyConfig reference(config);
  133. return reference.Equals(arg.value());
  134. }
  135. TEST_F(PrefProxyConfigTrackerImplTest, Observers) {
  136. InitConfigService(net::ProxyConfigService::CONFIG_VALID);
  137. const net::ProxyConfigService::ConfigAvailability CONFIG_VALID =
  138. net::ProxyConfigService::CONFIG_VALID;
  139. MockObserver observer;
  140. proxy_config_service_->AddObserver(&observer);
  141. // Firing the observers in the delegate should trigger a notification.
  142. net::ProxyConfig config2;
  143. config2.set_auto_detect(true);
  144. EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config2),
  145. CONFIG_VALID)).Times(1);
  146. delegate_service_->SetProxyConfig(config2, CONFIG_VALID);
  147. base::RunLoop().RunUntilIdle();
  148. Mock::VerifyAndClearExpectations(&observer);
  149. // Override configuration, this should trigger a notification.
  150. net::ProxyConfig pref_config;
  151. pref_config.set_pac_url(GURL(kFixedPacUrl));
  152. EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(pref_config),
  153. CONFIG_VALID)).Times(1);
  154. pref_service_->SetManagedPref(
  155. proxy_config::prefs::kProxy,
  156. std::make_unique<base::Value>(
  157. ProxyConfigDictionary::CreatePacScript(kFixedPacUrl, false)));
  158. base::RunLoop().RunUntilIdle();
  159. Mock::VerifyAndClearExpectations(&observer);
  160. // Since there are pref overrides, delegate changes should be ignored.
  161. net::ProxyConfig config3;
  162. config3.proxy_rules().ParseFromString("http=config3:80");
  163. EXPECT_CALL(observer, OnProxyConfigChanged(_, _)).Times(0);
  164. net::ProxyConfig fixed_proxy_config = fixed_config_.value();
  165. fixed_proxy_config.set_auto_detect(true);
  166. fixed_config_ = net::ProxyConfigWithAnnotation(fixed_proxy_config,
  167. TRAFFIC_ANNOTATION_FOR_TESTS);
  168. delegate_service_->SetProxyConfig(config3, CONFIG_VALID);
  169. base::RunLoop().RunUntilIdle();
  170. Mock::VerifyAndClearExpectations(&observer);
  171. // Clear the override should switch back to the fixed configuration.
  172. EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config3),
  173. CONFIG_VALID)).Times(1);
  174. pref_service_->RemoveManagedPref(proxy_config::prefs::kProxy);
  175. base::RunLoop().RunUntilIdle();
  176. Mock::VerifyAndClearExpectations(&observer);
  177. // Delegate service notifications should show up again.
  178. net::ProxyConfig config4;
  179. config4.proxy_rules().ParseFromString("socks:config4");
  180. EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config4),
  181. CONFIG_VALID)).Times(1);
  182. delegate_service_->SetProxyConfig(config4, CONFIG_VALID);
  183. base::RunLoop().RunUntilIdle();
  184. Mock::VerifyAndClearExpectations(&observer);
  185. proxy_config_service_->RemoveObserver(&observer);
  186. }
  187. TEST_F(PrefProxyConfigTrackerImplTest, Fallback) {
  188. InitConfigService(net::ProxyConfigService::CONFIG_VALID);
  189. const net::ProxyConfigService::ConfigAvailability CONFIG_VALID =
  190. net::ProxyConfigService::CONFIG_VALID;
  191. MockObserver observer;
  192. net::ProxyConfigWithAnnotation actual_config;
  193. delegate_service_->SetProxyConfig(net::ProxyConfig::CreateDirect(),
  194. net::ProxyConfigService::CONFIG_UNSET);
  195. proxy_config_service_->AddObserver(&observer);
  196. // Prepare test data.
  197. net::ProxyConfig recommended_config = net::ProxyConfig::CreateAutoDetect();
  198. net::ProxyConfig user_config =
  199. net::ProxyConfig::CreateFromCustomPacURL(GURL(kFixedPacUrl));
  200. // Set a recommended pref.
  201. EXPECT_CALL(observer,
  202. OnProxyConfigChanged(ProxyConfigMatches(recommended_config),
  203. CONFIG_VALID)).Times(1);
  204. pref_service_->SetRecommendedPref(
  205. proxy_config::prefs::kProxy,
  206. std::make_unique<base::Value>(ProxyConfigDictionary::CreateAutoDetect()));
  207. base::RunLoop().RunUntilIdle();
  208. Mock::VerifyAndClearExpectations(&observer);
  209. EXPECT_EQ(CONFIG_VALID,
  210. proxy_config_service_->GetLatestProxyConfig(&actual_config));
  211. EXPECT_TRUE(actual_config.value().Equals(recommended_config));
  212. // Override in user prefs.
  213. EXPECT_CALL(observer,
  214. OnProxyConfigChanged(ProxyConfigMatches(user_config),
  215. CONFIG_VALID)).Times(1);
  216. pref_service_->SetManagedPref(
  217. proxy_config::prefs::kProxy,
  218. std::make_unique<base::Value>(
  219. ProxyConfigDictionary::CreatePacScript(kFixedPacUrl, false)));
  220. base::RunLoop().RunUntilIdle();
  221. Mock::VerifyAndClearExpectations(&observer);
  222. EXPECT_EQ(CONFIG_VALID,
  223. proxy_config_service_->GetLatestProxyConfig(&actual_config));
  224. EXPECT_TRUE(actual_config.value().Equals(user_config));
  225. // Go back to recommended pref.
  226. EXPECT_CALL(observer,
  227. OnProxyConfigChanged(ProxyConfigMatches(recommended_config),
  228. CONFIG_VALID)).Times(1);
  229. pref_service_->RemoveManagedPref(proxy_config::prefs::kProxy);
  230. base::RunLoop().RunUntilIdle();
  231. Mock::VerifyAndClearExpectations(&observer);
  232. EXPECT_EQ(CONFIG_VALID,
  233. proxy_config_service_->GetLatestProxyConfig(&actual_config));
  234. EXPECT_TRUE(actual_config.value().Equals(recommended_config));
  235. proxy_config_service_->RemoveObserver(&observer);
  236. }
  237. TEST_F(PrefProxyConfigTrackerImplTest, ExplicitSystemSettings) {
  238. InitConfigService(net::ProxyConfigService::CONFIG_VALID);
  239. pref_service_->SetRecommendedPref(
  240. proxy_config::prefs::kProxy,
  241. std::make_unique<base::Value>(ProxyConfigDictionary::CreateAutoDetect()));
  242. pref_service_->SetUserPref(
  243. proxy_config::prefs::kProxy,
  244. std::make_unique<base::Value>(ProxyConfigDictionary::CreateSystem()));
  245. base::RunLoop().RunUntilIdle();
  246. // Test if we actually use the system setting, which is |kFixedPacUrl|.
  247. net::ProxyConfigWithAnnotation actual_config;
  248. EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
  249. proxy_config_service_->GetLatestProxyConfig(&actual_config));
  250. EXPECT_EQ(GURL(kFixedPacUrl), actual_config.value().pac_url());
  251. }
  252. // Test the case where the delegate service gets a config only after the service
  253. // is created.
  254. TEST_F(PrefProxyConfigTrackerImplTest, DelegateConfigServiceGetsConfigLate) {
  255. InitConfigService(net::ProxyConfigService::CONFIG_PENDING);
  256. testing::StrictMock<MockObserver> observer;
  257. proxy_config_service_->AddObserver(&observer);
  258. net::ProxyConfigWithAnnotation actual_config;
  259. EXPECT_EQ(net::ProxyConfigService::CONFIG_PENDING,
  260. proxy_config_service_->GetLatestProxyConfig(&actual_config));
  261. // When the delegate service gets the config, the other service should update
  262. // its observers.
  263. EXPECT_CALL(observer,
  264. OnProxyConfigChanged(ProxyConfigMatches(fixed_config_.value()),
  265. net::ProxyConfigService::CONFIG_VALID))
  266. .Times(1);
  267. delegate_service_->SetProxyConfig(fixed_config_.value(),
  268. net::ProxyConfigService::CONFIG_VALID);
  269. // Since no prefs were set, should just use the delegated config service's
  270. // settings.
  271. EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
  272. proxy_config_service_->GetLatestProxyConfig(&actual_config));
  273. EXPECT_EQ(GURL(kFixedPacUrl), actual_config.value().pac_url());
  274. proxy_config_service_->RemoveObserver(&observer);
  275. }
  276. } // namespace