xref: /aosp_15_r20/external/cronet/net/http/http_server_properties_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/http/http_server_properties.h"
6 
7 #include <memory>
8 #include <string>
9 #include <vector>
10 
11 #include "base/check.h"
12 #include "base/feature_list.h"
13 #include "base/functional/bind.h"
14 #include "base/functional/callback.h"
15 #include "base/json/json_writer.h"
16 #include "base/memory/raw_ptr.h"
17 #include "base/run_loop.h"
18 #include "base/test/scoped_feature_list.h"
19 #include "base/test/simple_test_clock.h"
20 #include "base/test/task_environment.h"
21 #include "base/time/time.h"
22 #include "base/values.h"
23 #include "net/base/features.h"
24 #include "net/base/host_port_pair.h"
25 #include "net/base/ip_address.h"
26 #include "net/base/schemeful_site.h"
27 #include "net/http/http_network_session.h"
28 #include "net/test/test_with_task_environment.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "url/gurl.h"
31 
32 namespace net {
33 
34 const base::TimeDelta BROKEN_ALT_SVC_EXPIRE_DELAYS[10] = {
35     base::Seconds(300),    base::Seconds(600),   base::Seconds(1200),
36     base::Seconds(2400),   base::Seconds(4800),  base::Seconds(9600),
37     base::Seconds(19200),  base::Seconds(38400), base::Seconds(76800),
38     base::Seconds(153600),
39 };
40 
41 class HttpServerPropertiesPeer {
42  public:
AddBrokenAlternativeServiceWithExpirationTime(HttpServerProperties * impl,const AlternativeService & alternative_service,base::TimeTicks when,const NetworkAnonymizationKey network_anonymization_key=NetworkAnonymizationKey ())43   static void AddBrokenAlternativeServiceWithExpirationTime(
44       HttpServerProperties* impl,
45       const AlternativeService& alternative_service,
46       base::TimeTicks when,
47       const NetworkAnonymizationKey network_anonymization_key =
48           NetworkAnonymizationKey()) {
49     BrokenAlternativeService broken_alternative_service(
50         alternative_service, network_anonymization_key,
51         true /* use_network_anonymization_key */);
52     BrokenAlternativeServiceList::iterator unused_it;
53     impl->broken_alternative_services_.AddToBrokenListAndMap(
54         broken_alternative_service, when, &unused_it);
55     auto it =
56         impl->broken_alternative_services_.recently_broken_alternative_services_
57             .Get(broken_alternative_service);
58     if (it == impl->broken_alternative_services_
59                   .recently_broken_alternative_services_.end()) {
60       impl->broken_alternative_services_.recently_broken_alternative_services_
61           .Put(broken_alternative_service, 1);
62     } else {
63       it->second++;
64     }
65   }
66 
ExpireBrokenAlternateProtocolMappings(HttpServerProperties * impl)67   static void ExpireBrokenAlternateProtocolMappings(
68       HttpServerProperties* impl) {
69     impl->broken_alternative_services_.ExpireBrokenAlternateProtocolMappings();
70   }
71 };
72 
73 namespace {
74 
75 // Creates a ServerInfoMapKey without a NetworkAnonymizationKey.
CreateSimpleKey(const url::SchemeHostPort & server)76 HttpServerProperties::ServerInfoMapKey CreateSimpleKey(
77     const url::SchemeHostPort& server) {
78   return HttpServerProperties::ServerInfoMapKey(
79       server, net::NetworkAnonymizationKey(),
80       false /* use_network_anonymization_key */);
81 }
82 
83 class HttpServerPropertiesTest : public TestWithTaskEnvironment {
84  protected:
HttpServerPropertiesTest()85   HttpServerPropertiesTest()
86       : TestWithTaskEnvironment(
87             base::test::TaskEnvironment::TimeSource::MOCK_TIME),
88         // Many tests assume partitioning is disabled by default.
89         feature_list_(CreateFeatureListWithPartitioningDisabled()),
90         test_tick_clock_(GetMockTickClock()),
91         impl_(nullptr /* pref_delegate */,
92               nullptr /* net_log */,
93               test_tick_clock_,
94               &test_clock_) {
95     // Set |test_clock_| to some random time.
96     test_clock_.Advance(base::Seconds(12345));
97 
98     SchemefulSite site1(GURL("https://foo.test/"));
99     network_anonymization_key1_ =
100         NetworkAnonymizationKey::CreateSameSite(site1);
101     SchemefulSite site2(GURL("https://bar.test/"));
102     network_anonymization_key2_ =
103         NetworkAnonymizationKey::CreateSameSite(site2);
104   }
105 
106   // This is a little awkward, but need to create and configure the
107   // ScopedFeatureList before creating the HttpServerProperties.
108   static std::unique_ptr<base::test::ScopedFeatureList>
CreateFeatureListWithPartitioningDisabled()109   CreateFeatureListWithPartitioningDisabled() {
110     std::unique_ptr<base::test::ScopedFeatureList> feature_list =
111         std::make_unique<base::test::ScopedFeatureList>();
112     feature_list->InitAndDisableFeature(
113         features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
114     return feature_list;
115   }
116 
HasAlternativeService(const url::SchemeHostPort & origin,const NetworkAnonymizationKey & network_anonymization_key)117   bool HasAlternativeService(
118       const url::SchemeHostPort& origin,
119       const NetworkAnonymizationKey& network_anonymization_key) {
120     const AlternativeServiceInfoVector alternative_service_info_vector =
121         impl_.GetAlternativeServiceInfos(origin, network_anonymization_key);
122     return !alternative_service_info_vector.empty();
123   }
124 
SetAlternativeService(const url::SchemeHostPort & origin,const AlternativeService & alternative_service)125   void SetAlternativeService(const url::SchemeHostPort& origin,
126                              const AlternativeService& alternative_service) {
127     const base::Time expiration = test_clock_.Now() + base::Days(1);
128     if (alternative_service.protocol == kProtoQUIC) {
129       impl_.SetQuicAlternativeService(origin, NetworkAnonymizationKey(),
130                                       alternative_service, expiration,
131                                       DefaultSupportedQuicVersions());
132     } else {
133       impl_.SetHttp2AlternativeService(origin, NetworkAnonymizationKey(),
134                                        alternative_service, expiration);
135     }
136   }
137 
MarkBrokenAndLetExpireAlternativeServiceNTimes(const AlternativeService & alternative_service,int num_times)138   void MarkBrokenAndLetExpireAlternativeServiceNTimes(
139       const AlternativeService& alternative_service,
140       int num_times) {}
141 
142   std::unique_ptr<base::test::ScopedFeatureList> feature_list_;
143 
144   raw_ptr<const base::TickClock> test_tick_clock_;
145   base::SimpleTestClock test_clock_;
146 
147   // Two different non-empty network isolation keys for use in tests that need
148   // them.
149   NetworkAnonymizationKey network_anonymization_key1_;
150   NetworkAnonymizationKey network_anonymization_key2_;
151 
152   HttpServerProperties impl_;
153 };
154 
TEST_F(HttpServerPropertiesTest,SetSupportsSpdy)155 TEST_F(HttpServerPropertiesTest, SetSupportsSpdy) {
156   // Check spdy servers are correctly set with SchemeHostPort key.
157   url::SchemeHostPort https_www_server("https", "www.google.com", 443);
158   url::SchemeHostPort http_photo_server("http", "photos.google.com", 80);
159   url::SchemeHostPort https_mail_server("https", "mail.google.com", 443);
160   // Servers with port equal to default port in scheme will drop port components
161   // when calling Serialize().
162 
163   url::SchemeHostPort http_google_server("http", "www.google.com", 443);
164   url::SchemeHostPort https_photos_server("https", "photos.google.com", 443);
165   url::SchemeHostPort valid_google_server((GURL("https://www.google.com")));
166 
167   impl_.SetSupportsSpdy(https_www_server, NetworkAnonymizationKey(), true);
168   impl_.SetSupportsSpdy(http_photo_server, NetworkAnonymizationKey(), true);
169   impl_.SetSupportsSpdy(https_mail_server, NetworkAnonymizationKey(), false);
170   EXPECT_TRUE(
171       impl_.GetSupportsSpdy(https_www_server, NetworkAnonymizationKey()));
172   EXPECT_TRUE(impl_.SupportsRequestPriority(https_www_server,
173                                             NetworkAnonymizationKey()));
174   EXPECT_TRUE(
175       impl_.GetSupportsSpdy(http_photo_server, NetworkAnonymizationKey()));
176   EXPECT_TRUE(impl_.SupportsRequestPriority(http_photo_server,
177                                             NetworkAnonymizationKey()));
178   EXPECT_FALSE(
179       impl_.GetSupportsSpdy(https_mail_server, NetworkAnonymizationKey()));
180   EXPECT_FALSE(impl_.SupportsRequestPriority(https_mail_server,
181                                              NetworkAnonymizationKey()));
182   EXPECT_FALSE(
183       impl_.GetSupportsSpdy(http_google_server, NetworkAnonymizationKey()));
184   EXPECT_FALSE(impl_.SupportsRequestPriority(http_google_server,
185                                              NetworkAnonymizationKey()));
186   EXPECT_FALSE(
187       impl_.GetSupportsSpdy(https_photos_server, NetworkAnonymizationKey()));
188   EXPECT_FALSE(impl_.SupportsRequestPriority(https_photos_server,
189                                              NetworkAnonymizationKey()));
190   EXPECT_TRUE(
191       impl_.GetSupportsSpdy(valid_google_server, NetworkAnonymizationKey()));
192   EXPECT_TRUE(impl_.SupportsRequestPriority(valid_google_server,
193                                             NetworkAnonymizationKey()));
194 
195   // Flip values of two servers.
196   impl_.SetSupportsSpdy(https_www_server, NetworkAnonymizationKey(), false);
197   impl_.SetSupportsSpdy(https_mail_server, NetworkAnonymizationKey(), true);
198   EXPECT_FALSE(
199       impl_.GetSupportsSpdy(https_www_server, NetworkAnonymizationKey()));
200   EXPECT_FALSE(impl_.SupportsRequestPriority(https_www_server,
201                                              NetworkAnonymizationKey()));
202   EXPECT_TRUE(
203       impl_.GetSupportsSpdy(https_mail_server, NetworkAnonymizationKey()));
204   EXPECT_TRUE(impl_.SupportsRequestPriority(https_mail_server,
205                                             NetworkAnonymizationKey()));
206 }
207 
TEST_F(HttpServerPropertiesTest,SetSupportsSpdyWebSockets)208 TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWebSockets) {
209   // The https and wss servers should be treated as the same server, as should
210   // the http and ws servers.
211   url::SchemeHostPort https_server("https", "www.test.com", 443);
212   url::SchemeHostPort wss_server("wss", "www.test.com", 443);
213   url::SchemeHostPort http_server("http", "www.test.com", 443);
214   url::SchemeHostPort ws_server("ws", "www.test.com", 443);
215 
216   EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
217   EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
218   EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
219   EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
220 
221   impl_.SetSupportsSpdy(wss_server, NetworkAnonymizationKey(), true);
222   EXPECT_TRUE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
223   EXPECT_TRUE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
224   EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
225   EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
226 
227   impl_.SetSupportsSpdy(http_server, NetworkAnonymizationKey(), true);
228   EXPECT_TRUE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
229   EXPECT_TRUE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
230   EXPECT_TRUE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
231   EXPECT_TRUE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
232 
233   impl_.SetSupportsSpdy(https_server, NetworkAnonymizationKey(), false);
234   EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
235   EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
236   EXPECT_TRUE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
237   EXPECT_TRUE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
238 
239   impl_.SetSupportsSpdy(ws_server, NetworkAnonymizationKey(), false);
240   EXPECT_FALSE(impl_.GetSupportsSpdy(https_server, NetworkAnonymizationKey()));
241   EXPECT_FALSE(impl_.GetSupportsSpdy(wss_server, NetworkAnonymizationKey()));
242   EXPECT_FALSE(impl_.GetSupportsSpdy(http_server, NetworkAnonymizationKey()));
243   EXPECT_FALSE(impl_.GetSupportsSpdy(ws_server, NetworkAnonymizationKey()));
244 }
245 
TEST_F(HttpServerPropertiesTest,SetSupportsSpdyWithNetworkIsolationKey)246 TEST_F(HttpServerPropertiesTest, SetSupportsSpdyWithNetworkIsolationKey) {
247   const url::SchemeHostPort kServer("https", "foo.test", 443);
248 
249   EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_anonymization_key1_));
250   EXPECT_FALSE(
251       impl_.SupportsRequestPriority(kServer, network_anonymization_key1_));
252   EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
253   EXPECT_FALSE(
254       impl_.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
255 
256   // Without network isolation keys enabled for HttpServerProperties, passing in
257   // a NetworkAnonymizationKey should have no effect on behavior.
258   for (const auto& network_anonymization_key_to_set :
259        {NetworkAnonymizationKey(), network_anonymization_key1_}) {
260     impl_.SetSupportsSpdy(kServer, network_anonymization_key_to_set, true);
261     EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, network_anonymization_key1_));
262     EXPECT_TRUE(
263         impl_.SupportsRequestPriority(kServer, network_anonymization_key1_));
264     EXPECT_TRUE(impl_.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
265     EXPECT_TRUE(
266         impl_.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
267 
268     impl_.SetSupportsSpdy(kServer, network_anonymization_key_to_set, false);
269     EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, network_anonymization_key1_));
270     EXPECT_FALSE(
271         impl_.SupportsRequestPriority(kServer, network_anonymization_key1_));
272     EXPECT_FALSE(impl_.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
273     EXPECT_FALSE(
274         impl_.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
275   }
276 
277   // With network isolation keys enabled for HttpServerProperties, the
278   // NetworkAnonymizationKey argument should be respected.
279 
280   base::test::ScopedFeatureList feature_list;
281   feature_list.InitAndEnableFeature(
282       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
283   // Since HttpServerProperties caches the feature value, have to create a new
284   // one.
285   HttpServerProperties properties(nullptr /* pref_delegate */,
286                                   nullptr /* net_log */, test_tick_clock_,
287                                   &test_clock_);
288 
289   EXPECT_FALSE(
290       properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
291   EXPECT_FALSE(
292       properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
293   EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
294   EXPECT_FALSE(
295       properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
296 
297   properties.SetSupportsSpdy(kServer, network_anonymization_key1_, true);
298   EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
299   EXPECT_TRUE(
300       properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
301   EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
302   EXPECT_FALSE(
303       properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
304 
305   properties.SetSupportsSpdy(kServer, NetworkAnonymizationKey(), true);
306   EXPECT_TRUE(properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
307   EXPECT_TRUE(
308       properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
309   EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
310   EXPECT_TRUE(
311       properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
312 
313   properties.SetSupportsSpdy(kServer, network_anonymization_key1_, false);
314   EXPECT_FALSE(
315       properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
316   EXPECT_FALSE(
317       properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
318   EXPECT_TRUE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
319   EXPECT_TRUE(
320       properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
321 
322   properties.SetSupportsSpdy(kServer, NetworkAnonymizationKey(), false);
323   EXPECT_FALSE(
324       properties.GetSupportsSpdy(kServer, network_anonymization_key1_));
325   EXPECT_FALSE(
326       properties.SupportsRequestPriority(kServer, network_anonymization_key1_));
327   EXPECT_FALSE(properties.GetSupportsSpdy(kServer, NetworkAnonymizationKey()));
328   EXPECT_FALSE(
329       properties.SupportsRequestPriority(kServer, NetworkAnonymizationKey()));
330 }
331 
TEST_F(HttpServerPropertiesTest,LoadSupportsSpdy)332 TEST_F(HttpServerPropertiesTest, LoadSupportsSpdy) {
333   HttpServerProperties::ServerInfo supports_spdy;
334   supports_spdy.supports_spdy = true;
335   HttpServerProperties::ServerInfo no_spdy;
336   no_spdy.supports_spdy = false;
337 
338   url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
339   url::SchemeHostPort spdy_server_photos("https", "photos.google.com", 443);
340   url::SchemeHostPort spdy_server_docs("https", "docs.google.com", 443);
341   url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
342 
343   // Check by initializing empty spdy servers.
344   std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers =
345       std::make_unique<HttpServerProperties::ServerInfoMap>();
346   impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers));
347   EXPECT_FALSE(
348       impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
349 
350   // Check by initializing www.google.com:443 and photos.google.com:443 as spdy
351   // servers.
352   std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers1 =
353       std::make_unique<HttpServerProperties::ServerInfoMap>();
354   spdy_servers1->Put(CreateSimpleKey(spdy_server_google), supports_spdy);
355   spdy_servers1->Put(CreateSimpleKey(spdy_server_photos), no_spdy);
356   impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers1));
357   // Note: these calls affect MRU order.
358   EXPECT_TRUE(
359       impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
360   EXPECT_FALSE(
361       impl_.GetSupportsSpdy(spdy_server_photos, NetworkAnonymizationKey()));
362 
363   // Verify google and photos are in the list in MRU order.
364   ASSERT_EQ(2U, impl_.server_info_map_for_testing().size());
365   auto it = impl_.server_info_map_for_testing().begin();
366   EXPECT_EQ(spdy_server_photos, it->first.server);
367   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
368   ASSERT_TRUE(it->second.supports_spdy.has_value());
369   EXPECT_FALSE(*it->second.supports_spdy);
370   ++it;
371   EXPECT_EQ(spdy_server_google, it->first.server);
372   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
373   ASSERT_TRUE(it->second.supports_spdy.has_value());
374   EXPECT_TRUE(*it->second.supports_spdy);
375 
376   // Check by initializing mail.google.com:443 and docs.google.com:443.
377   std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers2 =
378       std::make_unique<HttpServerProperties::ServerInfoMap>();
379   spdy_servers2->Put(CreateSimpleKey(spdy_server_mail), supports_spdy);
380   spdy_servers2->Put(CreateSimpleKey(spdy_server_docs), supports_spdy);
381   impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers2));
382 
383   // Verify all the servers are in the list in MRU order. Note that
384   // OnServerInfoLoadedForTesting will put existing spdy server entries in
385   // front of newly added entries.
386   ASSERT_EQ(4U, impl_.server_info_map_for_testing().size());
387   it = impl_.server_info_map_for_testing().begin();
388   EXPECT_EQ(spdy_server_photos, it->first.server);
389   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
390   ASSERT_TRUE(it->second.supports_spdy.has_value());
391   EXPECT_FALSE(*it->second.supports_spdy);
392   ++it;
393   EXPECT_EQ(spdy_server_google, it->first.server);
394   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
395   ASSERT_TRUE(it->second.supports_spdy.has_value());
396   EXPECT_TRUE(*it->second.supports_spdy);
397   ++it;
398   EXPECT_EQ(spdy_server_docs, it->first.server);
399   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
400   ASSERT_TRUE(it->second.supports_spdy.has_value());
401   EXPECT_TRUE(*it->second.supports_spdy);
402   ++it;
403   EXPECT_EQ(spdy_server_mail, it->first.server);
404   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
405   ASSERT_TRUE(it->second.supports_spdy.has_value());
406   EXPECT_TRUE(*it->second.supports_spdy);
407 
408   // Check these in reverse MRU order so that MRU order stays the same.
409   EXPECT_TRUE(
410       impl_.GetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey()));
411   EXPECT_TRUE(
412       impl_.GetSupportsSpdy(spdy_server_docs, NetworkAnonymizationKey()));
413   EXPECT_TRUE(
414       impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
415   EXPECT_FALSE(
416       impl_.GetSupportsSpdy(spdy_server_photos, NetworkAnonymizationKey()));
417 
418   // Verify that old values loaded from disk take precedence over newer learned
419   // values and also verify the recency list order is unchanged.
420   std::unique_ptr<HttpServerProperties::ServerInfoMap> spdy_servers3 =
421       std::make_unique<HttpServerProperties::ServerInfoMap>();
422   spdy_servers3->Put(CreateSimpleKey(spdy_server_mail), no_spdy);
423   spdy_servers3->Put(CreateSimpleKey(spdy_server_photos), supports_spdy);
424   impl_.OnServerInfoLoadedForTesting(std::move(spdy_servers3));
425 
426   // Verify the entries are in the same order.
427   ASSERT_EQ(4U, impl_.server_info_map_for_testing().size());
428   it = impl_.server_info_map_for_testing().begin();
429   EXPECT_EQ(spdy_server_photos, it->first.server);
430   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
431   ASSERT_TRUE(it->second.supports_spdy.has_value());
432   EXPECT_TRUE(*it->second.supports_spdy);
433   ++it;
434   EXPECT_EQ(spdy_server_google, it->first.server);
435   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
436   ASSERT_TRUE(it->second.supports_spdy.has_value());
437   EXPECT_TRUE(*it->second.supports_spdy);
438   ++it;
439   EXPECT_EQ(spdy_server_docs, it->first.server);
440   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
441   ASSERT_TRUE(it->second.supports_spdy.has_value());
442   EXPECT_TRUE(*it->second.supports_spdy);
443   ++it;
444   EXPECT_EQ(spdy_server_mail, it->first.server);
445   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
446   ASSERT_TRUE(it->second.supports_spdy.has_value());
447   EXPECT_FALSE(*it->second.supports_spdy);
448 
449   // Verify photos server doesn't support SPDY and other servers support SPDY.
450   EXPECT_FALSE(
451       impl_.GetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey()));
452   EXPECT_TRUE(
453       impl_.GetSupportsSpdy(spdy_server_docs, NetworkAnonymizationKey()));
454   EXPECT_TRUE(
455       impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
456   EXPECT_TRUE(
457       impl_.GetSupportsSpdy(spdy_server_photos, NetworkAnonymizationKey()));
458 }
459 
TEST_F(HttpServerPropertiesTest,SupportsRequestPriority)460 TEST_F(HttpServerPropertiesTest, SupportsRequestPriority) {
461   url::SchemeHostPort spdy_server_empty("https", std::string(), 443);
462   EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_empty,
463                                              NetworkAnonymizationKey()));
464 
465   // Add www.google.com:443 as supporting SPDY.
466   url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
467   impl_.SetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey(), true);
468   EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_google,
469                                             NetworkAnonymizationKey()));
470 
471   // Add mail.google.com:443 as not supporting SPDY.
472   url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
473   EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_mail,
474                                              NetworkAnonymizationKey()));
475 
476   // Add docs.google.com:443 as supporting SPDY.
477   url::SchemeHostPort spdy_server_docs("https", "docs.google.com", 443);
478   impl_.SetSupportsSpdy(spdy_server_docs, NetworkAnonymizationKey(), true);
479   EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_docs,
480                                             NetworkAnonymizationKey()));
481 
482   // Add www.youtube.com:443 as supporting QUIC.
483   url::SchemeHostPort youtube_server("https", "www.youtube.com", 443);
484   const AlternativeService alternative_service1(kProtoQUIC, "www.youtube.com",
485                                                 443);
486   SetAlternativeService(youtube_server, alternative_service1);
487   EXPECT_TRUE(
488       impl_.SupportsRequestPriority(youtube_server, NetworkAnonymizationKey()));
489 
490   // Add www.example.com:443 with two alternative services, one supporting QUIC.
491   url::SchemeHostPort example_server("https", "www.example.com", 443);
492   const AlternativeService alternative_service2(kProtoHTTP2, "", 443);
493   SetAlternativeService(example_server, alternative_service2);
494   SetAlternativeService(example_server, alternative_service1);
495   EXPECT_TRUE(
496       impl_.SupportsRequestPriority(example_server, NetworkAnonymizationKey()));
497 
498   // Verify all the entries are the same after additions.
499   EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_google,
500                                             NetworkAnonymizationKey()));
501   EXPECT_FALSE(impl_.SupportsRequestPriority(spdy_server_mail,
502                                              NetworkAnonymizationKey()));
503   EXPECT_TRUE(impl_.SupportsRequestPriority(spdy_server_docs,
504                                             NetworkAnonymizationKey()));
505   EXPECT_TRUE(
506       impl_.SupportsRequestPriority(youtube_server, NetworkAnonymizationKey()));
507   EXPECT_TRUE(
508       impl_.SupportsRequestPriority(example_server, NetworkAnonymizationKey()));
509 }
510 
TEST_F(HttpServerPropertiesTest,ClearSupportsSpdy)511 TEST_F(HttpServerPropertiesTest, ClearSupportsSpdy) {
512   // Add www.google.com:443 and mail.google.com:443 as supporting SPDY.
513   url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
514   impl_.SetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey(), true);
515   url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
516   impl_.SetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey(), true);
517 
518   EXPECT_TRUE(
519       impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
520   EXPECT_TRUE(
521       impl_.GetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey()));
522 
523   base::RunLoop run_loop;
524   bool callback_invoked_ = false;
525   impl_.Clear(base::BindOnce(
526       [](bool* callback_invoked, base::OnceClosure quit_closure) {
527         *callback_invoked = true;
528         std::move(quit_closure).Run();
529       },
530       &callback_invoked_, run_loop.QuitClosure()));
531   EXPECT_FALSE(
532       impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
533   EXPECT_FALSE(
534       impl_.GetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey()));
535 
536   // Callback should be run asynchronously.
537   EXPECT_FALSE(callback_invoked_);
538   run_loop.Run();
539   EXPECT_TRUE(callback_invoked_);
540 }
541 
TEST_F(HttpServerPropertiesTest,MRUOfServerInfoMap)542 TEST_F(HttpServerPropertiesTest, MRUOfServerInfoMap) {
543   url::SchemeHostPort spdy_server_google("https", "www.google.com", 443);
544   url::SchemeHostPort spdy_server_mail("https", "mail.google.com", 443);
545 
546   // Add www.google.com:443 as supporting SPDY.
547   impl_.SetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey(), true);
548   ASSERT_EQ(1u, impl_.server_info_map_for_testing().size());
549   auto it = impl_.server_info_map_for_testing().begin();
550   ASSERT_EQ(spdy_server_google, it->first.server);
551   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
552 
553   // Add mail.google.com:443 as supporting SPDY. Verify mail.google.com:443 and
554   // www.google.com:443 are in the list.
555   impl_.SetSupportsSpdy(spdy_server_mail, NetworkAnonymizationKey(), true);
556   ASSERT_EQ(2u, impl_.server_info_map_for_testing().size());
557   it = impl_.server_info_map_for_testing().begin();
558   ASSERT_EQ(spdy_server_mail, it->first.server);
559   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
560   ++it;
561   ASSERT_EQ(spdy_server_google, it->first.server);
562   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
563 
564   // Get www.google.com:443. It should become the most-recently-used server.
565   EXPECT_TRUE(
566       impl_.GetSupportsSpdy(spdy_server_google, NetworkAnonymizationKey()));
567   ASSERT_EQ(2u, impl_.server_info_map_for_testing().size());
568   it = impl_.server_info_map_for_testing().begin();
569   ASSERT_EQ(spdy_server_google, it->first.server);
570   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
571   ++it;
572   ASSERT_EQ(spdy_server_mail, it->first.server);
573   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
574 }
575 
576 typedef HttpServerPropertiesTest AlternateProtocolServerPropertiesTest;
577 
TEST_F(AlternateProtocolServerPropertiesTest,Basic)578 TEST_F(AlternateProtocolServerPropertiesTest, Basic) {
579   url::SchemeHostPort test_server("http", "foo", 80);
580   EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
581 
582   AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
583   SetAlternativeService(test_server, alternative_service);
584   const AlternativeServiceInfoVector alternative_service_info_vector =
585       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
586   ASSERT_EQ(1u, alternative_service_info_vector.size());
587   EXPECT_EQ(alternative_service,
588             alternative_service_info_vector[0].alternative_service());
589 
590   impl_.Clear(base::OnceClosure());
591   EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
592 }
593 
TEST_F(AlternateProtocolServerPropertiesTest,ExcludeOrigin)594 TEST_F(AlternateProtocolServerPropertiesTest, ExcludeOrigin) {
595   AlternativeServiceInfoVector alternative_service_info_vector;
596   base::Time expiration = test_clock_.Now() + base::Days(1);
597   // Same hostname, same port, TCP: should be ignored.
598   AlternativeServiceInfo alternative_service_info1 =
599       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
600           AlternativeService(kProtoHTTP2, "foo", 443), expiration);
601   alternative_service_info_vector.push_back(alternative_service_info1);
602   // Different hostname: GetAlternativeServiceInfos should return this one.
603   AlternativeServiceInfo alternative_service_info2 =
604       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
605           AlternativeService(kProtoHTTP2, "bar", 443), expiration);
606   alternative_service_info_vector.push_back(alternative_service_info2);
607   // Different port: GetAlternativeServiceInfos should return this one too.
608   AlternativeServiceInfo alternative_service_info3 =
609       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
610           AlternativeService(kProtoHTTP2, "foo", 80), expiration);
611   alternative_service_info_vector.push_back(alternative_service_info3);
612   // QUIC: GetAlternativeServices should return this one too.
613   AlternativeServiceInfo alternative_service_info4 =
614       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
615           AlternativeService(kProtoQUIC, "foo", 443), expiration,
616           DefaultSupportedQuicVersions());
617   alternative_service_info_vector.push_back(alternative_service_info4);
618 
619   url::SchemeHostPort test_server("https", "foo", 443);
620   impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
621                                alternative_service_info_vector);
622 
623   const AlternativeServiceInfoVector alternative_service_info_vector2 =
624       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
625   ASSERT_EQ(3u, alternative_service_info_vector2.size());
626   EXPECT_EQ(alternative_service_info2, alternative_service_info_vector2[0]);
627   EXPECT_EQ(alternative_service_info3, alternative_service_info_vector2[1]);
628   EXPECT_EQ(alternative_service_info4, alternative_service_info_vector2[2]);
629 }
630 
TEST_F(AlternateProtocolServerPropertiesTest,Set)631 TEST_F(AlternateProtocolServerPropertiesTest, Set) {
632   // |test_server1| has an alternative service, which will not be
633   // affected by OnServerInfoLoadedForTesting(), because
634   // |server_info_map| does not have an entry for
635   // |test_server1|.
636   url::SchemeHostPort test_server1("http", "foo1", 80);
637   const AlternativeService alternative_service1(kProtoHTTP2, "bar1", 443);
638   const base::Time now = test_clock_.Now();
639   base::Time expiration1 = now + base::Days(1);
640   // 1st entry in the memory.
641   impl_.SetHttp2AlternativeService(test_server1, NetworkAnonymizationKey(),
642                                    alternative_service1, expiration1);
643 
644   // |test_server2| has an alternative service, which will be
645   // overwritten by OnServerInfoLoadedForTesting(), because
646   // |server_info_map| has an entry for |test_server2|.
647   AlternativeServiceInfoVector alternative_service_info_vector;
648   const AlternativeService alternative_service2(kProtoHTTP2, "bar2", 443);
649   base::Time expiration2 = now + base::Days(2);
650   alternative_service_info_vector.push_back(
651       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
652           alternative_service2, expiration2));
653   url::SchemeHostPort test_server2("http", "foo2", 80);
654   // 0th entry in the memory.
655   impl_.SetAlternativeServices(test_server2, NetworkAnonymizationKey(),
656                                alternative_service_info_vector);
657 
658   // Prepare |server_info_map| to be loaded by OnServerInfoLoadedForTesting().
659   std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
660       std::make_unique<HttpServerProperties::ServerInfoMap>();
661   const AlternativeService alternative_service3(kProtoHTTP2, "bar3", 123);
662   base::Time expiration3 = now + base::Days(3);
663   const AlternativeServiceInfo alternative_service_info1 =
664       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
665           alternative_service3, expiration3);
666   // Simulate updating data for 0th entry with data from Preferences.
667   server_info_map->GetOrPut(CreateSimpleKey(test_server2))
668       ->second.alternative_services =
669       AlternativeServiceInfoVector(/*size=*/1, alternative_service_info1);
670 
671   url::SchemeHostPort test_server3("http", "foo3", 80);
672   const AlternativeService alternative_service4(kProtoHTTP2, "bar4", 1234);
673   base::Time expiration4 = now + base::Days(4);
674   const AlternativeServiceInfo alternative_service_info2 =
675       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
676           alternative_service4, expiration4);
677   // Add an old entry from Preferences, this will be added to end of recency
678   // list.
679   server_info_map->GetOrPut(CreateSimpleKey(test_server3))
680       ->second.alternative_services =
681       AlternativeServiceInfoVector(/*size=*/1, alternative_service_info2);
682 
683   // MRU list will be test_server2, test_server1, test_server3.
684   impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
685 
686   // Verify server_info_map.
687   const HttpServerProperties::ServerInfoMap& map =
688       impl_.server_info_map_for_testing();
689   ASSERT_EQ(3u, map.size());
690   auto map_it = map.begin();
691 
692   EXPECT_EQ(test_server2, map_it->first.server);
693   EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
694   ASSERT_TRUE(map_it->second.alternative_services.has_value());
695   const AlternativeServiceInfoVector* service_info =
696       &map_it->second.alternative_services.value();
697   ASSERT_EQ(1u, service_info->size());
698   EXPECT_EQ(alternative_service3, (*service_info)[0].alternative_service());
699   EXPECT_EQ(expiration3, (*service_info)[0].expiration());
700 
701   ++map_it;
702   EXPECT_EQ(test_server1, map_it->first.server);
703   EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
704   ASSERT_TRUE(map_it->second.alternative_services.has_value());
705   service_info = &map_it->second.alternative_services.value();
706   ASSERT_EQ(1u, service_info->size());
707   EXPECT_EQ(alternative_service1, (*service_info)[0].alternative_service());
708   EXPECT_EQ(expiration1, (*service_info)[0].expiration());
709 
710   ++map_it;
711   EXPECT_EQ(map_it->first.server, test_server3);
712   EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
713   ASSERT_TRUE(map_it->second.alternative_services.has_value());
714   service_info = &map_it->second.alternative_services.value();
715   ASSERT_EQ(1u, service_info->size());
716   EXPECT_EQ(alternative_service4, (*service_info)[0].alternative_service());
717   EXPECT_EQ(expiration4, (*service_info)[0].expiration());
718 }
719 
TEST_F(AlternateProtocolServerPropertiesTest,SetWebSockets)720 TEST_F(AlternateProtocolServerPropertiesTest, SetWebSockets) {
721   // The https and wss servers should be treated as the same server, as should
722   // the http and ws servers.
723   url::SchemeHostPort https_server("https", "www.test.com", 443);
724   url::SchemeHostPort wss_server("wss", "www.test.com", 443);
725   url::SchemeHostPort http_server("http", "www.test.com", 443);
726   url::SchemeHostPort ws_server("ws", "www.test.com", 443);
727 
728   AlternativeService alternative_service(kProtoHTTP2, "bar", 443);
729 
730   EXPECT_EQ(
731       0u,
732       impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
733           .size());
734   EXPECT_EQ(
735       0u,
736       impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
737           .size());
738   EXPECT_EQ(
739       0u,
740       impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
741           .size());
742   EXPECT_EQ(
743       0u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
744               .size());
745 
746   SetAlternativeService(wss_server, alternative_service);
747   EXPECT_EQ(
748       1u,
749       impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
750           .size());
751   EXPECT_EQ(
752       1u,
753       impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
754           .size());
755   EXPECT_EQ(
756       0u,
757       impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
758           .size());
759   EXPECT_EQ(
760       0u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
761               .size());
762 
763   SetAlternativeService(http_server, alternative_service);
764   EXPECT_EQ(
765       1u,
766       impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
767           .size());
768   EXPECT_EQ(
769       1u,
770       impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
771           .size());
772   EXPECT_EQ(
773       1u,
774       impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
775           .size());
776   EXPECT_EQ(
777       1u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
778               .size());
779 
780   impl_.SetAlternativeServices(https_server, NetworkAnonymizationKey(),
781                                AlternativeServiceInfoVector());
782   EXPECT_EQ(
783       0u,
784       impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
785           .size());
786   EXPECT_EQ(
787       0u,
788       impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
789           .size());
790   EXPECT_EQ(
791       1u,
792       impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
793           .size());
794   EXPECT_EQ(
795       1u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
796               .size());
797 
798   impl_.SetAlternativeServices(ws_server, NetworkAnonymizationKey(),
799                                AlternativeServiceInfoVector());
800   EXPECT_EQ(
801       0u,
802       impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
803           .size());
804   EXPECT_EQ(
805       0u,
806       impl_.GetAlternativeServiceInfos(wss_server, NetworkAnonymizationKey())
807           .size());
808   EXPECT_EQ(
809       0u,
810       impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
811           .size());
812   EXPECT_EQ(
813       0u, impl_.GetAlternativeServiceInfos(ws_server, NetworkAnonymizationKey())
814               .size());
815 }
816 
TEST_F(AlternateProtocolServerPropertiesTest,SetWithNetworkIsolationKey)817 TEST_F(AlternateProtocolServerPropertiesTest, SetWithNetworkIsolationKey) {
818   const url::SchemeHostPort kServer("https", "foo.test", 443);
819   const AlternativeServiceInfoVector kAlternativeServices(
820       {AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
821           AlternativeService(kProtoHTTP2, "foo", 443),
822           base::Time::Now() + base::Days(1) /* expiration */)});
823 
824   EXPECT_TRUE(
825       impl_.GetAlternativeServiceInfos(kServer, network_anonymization_key1_)
826           .empty());
827   EXPECT_TRUE(
828       impl_.GetAlternativeServiceInfos(kServer, NetworkAnonymizationKey())
829           .empty());
830 
831   // Without network isolation keys enabled for HttpServerProperties, passing in
832   // a NetworkAnonymizationKey should have no effect on behavior.
833   for (const auto& network_anonymization_key_to_set :
834        {NetworkAnonymizationKey(), network_anonymization_key1_}) {
835     impl_.SetAlternativeServices(kServer, network_anonymization_key_to_set,
836                                  kAlternativeServices);
837     EXPECT_EQ(kAlternativeServices, impl_.GetAlternativeServiceInfos(
838                                         kServer, network_anonymization_key1_));
839     EXPECT_EQ(kAlternativeServices, impl_.GetAlternativeServiceInfos(
840                                         kServer, NetworkAnonymizationKey()));
841 
842     impl_.SetAlternativeServices(kServer, network_anonymization_key_to_set,
843                                  AlternativeServiceInfoVector());
844     EXPECT_TRUE(
845         impl_.GetAlternativeServiceInfos(kServer, network_anonymization_key1_)
846             .empty());
847     EXPECT_TRUE(
848         impl_.GetAlternativeServiceInfos(kServer, NetworkAnonymizationKey())
849             .empty());
850   }
851 
852   // Check that with network isolation keys enabled for HttpServerProperties,
853   // the NetworkAnonymizationKey argument is respected.
854 
855   base::test::ScopedFeatureList feature_list;
856   feature_list.InitAndEnableFeature(
857       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
858   // Since HttpServerProperties caches the feature value, have to create a new
859   // one.
860   HttpServerProperties properties(nullptr /* pref_delegate */,
861                                   nullptr /* net_log */, test_tick_clock_,
862                                   &test_clock_);
863 
864   properties.SetAlternativeServices(kServer, network_anonymization_key1_,
865                                     kAlternativeServices);
866   EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
867                                       kServer, network_anonymization_key1_));
868   EXPECT_TRUE(
869       properties.GetAlternativeServiceInfos(kServer, NetworkAnonymizationKey())
870           .empty());
871 
872   properties.SetAlternativeServices(kServer, NetworkAnonymizationKey(),
873                                     kAlternativeServices);
874   EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
875                                       kServer, network_anonymization_key1_));
876   EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
877                                       kServer, NetworkAnonymizationKey()));
878 
879   properties.SetAlternativeServices(kServer, network_anonymization_key1_,
880                                     AlternativeServiceInfoVector());
881   EXPECT_TRUE(
882       properties
883           .GetAlternativeServiceInfos(kServer, network_anonymization_key1_)
884           .empty());
885   EXPECT_EQ(kAlternativeServices, properties.GetAlternativeServiceInfos(
886                                       kServer, NetworkAnonymizationKey()));
887 
888   properties.SetAlternativeServices(kServer, NetworkAnonymizationKey(),
889                                     AlternativeServiceInfoVector());
890   EXPECT_TRUE(
891       properties
892           .GetAlternativeServiceInfos(kServer, network_anonymization_key1_)
893           .empty());
894   EXPECT_TRUE(
895       properties.GetAlternativeServiceInfos(kServer, NetworkAnonymizationKey())
896           .empty());
897 }
898 
899 // Regression test for https://crbug.com/504032:
900 // OnServerInfoLoadedForTesting() should not crash if there is an
901 // empty hostname is the mapping.
TEST_F(AlternateProtocolServerPropertiesTest,SetWithEmptyHostname)902 TEST_F(AlternateProtocolServerPropertiesTest, SetWithEmptyHostname) {
903   url::SchemeHostPort server("https", "foo", 443);
904   const AlternativeService alternative_service_with_empty_hostname(kProtoHTTP2,
905                                                                    "", 1234);
906   const AlternativeService alternative_service_with_foo_hostname(kProtoHTTP2,
907                                                                  "foo", 1234);
908   SetAlternativeService(server, alternative_service_with_empty_hostname);
909   impl_.MarkAlternativeServiceBroken(alternative_service_with_foo_hostname,
910                                      NetworkAnonymizationKey());
911 
912   std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
913       std::make_unique<HttpServerProperties::ServerInfoMap>();
914   impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
915 
916   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(
917       alternative_service_with_foo_hostname, NetworkAnonymizationKey()));
918   const AlternativeServiceInfoVector alternative_service_info_vector =
919       impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey());
920   ASSERT_EQ(1u, alternative_service_info_vector.size());
921   EXPECT_EQ(alternative_service_with_foo_hostname,
922             alternative_service_info_vector[0].alternative_service());
923 }
924 
925 // GetAlternativeServiceInfos() should remove |server_info_map_|
926 // elements with empty value.
TEST_F(AlternateProtocolServerPropertiesTest,EmptyVector)927 TEST_F(AlternateProtocolServerPropertiesTest, EmptyVector) {
928   url::SchemeHostPort server("https", "foo", 443);
929   const AlternativeService alternative_service(kProtoHTTP2, "bar", 443);
930   base::Time expiration = test_clock_.Now() - base::Days(1);
931   const AlternativeServiceInfo alternative_service_info =
932       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
933           alternative_service, expiration);
934   std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
935       std::make_unique<HttpServerProperties::ServerInfoMap>();
936   server_info_map->GetOrPut(CreateSimpleKey(server))
937       ->second.alternative_services = AlternativeServiceInfoVector(
938       /*size=*/1, alternative_service_info);
939 
940   // Prepare |server_info_map_| with a single key that has a single
941   // AlternativeServiceInfo with identical hostname and port.
942   impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
943 
944   // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
945   // |server_info_map_|, emptying the AlternativeServiceInfoVector
946   // corresponding to |server|.
947   ASSERT_TRUE(
948       impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
949           .empty());
950 
951   // GetAlternativeServiceInfos() should remove this key from
952   // |server_info_map_|, and SetAlternativeServices() should not crash.
953   impl_.SetAlternativeServices(
954       server, NetworkAnonymizationKey(),
955       AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
956 
957   // There should still be no alternative service assigned to |server|.
958   ASSERT_TRUE(
959       impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
960           .empty());
961 }
962 
963 // Regression test for https://crbug.com/516486 for the canonical host case.
TEST_F(AlternateProtocolServerPropertiesTest,EmptyVectorForCanonical)964 TEST_F(AlternateProtocolServerPropertiesTest, EmptyVectorForCanonical) {
965   url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
966   url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
967   const AlternativeService alternative_service(kProtoHTTP2, "", 443);
968   base::Time expiration = test_clock_.Now() - base::Days(1);
969   const AlternativeServiceInfo alternative_service_info =
970       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
971           alternative_service, expiration);
972   std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
973       std::make_unique<HttpServerProperties::ServerInfoMap>();
974   server_info_map->GetOrPut(CreateSimpleKey(canonical_server))
975       ->second.alternative_services =
976       AlternativeServiceInfoVector(/*size=*/1, alternative_service_info);
977 
978   // Prepare |server_info_map_| with a single key that has a single
979   // AlternativeServiceInfo with identical hostname and port.
980   impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
981 
982   // GetAlternativeServiceInfos() should remove such AlternativeServiceInfo from
983   // |server_info_map_|, emptying the AlternativeServiceInfoVector
984   // corresponding to |canonical_server|, even when looking up
985   // alternative services for |server|.
986   ASSERT_TRUE(
987       impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
988           .empty());
989 
990   // GetAlternativeServiceInfos() should remove this key from
991   // |server_info_map_|, and SetAlternativeServices() should not crash.
992   impl_.SetAlternativeServices(
993       canonical_server, NetworkAnonymizationKey(),
994       AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
995 
996   // There should still be no alternative service assigned to
997   // |canonical_server|.
998   ASSERT_TRUE(impl_
999                   .GetAlternativeServiceInfos(canonical_server,
1000                                               NetworkAnonymizationKey())
1001                   .empty());
1002 }
1003 
TEST_F(AlternateProtocolServerPropertiesTest,ClearServerWithCanonical)1004 TEST_F(AlternateProtocolServerPropertiesTest, ClearServerWithCanonical) {
1005   url::SchemeHostPort server("https", "foo.c.youtube.com", 443);
1006   url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1007   const AlternativeService alternative_service(kProtoQUIC, "", 443);
1008   base::Time expiration = test_clock_.Now() + base::Days(1);
1009   const AlternativeServiceInfo alternative_service_info =
1010       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
1011           alternative_service, expiration, DefaultSupportedQuicVersions());
1012 
1013   impl_.SetAlternativeServices(
1014       canonical_server, NetworkAnonymizationKey(),
1015       AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
1016 
1017   // Make sure the canonical service is returned for the other server.
1018   const AlternativeServiceInfoVector alternative_service_info_vector =
1019       impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey());
1020   ASSERT_EQ(1u, alternative_service_info_vector.size());
1021   EXPECT_EQ(kProtoQUIC,
1022             alternative_service_info_vector[0].alternative_service().protocol);
1023   EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port);
1024 
1025   // Now clear the alternatives for the other server and make sure it stays
1026   // cleared.
1027   // GetAlternativeServices() should remove this key from
1028   // |server_info_map_|, and SetAlternativeServices() should not crash.
1029   impl_.SetAlternativeServices(server, NetworkAnonymizationKey(),
1030                                AlternativeServiceInfoVector());
1031 
1032   ASSERT_TRUE(
1033       impl_.GetAlternativeServiceInfos(server, NetworkAnonymizationKey())
1034           .empty());
1035 }
1036 
TEST_F(AlternateProtocolServerPropertiesTest,MRUOfGetAlternativeServiceInfos)1037 TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternativeServiceInfos) {
1038   url::SchemeHostPort test_server1("http", "foo1", 80);
1039   const AlternativeService alternative_service1(kProtoHTTP2, "foo1", 443);
1040   SetAlternativeService(test_server1, alternative_service1);
1041   url::SchemeHostPort test_server2("http", "foo2", 80);
1042   const AlternativeService alternative_service2(kProtoHTTP2, "foo2", 1234);
1043   SetAlternativeService(test_server2, alternative_service2);
1044 
1045   const HttpServerProperties::ServerInfoMap& map =
1046       impl_.server_info_map_for_testing();
1047   auto it = map.begin();
1048   EXPECT_EQ(test_server2, it->first.server);
1049   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1050   ASSERT_TRUE(it->second.alternative_services.has_value());
1051   ASSERT_EQ(1u, it->second.alternative_services->size());
1052   EXPECT_EQ(alternative_service2,
1053             it->second.alternative_services.value()[0].alternative_service());
1054 
1055   const AlternativeServiceInfoVector alternative_service_info_vector =
1056       impl_.GetAlternativeServiceInfos(test_server1, NetworkAnonymizationKey());
1057   ASSERT_EQ(1u, alternative_service_info_vector.size());
1058   EXPECT_EQ(alternative_service1,
1059             alternative_service_info_vector[0].alternative_service());
1060 
1061   // GetAlternativeServices should reorder the AlternateProtocol map.
1062   it = map.begin();
1063   EXPECT_EQ(test_server1, it->first.server);
1064   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1065   ASSERT_TRUE(it->second.alternative_services.has_value());
1066   ASSERT_EQ(1u, it->second.alternative_services->size());
1067   EXPECT_EQ(alternative_service1,
1068             it->second.alternative_services.value()[0].alternative_service());
1069 }
1070 
TEST_F(AlternateProtocolServerPropertiesTest,SetBroken)1071 TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
1072   url::SchemeHostPort test_server("http", "foo", 80);
1073   const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1074   SetAlternativeService(test_server, alternative_service1);
1075   AlternativeServiceInfoVector alternative_service_info_vector =
1076       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1077   ASSERT_EQ(1u, alternative_service_info_vector.size());
1078   EXPECT_EQ(alternative_service1,
1079             alternative_service_info_vector[0].alternative_service());
1080   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
1081                                                 NetworkAnonymizationKey()));
1082 
1083   // GetAlternativeServiceInfos should return the broken alternative service.
1084   impl_.MarkAlternativeServiceBroken(alternative_service1,
1085                                      NetworkAnonymizationKey());
1086   alternative_service_info_vector =
1087       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1088   ASSERT_EQ(1u, alternative_service_info_vector.size());
1089   EXPECT_EQ(alternative_service1,
1090             alternative_service_info_vector[0].alternative_service());
1091   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1092                                                NetworkAnonymizationKey()));
1093 
1094   // SetAlternativeServices should add a broken alternative service to the map.
1095   AlternativeServiceInfoVector alternative_service_info_vector2;
1096   base::Time expiration = test_clock_.Now() + base::Days(1);
1097   alternative_service_info_vector2.push_back(
1098       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1099           alternative_service1, expiration));
1100   const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
1101   alternative_service_info_vector2.push_back(
1102       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1103           alternative_service2, expiration));
1104   impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1105                                alternative_service_info_vector2);
1106   alternative_service_info_vector =
1107       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1108   ASSERT_EQ(2u, alternative_service_info_vector.size());
1109   EXPECT_EQ(alternative_service1,
1110             alternative_service_info_vector[0].alternative_service());
1111   EXPECT_EQ(alternative_service2,
1112             alternative_service_info_vector[1].alternative_service());
1113   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1114                                                NetworkAnonymizationKey()));
1115   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
1116                                                 NetworkAnonymizationKey()));
1117 
1118   // SetAlternativeService should add a broken alternative service to the map.
1119   SetAlternativeService(test_server, alternative_service1);
1120   alternative_service_info_vector =
1121       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1122   ASSERT_EQ(1u, alternative_service_info_vector.size());
1123   EXPECT_EQ(alternative_service1,
1124             alternative_service_info_vector[0].alternative_service());
1125   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1126                                                NetworkAnonymizationKey()));
1127 }
1128 
TEST_F(AlternateProtocolServerPropertiesTest,SetBrokenUntilDefaultNetworkChanges)1129 TEST_F(AlternateProtocolServerPropertiesTest,
1130        SetBrokenUntilDefaultNetworkChanges) {
1131   url::SchemeHostPort test_server("http", "foo", 80);
1132   const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1133   SetAlternativeService(test_server, alternative_service1);
1134   AlternativeServiceInfoVector alternative_service_info_vector =
1135       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1136   ASSERT_EQ(1u, alternative_service_info_vector.size());
1137   EXPECT_EQ(alternative_service1,
1138             alternative_service_info_vector[0].alternative_service());
1139   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
1140                                                 NetworkAnonymizationKey()));
1141 
1142   // Mark the alternative service as broken until the default network changes.
1143   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1144       alternative_service1, NetworkAnonymizationKey());
1145   // The alternative service should be persisted and marked as broken.
1146   alternative_service_info_vector =
1147       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1148   ASSERT_EQ(1u, alternative_service_info_vector.size());
1149   EXPECT_EQ(alternative_service1,
1150             alternative_service_info_vector[0].alternative_service());
1151   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1152                                                NetworkAnonymizationKey()));
1153 
1154   // SetAlternativeServices should add a broken alternative service to the map.
1155   AlternativeServiceInfoVector alternative_service_info_vector2;
1156   base::Time expiration = test_clock_.Now() + base::Days(1);
1157   alternative_service_info_vector2.push_back(
1158       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1159           alternative_service1, expiration));
1160   const AlternativeService alternative_service2(kProtoHTTP2, "foo", 1234);
1161   alternative_service_info_vector2.push_back(
1162       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1163           alternative_service2, expiration));
1164   impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1165                                alternative_service_info_vector2);
1166   alternative_service_info_vector =
1167       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1168   ASSERT_EQ(2u, alternative_service_info_vector.size());
1169   EXPECT_EQ(alternative_service1,
1170             alternative_service_info_vector[0].alternative_service());
1171   EXPECT_EQ(alternative_service2,
1172             alternative_service_info_vector[1].alternative_service());
1173   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1174                                                NetworkAnonymizationKey()));
1175   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
1176                                                 NetworkAnonymizationKey()));
1177 
1178   // SetAlternativeService should add a broken alternative service to the map.
1179   SetAlternativeService(test_server, alternative_service1);
1180   alternative_service_info_vector =
1181       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1182   ASSERT_EQ(1u, alternative_service_info_vector.size());
1183   EXPECT_EQ(alternative_service1,
1184             alternative_service_info_vector[0].alternative_service());
1185   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
1186                                                NetworkAnonymizationKey()));
1187 }
1188 
TEST_F(AlternateProtocolServerPropertiesTest,MaxAge)1189 TEST_F(AlternateProtocolServerPropertiesTest, MaxAge) {
1190   AlternativeServiceInfoVector alternative_service_info_vector;
1191   base::Time now = test_clock_.Now();
1192   base::TimeDelta one_day = base::Days(1);
1193 
1194   // First alternative service expired one day ago, should not be returned by
1195   // GetAlternativeServiceInfos().
1196   const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1197   alternative_service_info_vector.push_back(
1198       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1199           alternative_service1, now - one_day));
1200 
1201   // Second alterrnative service will expire one day from now, should be
1202   // returned by GetAlternativeSerices().
1203   const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1204   alternative_service_info_vector.push_back(
1205       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1206           alternative_service2, now + one_day));
1207 
1208   url::SchemeHostPort test_server("http", "foo", 80);
1209   impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1210                                alternative_service_info_vector);
1211 
1212   AlternativeServiceInfoVector alternative_service_info_vector2 =
1213       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1214   ASSERT_EQ(1u, alternative_service_info_vector2.size());
1215   EXPECT_EQ(alternative_service2,
1216             alternative_service_info_vector2[0].alternative_service());
1217 }
1218 
TEST_F(AlternateProtocolServerPropertiesTest,MaxAgeCanonical)1219 TEST_F(AlternateProtocolServerPropertiesTest, MaxAgeCanonical) {
1220   AlternativeServiceInfoVector alternative_service_info_vector;
1221   base::Time now = test_clock_.Now();
1222   base::TimeDelta one_day = base::Days(1);
1223 
1224   // First alternative service expired one day ago, should not be returned by
1225   // GetAlternativeServiceInfos().
1226   const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1227   alternative_service_info_vector.push_back(
1228       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1229           alternative_service1, now - one_day));
1230 
1231   // Second alterrnative service will expire one day from now, should be
1232   // returned by GetAlternativeSerices().
1233   const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1234   alternative_service_info_vector.push_back(
1235       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1236           alternative_service2, now + one_day));
1237 
1238   url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1239   impl_.SetAlternativeServices(canonical_server, NetworkAnonymizationKey(),
1240                                alternative_service_info_vector);
1241 
1242   url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1243   AlternativeServiceInfoVector alternative_service_info_vector2 =
1244       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1245   ASSERT_EQ(1u, alternative_service_info_vector2.size());
1246   EXPECT_EQ(alternative_service2,
1247             alternative_service_info_vector2[0].alternative_service());
1248 }
1249 
TEST_F(AlternateProtocolServerPropertiesTest,AlternativeServiceWithScheme)1250 TEST_F(AlternateProtocolServerPropertiesTest, AlternativeServiceWithScheme) {
1251   AlternativeServiceInfoVector alternative_service_info_vector;
1252   const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1253   base::Time expiration = test_clock_.Now() + base::Days(1);
1254   alternative_service_info_vector.push_back(
1255       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1256           alternative_service1, expiration));
1257   const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1258   alternative_service_info_vector.push_back(
1259       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1260           alternative_service2, expiration));
1261   // Set Alt-Svc list for |http_server|.
1262   url::SchemeHostPort http_server("http", "foo", 80);
1263   impl_.SetAlternativeServices(http_server, NetworkAnonymizationKey(),
1264                                alternative_service_info_vector);
1265 
1266   const net::HttpServerProperties::ServerInfoMap& map =
1267       impl_.server_info_map_for_testing();
1268   auto it = map.begin();
1269   EXPECT_EQ(http_server, it->first.server);
1270   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1271   ASSERT_TRUE(it->second.alternative_services.has_value());
1272   ASSERT_EQ(2u, it->second.alternative_services->size());
1273   EXPECT_EQ(alternative_service1,
1274             it->second.alternative_services.value()[0].alternative_service());
1275   EXPECT_EQ(alternative_service2,
1276             it->second.alternative_services.value()[1].alternative_service());
1277 
1278   // Check Alt-Svc list should not be set for |https_server|.
1279   url::SchemeHostPort https_server("https", "foo", 80);
1280   EXPECT_EQ(
1281       0u,
1282       impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
1283           .size());
1284 
1285   // Set Alt-Svc list for |https_server|.
1286   impl_.SetAlternativeServices(https_server, NetworkAnonymizationKey(),
1287                                alternative_service_info_vector);
1288   EXPECT_EQ(
1289       2u,
1290       impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
1291           .size());
1292   EXPECT_EQ(
1293       2u,
1294       impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
1295           .size());
1296 
1297   // Clear Alt-Svc list for |http_server|.
1298   impl_.SetAlternativeServices(http_server, NetworkAnonymizationKey(),
1299                                AlternativeServiceInfoVector());
1300 
1301   EXPECT_EQ(
1302       0u,
1303       impl_.GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
1304           .size());
1305   EXPECT_EQ(
1306       2u,
1307       impl_.GetAlternativeServiceInfos(https_server, NetworkAnonymizationKey())
1308           .size());
1309 }
1310 
TEST_F(AlternateProtocolServerPropertiesTest,ClearAlternativeServices)1311 TEST_F(AlternateProtocolServerPropertiesTest, ClearAlternativeServices) {
1312   AlternativeServiceInfoVector alternative_service_info_vector;
1313   const AlternativeService alternative_service1(kProtoHTTP2, "foo", 443);
1314   base::Time expiration = test_clock_.Now() + base::Days(1);
1315   alternative_service_info_vector.push_back(
1316       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1317           alternative_service1, expiration));
1318   const AlternativeService alternative_service2(kProtoHTTP2, "bar", 1234);
1319   alternative_service_info_vector.push_back(
1320       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1321           alternative_service2, expiration));
1322   url::SchemeHostPort test_server("http", "foo", 80);
1323   impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1324                                alternative_service_info_vector);
1325 
1326   const net::HttpServerProperties::ServerInfoMap& map =
1327       impl_.server_info_map_for_testing();
1328   auto it = map.begin();
1329   EXPECT_EQ(test_server, it->first.server);
1330   EXPECT_TRUE(it->first.network_anonymization_key.IsEmpty());
1331   ASSERT_TRUE(it->second.alternative_services.has_value());
1332   ASSERT_EQ(2u, it->second.alternative_services->size());
1333   EXPECT_EQ(alternative_service1,
1334             it->second.alternative_services.value()[0].alternative_service());
1335   EXPECT_EQ(alternative_service2,
1336             it->second.alternative_services.value()[1].alternative_service());
1337 
1338   impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1339                                AlternativeServiceInfoVector());
1340   EXPECT_TRUE(map.empty());
1341 }
1342 
1343 // A broken alternative service in the mapping carries meaningful information,
1344 // therefore it should not be ignored by SetAlternativeService().  In
1345 // particular, an alternative service mapped to an origin shadows alternative
1346 // services of canonical hosts.
TEST_F(AlternateProtocolServerPropertiesTest,BrokenShadowsCanonical)1347 TEST_F(AlternateProtocolServerPropertiesTest, BrokenShadowsCanonical) {
1348   url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1349   url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1350   AlternativeService canonical_alternative_service(kProtoQUIC,
1351                                                    "bar.c.youtube.com", 1234);
1352   SetAlternativeService(canonical_server, canonical_alternative_service);
1353   AlternativeServiceInfoVector alternative_service_info_vector =
1354       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1355   ASSERT_EQ(1u, alternative_service_info_vector.size());
1356   EXPECT_EQ(canonical_alternative_service,
1357             alternative_service_info_vector[0].alternative_service());
1358 
1359   const AlternativeService broken_alternative_service(kProtoHTTP2, "foo", 443);
1360   impl_.MarkAlternativeServiceBroken(broken_alternative_service,
1361                                      NetworkAnonymizationKey());
1362   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
1363                                                NetworkAnonymizationKey()));
1364 
1365   SetAlternativeService(test_server, broken_alternative_service);
1366   alternative_service_info_vector =
1367       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1368   ASSERT_EQ(1u, alternative_service_info_vector.size());
1369   EXPECT_EQ(broken_alternative_service,
1370             alternative_service_info_vector[0].alternative_service());
1371   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service,
1372                                                NetworkAnonymizationKey()));
1373 }
1374 
TEST_F(AlternateProtocolServerPropertiesTest,ClearBroken)1375 TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) {
1376   url::SchemeHostPort test_server("http", "foo", 80);
1377   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1378   SetAlternativeService(test_server, alternative_service);
1379   impl_.MarkAlternativeServiceBroken(alternative_service,
1380                                      NetworkAnonymizationKey());
1381   ASSERT_TRUE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
1382   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1383                                                NetworkAnonymizationKey()));
1384   // SetAlternativeServices should leave a broken alternative service marked
1385   // as such.
1386   impl_.SetAlternativeServices(test_server, NetworkAnonymizationKey(),
1387                                AlternativeServiceInfoVector());
1388   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1389                                                NetworkAnonymizationKey()));
1390 }
1391 
TEST_F(AlternateProtocolServerPropertiesTest,MarkBrokenWithNetworkIsolationKey)1392 TEST_F(AlternateProtocolServerPropertiesTest,
1393        MarkBrokenWithNetworkIsolationKey) {
1394   url::SchemeHostPort server("http", "foo", 80);
1395   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1396   const base::Time expiration = test_clock_.Now() + base::Days(1);
1397 
1398   // Without NetworkIsolationKeys enabled, the NetworkAnonymizationKey parameter
1399   // should be ignored.
1400   impl_.SetHttp2AlternativeService(server, network_anonymization_key1_,
1401                                    alternative_service, expiration);
1402   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1403                                                 network_anonymization_key1_));
1404   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1405       alternative_service, network_anonymization_key1_));
1406   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1407                                                 network_anonymization_key2_));
1408   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1409       alternative_service, network_anonymization_key2_));
1410 
1411   impl_.MarkAlternativeServiceBroken(alternative_service,
1412                                      network_anonymization_key1_);
1413   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1414                                                network_anonymization_key1_));
1415   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1416       alternative_service, network_anonymization_key1_));
1417   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1418                                                network_anonymization_key2_));
1419   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1420       alternative_service, network_anonymization_key2_));
1421 
1422   impl_.ConfirmAlternativeService(alternative_service,
1423                                   network_anonymization_key2_);
1424   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1425                                                 network_anonymization_key1_));
1426   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1427       alternative_service, network_anonymization_key1_));
1428   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1429                                                 network_anonymization_key2_));
1430   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1431       alternative_service, network_anonymization_key2_));
1432 
1433   base::test::ScopedFeatureList feature_list;
1434   feature_list.InitAndEnableFeature(
1435       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1436   // Since HttpServerProperties caches the feature value, have to create a new
1437   // one.
1438   HttpServerProperties properties(nullptr /* pref_delegate */,
1439                                   nullptr /* net_log */, test_tick_clock_,
1440                                   &test_clock_);
1441 
1442   properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1443                                         alternative_service, expiration);
1444   properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1445                                         alternative_service, expiration);
1446 
1447   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1448       alternative_service, network_anonymization_key1_));
1449   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1450       alternative_service, network_anonymization_key1_));
1451   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1452       alternative_service, network_anonymization_key2_));
1453   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1454       alternative_service, network_anonymization_key2_));
1455 
1456   properties.MarkAlternativeServiceBroken(alternative_service,
1457                                           network_anonymization_key1_);
1458   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1459       alternative_service, network_anonymization_key1_));
1460   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1461       alternative_service, network_anonymization_key1_));
1462   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1463       alternative_service, network_anonymization_key2_));
1464   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1465       alternative_service, network_anonymization_key2_));
1466 
1467   properties.MarkAlternativeServiceBroken(alternative_service,
1468                                           network_anonymization_key2_);
1469   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1470       alternative_service, network_anonymization_key1_));
1471   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1472       alternative_service, network_anonymization_key1_));
1473   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1474       alternative_service, network_anonymization_key2_));
1475   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1476       alternative_service, network_anonymization_key2_));
1477 
1478   properties.ConfirmAlternativeService(alternative_service,
1479                                        network_anonymization_key1_);
1480   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1481       alternative_service, network_anonymization_key1_));
1482   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1483       alternative_service, network_anonymization_key1_));
1484   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1485       alternative_service, network_anonymization_key2_));
1486   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1487       alternative_service, network_anonymization_key2_));
1488 
1489   properties.ConfirmAlternativeService(alternative_service,
1490                                        network_anonymization_key2_);
1491   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1492       alternative_service, network_anonymization_key1_));
1493   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1494       alternative_service, network_anonymization_key1_));
1495   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1496       alternative_service, network_anonymization_key2_));
1497   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1498       alternative_service, network_anonymization_key2_));
1499 }
1500 
TEST_F(AlternateProtocolServerPropertiesTest,MarkRecentlyBroken)1501 TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) {
1502   url::SchemeHostPort server("http", "foo", 80);
1503   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1504   SetAlternativeService(server, alternative_service);
1505 
1506   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1507                                                 NetworkAnonymizationKey()));
1508   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1509       alternative_service, NetworkAnonymizationKey()));
1510 
1511   impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
1512                                              NetworkAnonymizationKey());
1513   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1514                                                 NetworkAnonymizationKey()));
1515   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1516       alternative_service, NetworkAnonymizationKey()));
1517 
1518   impl_.ConfirmAlternativeService(alternative_service,
1519                                   NetworkAnonymizationKey());
1520   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1521                                                 NetworkAnonymizationKey()));
1522   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1523       alternative_service, NetworkAnonymizationKey()));
1524 }
1525 
TEST_F(AlternateProtocolServerPropertiesTest,MarkRecentlyBrokenWithNetworkIsolationKey)1526 TEST_F(AlternateProtocolServerPropertiesTest,
1527        MarkRecentlyBrokenWithNetworkIsolationKey) {
1528   url::SchemeHostPort server("http", "foo", 80);
1529   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1530   const base::Time expiration = test_clock_.Now() + base::Days(1);
1531 
1532   // Without NetworkIsolationKeys enabled, the NetworkAnonymizationKey parameter
1533   // should be ignored.
1534   impl_.SetHttp2AlternativeService(server, network_anonymization_key1_,
1535                                    alternative_service, expiration);
1536   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1537                                                 network_anonymization_key1_));
1538   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1539       alternative_service, network_anonymization_key1_));
1540   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1541                                                 network_anonymization_key2_));
1542   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1543       alternative_service, network_anonymization_key2_));
1544 
1545   impl_.MarkAlternativeServiceRecentlyBroken(alternative_service,
1546                                              network_anonymization_key1_);
1547   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1548                                                 network_anonymization_key1_));
1549   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1550       alternative_service, network_anonymization_key1_));
1551   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1552                                                 network_anonymization_key2_));
1553   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1554       alternative_service, network_anonymization_key2_));
1555 
1556   impl_.ConfirmAlternativeService(alternative_service,
1557                                   network_anonymization_key2_);
1558   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1559                                                 network_anonymization_key1_));
1560   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1561       alternative_service, network_anonymization_key1_));
1562   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1563                                                 network_anonymization_key2_));
1564   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1565       alternative_service, network_anonymization_key2_));
1566 
1567   base::test::ScopedFeatureList feature_list;
1568   feature_list.InitAndEnableFeature(
1569       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1570   // Since HttpServerProperties caches the feature value, have to create a new
1571   // one.
1572   HttpServerProperties properties(nullptr /* pref_delegate */,
1573                                   nullptr /* net_log */, test_tick_clock_,
1574                                   &test_clock_);
1575 
1576   properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1577                                         alternative_service, expiration);
1578   properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1579                                         alternative_service, expiration);
1580   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1581       alternative_service, network_anonymization_key1_));
1582   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1583       alternative_service, network_anonymization_key1_));
1584   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1585       alternative_service, network_anonymization_key2_));
1586   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1587       alternative_service, network_anonymization_key2_));
1588 
1589   properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
1590                                                   network_anonymization_key1_);
1591   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1592       alternative_service, network_anonymization_key1_));
1593   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1594       alternative_service, network_anonymization_key1_));
1595   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1596       alternative_service, network_anonymization_key2_));
1597   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1598       alternative_service, network_anonymization_key2_));
1599 
1600   properties.MarkAlternativeServiceRecentlyBroken(alternative_service,
1601                                                   network_anonymization_key2_);
1602   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1603       alternative_service, network_anonymization_key1_));
1604   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1605       alternative_service, network_anonymization_key1_));
1606   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1607       alternative_service, network_anonymization_key2_));
1608   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1609       alternative_service, network_anonymization_key2_));
1610 
1611   properties.ConfirmAlternativeService(alternative_service,
1612                                        network_anonymization_key1_);
1613   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1614       alternative_service, network_anonymization_key1_));
1615   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1616       alternative_service, network_anonymization_key1_));
1617   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1618       alternative_service, network_anonymization_key2_));
1619   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1620       alternative_service, network_anonymization_key2_));
1621 
1622   properties.ConfirmAlternativeService(alternative_service,
1623                                        network_anonymization_key2_);
1624   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1625       alternative_service, network_anonymization_key1_));
1626   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1627       alternative_service, network_anonymization_key1_));
1628   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1629       alternative_service, network_anonymization_key2_));
1630   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1631       alternative_service, network_anonymization_key2_));
1632 }
1633 
TEST_F(AlternateProtocolServerPropertiesTest,MarkBrokenUntilDefaultNetworkChanges)1634 TEST_F(AlternateProtocolServerPropertiesTest,
1635        MarkBrokenUntilDefaultNetworkChanges) {
1636   url::SchemeHostPort server("http", "foo", 80);
1637   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1638   SetAlternativeService(server, alternative_service);
1639 
1640   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1641                                                 NetworkAnonymizationKey()));
1642   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1643       alternative_service, NetworkAnonymizationKey()));
1644 
1645   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1646       alternative_service, NetworkAnonymizationKey());
1647   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1648                                                NetworkAnonymizationKey()));
1649   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1650       alternative_service, NetworkAnonymizationKey()));
1651 
1652   impl_.ConfirmAlternativeService(alternative_service,
1653                                   NetworkAnonymizationKey());
1654   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1655                                                 NetworkAnonymizationKey()));
1656   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1657       alternative_service, NetworkAnonymizationKey()));
1658 }
1659 
TEST_F(AlternateProtocolServerPropertiesTest,MarkBrokenUntilDefaultNetworkChangesWithNetworkIsolationKey)1660 TEST_F(AlternateProtocolServerPropertiesTest,
1661        MarkBrokenUntilDefaultNetworkChangesWithNetworkIsolationKey) {
1662   url::SchemeHostPort server("http", "foo", 80);
1663   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1664   const base::Time expiration = test_clock_.Now() + base::Days(1);
1665 
1666   // Without NetworkIsolationKeys enabled, the NetworkAnonymizationKey parameter
1667   // should be ignored.
1668   impl_.SetHttp2AlternativeService(server, network_anonymization_key1_,
1669                                    alternative_service, expiration);
1670 
1671   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1672                                                 network_anonymization_key1_));
1673   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1674       alternative_service, network_anonymization_key1_));
1675   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1676                                                 network_anonymization_key2_));
1677   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1678       alternative_service, network_anonymization_key2_));
1679 
1680   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1681       alternative_service, network_anonymization_key1_);
1682   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1683                                                network_anonymization_key1_));
1684   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1685       alternative_service, network_anonymization_key1_));
1686   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1687                                                network_anonymization_key2_));
1688   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1689       alternative_service, network_anonymization_key2_));
1690 
1691   impl_.ConfirmAlternativeService(alternative_service,
1692                                   network_anonymization_key2_);
1693   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1694                                                 network_anonymization_key1_));
1695   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1696       alternative_service, network_anonymization_key1_));
1697   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1698                                                 network_anonymization_key2_));
1699   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1700       alternative_service, network_anonymization_key2_));
1701 
1702   base::test::ScopedFeatureList feature_list;
1703   feature_list.InitAndEnableFeature(
1704       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1705   // Since HttpServerProperties caches the feature value, have to create a new
1706   // one.
1707   HttpServerProperties properties(nullptr /* pref_delegate */,
1708                                   nullptr /* net_log */, test_tick_clock_,
1709                                   &test_clock_);
1710 
1711   properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1712                                         alternative_service, expiration);
1713   properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1714                                         alternative_service, expiration);
1715 
1716   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1717       alternative_service, network_anonymization_key1_));
1718   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1719       alternative_service, network_anonymization_key1_));
1720   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1721       alternative_service, network_anonymization_key2_));
1722   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1723       alternative_service, network_anonymization_key2_));
1724 
1725   properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1726       alternative_service, network_anonymization_key1_);
1727   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1728       alternative_service, network_anonymization_key1_));
1729   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1730       alternative_service, network_anonymization_key1_));
1731   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1732       alternative_service, network_anonymization_key2_));
1733   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1734       alternative_service, network_anonymization_key2_));
1735 
1736   properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1737       alternative_service, network_anonymization_key2_);
1738   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1739       alternative_service, network_anonymization_key1_));
1740   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1741       alternative_service, network_anonymization_key1_));
1742   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1743       alternative_service, network_anonymization_key2_));
1744   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1745       alternative_service, network_anonymization_key2_));
1746 
1747   properties.ConfirmAlternativeService(alternative_service,
1748                                        network_anonymization_key1_);
1749   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1750       alternative_service, network_anonymization_key1_));
1751   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1752       alternative_service, network_anonymization_key1_));
1753   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1754       alternative_service, network_anonymization_key2_));
1755   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1756       alternative_service, network_anonymization_key2_));
1757 
1758   properties.ConfirmAlternativeService(alternative_service,
1759                                        network_anonymization_key2_);
1760   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1761       alternative_service, network_anonymization_key1_));
1762   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1763       alternative_service, network_anonymization_key1_));
1764   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1765       alternative_service, network_anonymization_key2_));
1766   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1767       alternative_service, network_anonymization_key2_));
1768 }
1769 
TEST_F(AlternateProtocolServerPropertiesTest,OnDefaultNetworkChanged)1770 TEST_F(AlternateProtocolServerPropertiesTest, OnDefaultNetworkChanged) {
1771   url::SchemeHostPort server("http", "foo", 80);
1772   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1773 
1774   SetAlternativeService(server, alternative_service);
1775   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1776                                                 NetworkAnonymizationKey()));
1777   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1778       alternative_service, NetworkAnonymizationKey()));
1779 
1780   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1781       alternative_service, NetworkAnonymizationKey());
1782   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1783                                                NetworkAnonymizationKey()));
1784   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1785       alternative_service, NetworkAnonymizationKey()));
1786 
1787   // Default network change clears alt svc broken until default network changes.
1788   impl_.OnDefaultNetworkChanged();
1789   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1790                                                 NetworkAnonymizationKey()));
1791   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1792       alternative_service, NetworkAnonymizationKey()));
1793 
1794   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1795       alternative_service, NetworkAnonymizationKey());
1796   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1797                                                NetworkAnonymizationKey()));
1798   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1799       alternative_service, NetworkAnonymizationKey()));
1800 
1801   impl_.MarkAlternativeServiceBroken(alternative_service,
1802                                      NetworkAnonymizationKey());
1803   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1804                                                NetworkAnonymizationKey()));
1805   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1806       alternative_service, NetworkAnonymizationKey()));
1807 
1808   // Default network change doesn't affect alt svc that was simply marked broken
1809   // most recently.
1810   impl_.OnDefaultNetworkChanged();
1811   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1812                                                NetworkAnonymizationKey()));
1813   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1814       alternative_service, NetworkAnonymizationKey()));
1815 
1816   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1817       alternative_service, NetworkAnonymizationKey());
1818   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
1819                                                NetworkAnonymizationKey()));
1820   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
1821       alternative_service, NetworkAnonymizationKey()));
1822 
1823   // Default network change clears alt svc that was marked broken until default
1824   // network change most recently even if the alt svc was initially marked
1825   // broken.
1826   impl_.OnDefaultNetworkChanged();
1827   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
1828                                                 NetworkAnonymizationKey()));
1829   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
1830       alternative_service, NetworkAnonymizationKey()));
1831 }
1832 
TEST_F(AlternateProtocolServerPropertiesTest,OnDefaultNetworkChangedWithNetworkIsolationKey)1833 TEST_F(AlternateProtocolServerPropertiesTest,
1834        OnDefaultNetworkChangedWithNetworkIsolationKey) {
1835   url::SchemeHostPort server("http", "foo", 80);
1836   const AlternativeService alternative_service(kProtoHTTP2, "foo", 443);
1837 
1838   base::test::ScopedFeatureList feature_list;
1839   feature_list.InitAndEnableFeature(
1840       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1841   // Since HttpServerProperties caches the feature value, have to create a new
1842   // one.
1843   HttpServerProperties properties(nullptr /* pref_delegate */,
1844                                   nullptr /* net_log */, test_tick_clock_,
1845                                   &test_clock_);
1846 
1847   const base::Time expiration = test_clock_.Now() + base::Days(1);
1848   properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
1849                                         alternative_service, expiration);
1850   properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
1851                                         alternative_service, expiration);
1852 
1853   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1854       alternative_service, network_anonymization_key1_));
1855   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1856       alternative_service, network_anonymization_key1_));
1857   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1858       alternative_service, network_anonymization_key2_));
1859   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1860       alternative_service, network_anonymization_key2_));
1861 
1862   properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1863       alternative_service, network_anonymization_key1_);
1864   properties.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
1865       alternative_service, network_anonymization_key2_);
1866   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1867       alternative_service, network_anonymization_key1_));
1868   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1869       alternative_service, network_anonymization_key1_));
1870   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
1871       alternative_service, network_anonymization_key2_));
1872   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
1873       alternative_service, network_anonymization_key2_));
1874 
1875   // Default network change clears alt svc broken until default network changes.
1876   properties.OnDefaultNetworkChanged();
1877   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1878       alternative_service, network_anonymization_key1_));
1879   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1880       alternative_service, network_anonymization_key1_));
1881   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
1882       alternative_service, network_anonymization_key2_));
1883   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
1884       alternative_service, network_anonymization_key2_));
1885 }
1886 
TEST_F(AlternateProtocolServerPropertiesTest,Canonical)1887 TEST_F(AlternateProtocolServerPropertiesTest, Canonical) {
1888   url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1889   EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
1890 
1891   url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1892   EXPECT_FALSE(
1893       HasAlternativeService(canonical_server, NetworkAnonymizationKey()));
1894 
1895   AlternativeServiceInfoVector alternative_service_info_vector;
1896   const AlternativeService canonical_alternative_service1(
1897       kProtoQUIC, "bar.c.youtube.com", 1234);
1898   base::Time expiration = test_clock_.Now() + base::Days(1);
1899   alternative_service_info_vector.push_back(
1900       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
1901           canonical_alternative_service1, expiration,
1902           DefaultSupportedQuicVersions()));
1903   const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
1904   alternative_service_info_vector.push_back(
1905       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1906           canonical_alternative_service2, expiration));
1907   impl_.SetAlternativeServices(canonical_server, NetworkAnonymizationKey(),
1908                                alternative_service_info_vector);
1909 
1910   // Since |test_server| does not have an alternative service itself,
1911   // GetAlternativeServiceInfos should return those of |canonical_server|.
1912   AlternativeServiceInfoVector alternative_service_info_vector2 =
1913       impl_.GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey());
1914   ASSERT_EQ(2u, alternative_service_info_vector2.size());
1915   EXPECT_EQ(canonical_alternative_service1,
1916             alternative_service_info_vector2[0].alternative_service());
1917 
1918   // Since |canonical_alternative_service2| has an empty host,
1919   // GetAlternativeServiceInfos should substitute the hostname of its |origin|
1920   // argument.
1921   EXPECT_EQ(test_server.host(),
1922             alternative_service_info_vector2[1].alternative_service().host);
1923   EXPECT_EQ(canonical_alternative_service2.protocol,
1924             alternative_service_info_vector2[1].alternative_service().protocol);
1925   EXPECT_EQ(canonical_alternative_service2.port,
1926             alternative_service_info_vector2[1].alternative_service().port);
1927 
1928   // Verify the canonical suffix.
1929   EXPECT_EQ(".c.youtube.com",
1930             *impl_.GetCanonicalSuffixForTesting(test_server.host()));
1931   EXPECT_EQ(".c.youtube.com",
1932             *impl_.GetCanonicalSuffixForTesting(canonical_server.host()));
1933 }
1934 
TEST_F(AlternateProtocolServerPropertiesTest,ClearCanonical)1935 TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) {
1936   url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1937   url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
1938   AlternativeService canonical_alternative_service(kProtoQUIC,
1939                                                    "bar.c.youtube.com", 1234);
1940 
1941   SetAlternativeService(canonical_server, canonical_alternative_service);
1942   impl_.SetAlternativeServices(canonical_server, NetworkAnonymizationKey(),
1943                                AlternativeServiceInfoVector());
1944   EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
1945 }
1946 
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalWithNetworkIsolationKey)1947 TEST_F(AlternateProtocolServerPropertiesTest,
1948        CanonicalWithNetworkIsolationKey) {
1949   base::test::ScopedFeatureList feature_list;
1950   feature_list.InitAndEnableFeature(
1951       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1952   // Since HttpServerProperties caches the feature value, have to create a new
1953   // one.
1954   HttpServerProperties properties(nullptr /* pref_delegate */,
1955                                   nullptr /* net_log */, test_tick_clock_,
1956                                   &test_clock_);
1957 
1958   url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
1959   EXPECT_FALSE(HasAlternativeService(test_server, network_anonymization_key1_));
1960 
1961   url::SchemeHostPort canonical_server1("https", "bar.c.youtube.com", 443);
1962   EXPECT_FALSE(
1963       HasAlternativeService(canonical_server1, network_anonymization_key1_));
1964 
1965   AlternativeServiceInfoVector alternative_service_info_vector;
1966   const AlternativeService canonical_alternative_service1(
1967       kProtoQUIC, "bar.c.youtube.com", 1234);
1968   base::Time expiration = test_clock_.Now() + base::Days(1);
1969   alternative_service_info_vector.push_back(
1970       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
1971           canonical_alternative_service1, expiration,
1972           DefaultSupportedQuicVersions()));
1973   const AlternativeService canonical_alternative_service2(kProtoHTTP2, "", 443);
1974   alternative_service_info_vector.push_back(
1975       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
1976           canonical_alternative_service2, expiration));
1977   properties.SetAlternativeServices(canonical_server1,
1978                                     network_anonymization_key1_,
1979                                     alternative_service_info_vector);
1980 
1981   // Since |test_server| does not have an alternative service itself,
1982   // GetAlternativeServiceInfos should return those of |canonical_server|.
1983   AlternativeServiceInfoVector alternative_service_info_vector2 =
1984       properties.GetAlternativeServiceInfos(test_server,
1985                                             network_anonymization_key1_);
1986   ASSERT_EQ(2u, alternative_service_info_vector2.size());
1987   EXPECT_EQ(canonical_alternative_service1,
1988             alternative_service_info_vector2[0].alternative_service());
1989 
1990   // Canonical information should not be visible for other NetworkIsolationKeys.
1991   EXPECT_TRUE(
1992       properties
1993           .GetAlternativeServiceInfos(test_server, network_anonymization_key2_)
1994           .empty());
1995   EXPECT_TRUE(
1996       properties
1997           .GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
1998           .empty());
1999 
2000   // Now add an alternative service entry for network_anonymization_key2_ for a
2001   // different server and different NetworkAnonymizationKey, but with the same
2002   // canonical suffix.
2003   url::SchemeHostPort canonical_server2("https", "shrimp.c.youtube.com", 443);
2004   properties.SetAlternativeServices(canonical_server2,
2005                                     network_anonymization_key2_,
2006                                     {alternative_service_info_vector[0]});
2007 
2008   // The canonical server information should reachable, and different, for both
2009   // NetworkIsolationKeys.
2010   EXPECT_EQ(1u, properties
2011                     .GetAlternativeServiceInfos(test_server,
2012                                                 network_anonymization_key2_)
2013                     .size());
2014   EXPECT_EQ(2u, properties
2015                     .GetAlternativeServiceInfos(test_server,
2016                                                 network_anonymization_key1_)
2017                     .size());
2018   EXPECT_TRUE(
2019       properties
2020           .GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
2021           .empty());
2022 
2023   // Clearing the alternate service state of network_anonymization_key1_'s
2024   // canonical server should only affect network_anonymization_key1_.
2025   properties.SetAlternativeServices(canonical_server1,
2026                                     network_anonymization_key1_, {});
2027   EXPECT_EQ(1u, properties
2028                     .GetAlternativeServiceInfos(test_server,
2029                                                 network_anonymization_key2_)
2030                     .size());
2031   EXPECT_TRUE(
2032       properties
2033           .GetAlternativeServiceInfos(test_server, network_anonymization_key1_)
2034           .empty());
2035   EXPECT_TRUE(
2036       properties
2037           .GetAlternativeServiceInfos(test_server, NetworkAnonymizationKey())
2038           .empty());
2039 }
2040 
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalBroken)2041 TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken) {
2042   url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
2043   url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
2044   AlternativeService canonical_alternative_service(kProtoQUIC,
2045                                                    "bar.c.youtube.com", 1234);
2046 
2047   SetAlternativeService(canonical_server, canonical_alternative_service);
2048   EXPECT_TRUE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2049   impl_.MarkAlternativeServiceBroken(canonical_alternative_service,
2050                                      NetworkAnonymizationKey());
2051   EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2052 }
2053 
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalBrokenUntilDefaultNetworkChanges)2054 TEST_F(AlternateProtocolServerPropertiesTest,
2055        CanonicalBrokenUntilDefaultNetworkChanges) {
2056   url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
2057   url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
2058   AlternativeService canonical_alternative_service(kProtoQUIC,
2059                                                    "bar.c.youtube.com", 1234);
2060 
2061   SetAlternativeService(canonical_server, canonical_alternative_service);
2062   EXPECT_TRUE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2063   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
2064       canonical_alternative_service, NetworkAnonymizationKey());
2065   EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2066 }
2067 
2068 // Adding an alternative service for a new host overrides canonical host.
TEST_F(AlternateProtocolServerPropertiesTest,CanonicalOverride)2069 TEST_F(AlternateProtocolServerPropertiesTest, CanonicalOverride) {
2070   url::SchemeHostPort foo_server("https", "foo.c.youtube.com", 443);
2071   url::SchemeHostPort bar_server("https", "bar.c.youtube.com", 443);
2072   AlternativeService bar_alternative_service(kProtoQUIC, "bar.c.youtube.com",
2073                                              1234);
2074   SetAlternativeService(bar_server, bar_alternative_service);
2075   AlternativeServiceInfoVector alternative_service_info_vector =
2076       impl_.GetAlternativeServiceInfos(foo_server, NetworkAnonymizationKey());
2077   ASSERT_EQ(1u, alternative_service_info_vector.size());
2078   EXPECT_EQ(bar_alternative_service,
2079             alternative_service_info_vector[0].alternative_service());
2080 
2081   url::SchemeHostPort qux_server("https", "qux.c.youtube.com", 443);
2082   AlternativeService qux_alternative_service(kProtoQUIC, "qux.c.youtube.com",
2083                                              443);
2084   SetAlternativeService(qux_server, qux_alternative_service);
2085   alternative_service_info_vector =
2086       impl_.GetAlternativeServiceInfos(foo_server, NetworkAnonymizationKey());
2087   ASSERT_EQ(1u, alternative_service_info_vector.size());
2088   EXPECT_EQ(qux_alternative_service,
2089             alternative_service_info_vector[0].alternative_service());
2090 }
2091 
TEST_F(AlternateProtocolServerPropertiesTest,ClearWithCanonical)2092 TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) {
2093   url::SchemeHostPort test_server("https", "foo.c.youtube.com", 443);
2094   url::SchemeHostPort canonical_server("https", "bar.c.youtube.com", 443);
2095   AlternativeService canonical_alternative_service(kProtoQUIC,
2096                                                    "bar.c.youtube.com", 1234);
2097 
2098   SetAlternativeService(canonical_server, canonical_alternative_service);
2099   impl_.Clear(base::OnceClosure());
2100   EXPECT_FALSE(HasAlternativeService(test_server, NetworkAnonymizationKey()));
2101 }
2102 
TEST_F(AlternateProtocolServerPropertiesTest,ExpireBrokenAlternateProtocolMappings)2103 TEST_F(AlternateProtocolServerPropertiesTest,
2104        ExpireBrokenAlternateProtocolMappings) {
2105   url::SchemeHostPort server("https", "foo", 443);
2106   AlternativeService alternative_service(kProtoQUIC, "foo", 443);
2107   SetAlternativeService(server, alternative_service);
2108   EXPECT_TRUE(HasAlternativeService(server, NetworkAnonymizationKey()));
2109   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2110                                                 NetworkAnonymizationKey()));
2111   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
2112       alternative_service, NetworkAnonymizationKey()));
2113 
2114   base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2115   HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2116       &impl_, alternative_service, past);
2117   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
2118                                                NetworkAnonymizationKey()));
2119   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
2120       alternative_service, NetworkAnonymizationKey()));
2121 
2122   HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
2123   EXPECT_FALSE(HasAlternativeService(server, NetworkAnonymizationKey()));
2124   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2125                                                 NetworkAnonymizationKey()));
2126   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
2127       alternative_service, NetworkAnonymizationKey()));
2128 }
2129 
TEST_F(AlternateProtocolServerPropertiesTest,ExpireBrokenAlternateProtocolMappingsWithNetworkIsolationKey)2130 TEST_F(AlternateProtocolServerPropertiesTest,
2131        ExpireBrokenAlternateProtocolMappingsWithNetworkIsolationKey) {
2132   url::SchemeHostPort server("https", "foo", 443);
2133   AlternativeService alternative_service(kProtoHTTP2, "foo", 444);
2134   base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2135   base::TimeTicks future = test_tick_clock_->NowTicks() + base::Seconds(42);
2136   const base::Time alt_service_expiration = test_clock_.Now() + base::Days(1);
2137 
2138   base::test::ScopedFeatureList feature_list;
2139   feature_list.InitAndEnableFeature(
2140       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
2141   // Since HttpServerProperties caches the feature value, have to create a new
2142   // one.
2143   HttpServerProperties properties(nullptr /* pref_delegate */,
2144                                   nullptr /* net_log */, test_tick_clock_,
2145                                   &test_clock_);
2146 
2147   properties.SetHttp2AlternativeService(server, network_anonymization_key1_,
2148                                         alternative_service,
2149                                         alt_service_expiration);
2150   properties.SetHttp2AlternativeService(server, network_anonymization_key2_,
2151                                         alternative_service,
2152                                         alt_service_expiration);
2153 
2154   EXPECT_FALSE(
2155       properties.GetAlternativeServiceInfos(server, network_anonymization_key1_)
2156           .empty());
2157   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2158       alternative_service, network_anonymization_key1_));
2159   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
2160       alternative_service, network_anonymization_key1_));
2161   EXPECT_FALSE(
2162       properties.GetAlternativeServiceInfos(server, network_anonymization_key2_)
2163           .empty());
2164   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2165       alternative_service, network_anonymization_key2_));
2166   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
2167       alternative_service, network_anonymization_key2_));
2168 
2169   // Set broken alternative service with expiration date in the past for
2170   // |network_anonymization_key1_|.
2171   HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2172       &properties, alternative_service, past, network_anonymization_key1_);
2173   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2174       alternative_service, network_anonymization_key1_));
2175   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2176       alternative_service, network_anonymization_key1_));
2177   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2178       alternative_service, network_anonymization_key2_));
2179   EXPECT_FALSE(properties.WasAlternativeServiceRecentlyBroken(
2180       alternative_service, network_anonymization_key2_));
2181 
2182   // Set broken alternative service with expiration date in the future for
2183   // |network_anonymization_key1_|.
2184   HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2185       &properties, alternative_service, future, network_anonymization_key2_);
2186   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2187       alternative_service, network_anonymization_key1_));
2188   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2189       alternative_service, network_anonymization_key1_));
2190   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2191       alternative_service, network_anonymization_key2_));
2192   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2193       alternative_service, network_anonymization_key2_));
2194 
2195   // Only the broken entry for |network_anonymization_key1_| should be expired.
2196   HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&properties);
2197   EXPECT_TRUE(
2198       properties.GetAlternativeServiceInfos(server, network_anonymization_key1_)
2199           .empty());
2200   EXPECT_FALSE(properties.IsAlternativeServiceBroken(
2201       alternative_service, network_anonymization_key1_));
2202   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2203       alternative_service, network_anonymization_key1_));
2204   EXPECT_FALSE(
2205       properties.GetAlternativeServiceInfos(server, network_anonymization_key2_)
2206           .empty());
2207   EXPECT_TRUE(properties.IsAlternativeServiceBroken(
2208       alternative_service, network_anonymization_key2_));
2209   EXPECT_TRUE(properties.WasAlternativeServiceRecentlyBroken(
2210       alternative_service, network_anonymization_key2_));
2211 }
2212 
2213 // Regression test for https://crbug.com/505413.
TEST_F(AlternateProtocolServerPropertiesTest,RemoveExpiredBrokenAltSvc)2214 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) {
2215   url::SchemeHostPort foo_server("https", "foo", 443);
2216   AlternativeService bar_alternative_service(kProtoQUIC, "bar", 443);
2217   SetAlternativeService(foo_server, bar_alternative_service);
2218   EXPECT_TRUE(HasAlternativeService(foo_server, NetworkAnonymizationKey()));
2219 
2220   url::SchemeHostPort bar_server1("http", "bar", 80);
2221   AlternativeService nohost_alternative_service(kProtoQUIC, "", 443);
2222   SetAlternativeService(bar_server1, nohost_alternative_service);
2223   EXPECT_TRUE(HasAlternativeService(bar_server1, NetworkAnonymizationKey()));
2224 
2225   url::SchemeHostPort bar_server2("https", "bar", 443);
2226   AlternativeService baz_alternative_service(kProtoQUIC, "baz", 1234);
2227   SetAlternativeService(bar_server2, baz_alternative_service);
2228   EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkAnonymizationKey()));
2229 
2230   // Mark "bar:443" as broken.
2231   base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2232   HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2233       &impl_, bar_alternative_service, past);
2234 
2235   // Expire brokenness of "bar:443".
2236   HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
2237 
2238   // "foo:443" should have no alternative service now.
2239   EXPECT_FALSE(HasAlternativeService(foo_server, NetworkAnonymizationKey()));
2240   // "bar:80" should have no alternative service now.
2241   EXPECT_FALSE(HasAlternativeService(bar_server1, NetworkAnonymizationKey()));
2242   // The alternative service of "bar:443" should be unaffected.
2243   EXPECT_TRUE(HasAlternativeService(bar_server2, NetworkAnonymizationKey()));
2244 
2245   EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(
2246       bar_alternative_service, NetworkAnonymizationKey()));
2247   EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(
2248       baz_alternative_service, NetworkAnonymizationKey()));
2249 }
2250 
TEST_F(AlternateProtocolServerPropertiesTest,SetBrokenAlternativeServicesDelayParams1)2251 TEST_F(AlternateProtocolServerPropertiesTest,
2252        SetBrokenAlternativeServicesDelayParams1) {
2253   url::SchemeHostPort server("https", "foo", 443);
2254   AlternativeService alternative_service(kProtoQUIC, "foo", 443);
2255   SetAlternativeService(server, alternative_service);
2256 
2257   const base::TimeDelta initial_delay = base::Seconds(1);
2258   impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, true);
2259   for (int i = 0; i < 10; ++i) {
2260     impl_.MarkAlternativeServiceBroken(alternative_service,
2261                                        NetworkAnonymizationKey());
2262     // |impl_| should have posted task to expire the brokenness of
2263     // |alternative_service|
2264     EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
2265     EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
2266                                                  NetworkAnonymizationKey()));
2267 
2268     // Advance time by just enough so that |alternative_service|'s brokenness
2269     // expires.
2270     FastForwardBy(initial_delay * (1 << i));
2271 
2272     // Ensure brokenness of |alternative_service| has expired.
2273     EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
2274     EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2275                                                   NetworkAnonymizationKey()));
2276   }
2277 }
2278 
TEST_F(AlternateProtocolServerPropertiesTest,SetBrokenAlternativeServicesDelayParams2)2279 TEST_F(AlternateProtocolServerPropertiesTest,
2280        SetBrokenAlternativeServicesDelayParams2) {
2281   url::SchemeHostPort server("https", "foo", 443);
2282   AlternativeService alternative_service(kProtoQUIC, "foo", 443);
2283   SetAlternativeService(server, alternative_service);
2284 
2285   const base::TimeDelta initial_delay = base::Seconds(5);
2286   impl_.SetBrokenAlternativeServicesDelayParams(initial_delay, false);
2287   for (int i = 0; i < 10; ++i) {
2288     impl_.MarkAlternativeServiceBroken(alternative_service,
2289                                        NetworkAnonymizationKey());
2290     // |impl_| should have posted task to expire the brokenness of
2291     // |alternative_service|
2292     EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
2293     EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service,
2294                                                  NetworkAnonymizationKey()));
2295 
2296     // Advance time by just enough so that |alternative_service|'s brokenness
2297     // expires.
2298     if (i == 0) {
2299       FastForwardBy(initial_delay);
2300     } else {
2301       FastForwardBy(base::Seconds(300) * (1 << (i - 1)));
2302     }
2303 
2304     // Ensure brokenness of |alternative_service| has expired.
2305     EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
2306     EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service,
2307                                                   NetworkAnonymizationKey()));
2308   }
2309 }
2310 
2311 // Regression test for https://crbug.com/724302
TEST_F(AlternateProtocolServerPropertiesTest,RemoveExpiredBrokenAltSvc2)2312 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc2) {
2313   // This test will mark an alternative service A that has already been marked
2314   // broken many times, then immediately mark another alternative service B as
2315   // broken for the first time. Because A's been marked broken many times
2316   // already, its brokenness will be scheduled to expire much further in the
2317   // future than B, even though it was marked broken before B. This test makes
2318   // sure that even though A was marked broken before B, B's brokenness should
2319   // expire before A.
2320 
2321   url::SchemeHostPort server1("https", "foo", 443);
2322   AlternativeService alternative_service1(kProtoQUIC, "foo", 443);
2323   SetAlternativeService(server1, alternative_service1);
2324 
2325   url::SchemeHostPort server2("https", "bar", 443);
2326   AlternativeService alternative_service2(kProtoQUIC, "bar", 443);
2327   SetAlternativeService(server2, alternative_service2);
2328 
2329   // Repeatedly mark alt svc 1 broken and wait for its brokenness to expire.
2330   // This will increase its time until expiration.
2331   for (int i = 0; i < 3; ++i) {
2332     impl_.MarkAlternativeServiceBroken(alternative_service1,
2333                                        NetworkAnonymizationKey());
2334 
2335     // |impl_| should have posted task to expire the brokenness of
2336     // |alternative_service1|
2337     EXPECT_EQ(1u, GetPendingMainThreadTaskCount());
2338     EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
2339                                                  NetworkAnonymizationKey()));
2340 
2341     // Advance time by just enough so that |alternative_service1|'s brokenness
2342     // expires.
2343     FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[i]);
2344 
2345     // Ensure brokenness of |alternative_service1| has expired.
2346     EXPECT_EQ(0u, GetPendingMainThreadTaskCount());
2347     EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
2348                                                   NetworkAnonymizationKey()));
2349   }
2350 
2351   impl_.MarkAlternativeServiceBroken(alternative_service1,
2352                                      NetworkAnonymizationKey());
2353   impl_.MarkAlternativeServiceBroken(alternative_service2,
2354                                      NetworkAnonymizationKey());
2355 
2356   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service2,
2357                                                NetworkAnonymizationKey()));
2358 
2359   // Advance time by just enough so that |alternative_service2|'s brokennness
2360   // expires.
2361   FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
2362 
2363   EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1,
2364                                                NetworkAnonymizationKey()));
2365   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
2366                                                 NetworkAnonymizationKey()));
2367 
2368   // Advance time by enough so that |alternative_service1|'s brokenness expires.
2369   FastForwardBy(BROKEN_ALT_SVC_EXPIRE_DELAYS[3] -
2370                 BROKEN_ALT_SVC_EXPIRE_DELAYS[0]);
2371 
2372   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1,
2373                                                 NetworkAnonymizationKey()));
2374   EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2,
2375                                                 NetworkAnonymizationKey()));
2376 }
2377 
2378 // Regression test for https://crbug.com/994537. Having a ServerInfo entry
2379 // without a populated |alternative_services| value would cause
2380 // OnExpireBrokenAlternativeService() to hang..
TEST_F(AlternateProtocolServerPropertiesTest,RemoveExpiredBrokenAltSvc3)2381 TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc3) {
2382   // Add an altertive service entry.
2383   const url::SchemeHostPort kServer1("https", "foo", 443);
2384   const AlternativeService kAltService(kProtoQUIC, "bar", 443);
2385   SetAlternativeService(kServer1, kAltService);
2386   EXPECT_TRUE(HasAlternativeService(kServer1, NetworkAnonymizationKey()));
2387 
2388   // Add an entry to ServerInfo for another server, without an alternative
2389   // service value.
2390   const url::SchemeHostPort kServer2("http", "bar", 80);
2391   impl_.SetSupportsSpdy(kServer2, NetworkAnonymizationKey(), false);
2392 
2393   // Mark kAltService as broken.
2394   base::TimeTicks past = test_tick_clock_->NowTicks() - base::Seconds(42);
2395   HttpServerPropertiesPeer::AddBrokenAlternativeServiceWithExpirationTime(
2396       &impl_, kAltService, past);
2397 
2398   // Expire brokenness of kAltService. This call should not hang.
2399   HttpServerPropertiesPeer::ExpireBrokenAlternateProtocolMappings(&impl_);
2400 
2401   EXPECT_FALSE(HasAlternativeService(kServer1, NetworkAnonymizationKey()));
2402 }
2403 
TEST_F(AlternateProtocolServerPropertiesTest,GetAlternativeServiceInfoAsValue)2404 TEST_F(AlternateProtocolServerPropertiesTest,
2405        GetAlternativeServiceInfoAsValue) {
2406   constexpr base::Time::Exploded kNowExploded = {.year = 2018,
2407                                                  .month = 1,
2408                                                  .day_of_week = 3,
2409                                                  .day_of_month = 24,
2410                                                  .hour = 15,
2411                                                  .minute = 12,
2412                                                  .second = 53};
2413   base::Time now;
2414   bool result = base::Time::FromLocalExploded(kNowExploded, &now);
2415   DCHECK(result);
2416   test_clock_.SetNow(now);
2417 
2418   AlternativeServiceInfoVector alternative_service_info_vector;
2419   alternative_service_info_vector.push_back(
2420       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
2421           AlternativeService(kProtoHTTP2, "foo", 443), now + base::Minutes(1)));
2422   alternative_service_info_vector.push_back(
2423       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
2424           AlternativeService(kProtoQUIC, "bar", 443), now + base::Hours(1),
2425           DefaultSupportedQuicVersions()));
2426   alternative_service_info_vector.push_back(
2427       AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
2428           AlternativeService(kProtoQUIC, "baz", 443), now + base::Hours(1),
2429           DefaultSupportedQuicVersions()));
2430 
2431   impl_.SetAlternativeServices(url::SchemeHostPort("https", "youtube.com", 443),
2432                                NetworkAnonymizationKey(),
2433                                alternative_service_info_vector);
2434 
2435   impl_.MarkAlternativeServiceBroken(AlternativeService(kProtoQUIC, "bar", 443),
2436                                      NetworkAnonymizationKey());
2437 
2438   impl_.MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
2439       AlternativeService(kProtoQUIC, "baz", 443), NetworkAnonymizationKey());
2440 
2441   alternative_service_info_vector.clear();
2442   alternative_service_info_vector.push_back(
2443       AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
2444           AlternativeService(kProtoHTTP2, "foo2", 443), now + base::Days(1)));
2445   impl_.SetAlternativeServices(url::SchemeHostPort("http", "test.com", 80),
2446                                NetworkAnonymizationKey(),
2447                                alternative_service_info_vector);
2448 
2449   const char expected_json[] =
2450       "["
2451       "{"
2452       "\"alternative_service\":"
2453       "[\"h2 foo2:443, expires 2018-01-25 15:12:53\"],"
2454       "\"network_anonymization_key\":\"null\","
2455       "\"server\":\"http://test.com\""
2456       "},"
2457       "{"
2458       "\"alternative_service\":"
2459       "[\"h2 foo:443, expires 2018-01-24 15:13:53\","
2460       "\"quic bar:443, expires 2018-01-24 16:12:53"
2461       " (broken until 2018-01-24 15:17:53)\","
2462       "\"quic baz:443, expires 2018-01-24 16:12:53"
2463       " (broken until 2018-01-24 15:17:53)\"],"
2464       "\"network_anonymization_key\":\"null\","
2465       "\"server\":\"https://youtube.com\""
2466       "}"
2467       "]";
2468 
2469   base::Value alternative_service_info_value =
2470       impl_.GetAlternativeServiceInfoAsValue();
2471   std::string alternative_service_info_json;
2472   base::JSONWriter::Write(alternative_service_info_value,
2473                           &alternative_service_info_json);
2474   EXPECT_EQ(expected_json, alternative_service_info_json);
2475 }
2476 
TEST_F(HttpServerPropertiesTest,LoadLastLocalAddressWhenQuicWorked)2477 TEST_F(HttpServerPropertiesTest, LoadLastLocalAddressWhenQuicWorked) {
2478   const IPAddress kEmptyAddress;
2479   const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
2480   const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
2481 
2482   // Check by initializing empty address.
2483   impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
2484   EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2485   // Empty address should not be considered an address that was used when QUIC
2486   // worked.
2487   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2488   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2489   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2490 
2491   // Check by initializing with a valid address.
2492   impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress1);
2493   EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2494   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2495   EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2496   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2497 
2498   // Try another valid address.
2499   impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kValidAddress2);
2500   EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2501   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2502   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2503   EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2504 
2505   // And loading an empty address clears the current one.
2506   // TODO(mmenke): This seems like a bug, since if we've learned the current
2507   // network supports QUIC, surely we want to save that to disk? Seems like a
2508   // pre-existing value should take precedence, if non-empty, since if the
2509   // current network is already known to support QUIC, the loaded value is no
2510   // longer relevant.
2511   impl_.OnLastLocalAddressWhenQuicWorkedForTesting(kEmptyAddress);
2512   EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2513   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2514   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2515   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2516 }
2517 
TEST_F(HttpServerPropertiesTest,SetLastLocalAddressWhenQuicWorked)2518 TEST_F(HttpServerPropertiesTest, SetLastLocalAddressWhenQuicWorked) {
2519   const IPAddress kEmptyAddress;
2520   const IPAddress kValidAddress1 = IPAddress::IPv4Localhost();
2521   const IPAddress kValidAddress2 = IPAddress::IPv6Localhost();
2522 
2523   EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2524   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2525   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2526   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2527 
2528   // Set to a valid address.
2529   impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress1);
2530   EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2531   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2532   EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2533   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2534 
2535   // Clear only this value.
2536   impl_.ClearLastLocalAddressWhenQuicWorked();
2537   EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2538   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2539   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2540   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2541 
2542   // Try another valid address.
2543   impl_.SetLastLocalAddressWhenQuicWorked(kValidAddress2);
2544   EXPECT_TRUE(impl_.HasLastLocalAddressWhenQuicWorked());
2545   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2546   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2547   EXPECT_TRUE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2548 
2549   // Clear all values.
2550   impl_.Clear(base::OnceClosure());
2551   EXPECT_FALSE(impl_.HasLastLocalAddressWhenQuicWorked());
2552   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kEmptyAddress));
2553   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress1));
2554   EXPECT_FALSE(impl_.WasLastLocalAddressWhenQuicWorked(kValidAddress2));
2555 }
2556 
TEST_F(HttpServerPropertiesTest,LoadServerNetworkStats)2557 TEST_F(HttpServerPropertiesTest, LoadServerNetworkStats) {
2558   url::SchemeHostPort google_server("https", "www.google.com", 443);
2559 
2560   // Check by initializing empty ServerNetworkStats.
2561   std::unique_ptr<HttpServerProperties::ServerInfoMap> load_server_info_map =
2562       std::make_unique<HttpServerProperties::ServerInfoMap>();
2563   impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
2564   const ServerNetworkStats* stats =
2565       impl_.GetServerNetworkStats(google_server, NetworkAnonymizationKey());
2566   EXPECT_EQ(nullptr, stats);
2567 
2568   // Check by initializing with www.google.com:443.
2569   ServerNetworkStats stats_google;
2570   stats_google.srtt = base::Microseconds(10);
2571   stats_google.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
2572   load_server_info_map =
2573       std::make_unique<HttpServerProperties::ServerInfoMap>();
2574   load_server_info_map->GetOrPut(CreateSimpleKey(google_server))
2575       ->second.server_network_stats = stats_google;
2576   impl_.OnServerInfoLoadedForTesting(std::move(load_server_info_map));
2577 
2578   // Verify data for www.google.com:443.
2579   ASSERT_EQ(1u, impl_.server_info_map_for_testing().size());
2580   EXPECT_EQ(stats_google, *(impl_.GetServerNetworkStats(
2581                               google_server, NetworkAnonymizationKey())));
2582 
2583   // Test recency order and overwriting of data.
2584   //
2585   // |docs_server| has a ServerNetworkStats, which will be overwritten by
2586   // OnServerInfoLoadedForTesting(), because |server_network_stats_map| has an
2587   // entry for |docs_server|.
2588   url::SchemeHostPort docs_server("https", "docs.google.com", 443);
2589   ServerNetworkStats stats_docs;
2590   stats_docs.srtt = base::Microseconds(20);
2591   stats_docs.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(200);
2592   // Recency order will be |docs_server| and |google_server|.
2593   impl_.SetServerNetworkStats(docs_server, NetworkAnonymizationKey(),
2594                               stats_docs);
2595 
2596   // Prepare |server_info_map| to be loaded by OnServerInfoLoadedForTesting().
2597   std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map =
2598       std::make_unique<HttpServerProperties::ServerInfoMap>();
2599 
2600   // Change the values for |docs_server|.
2601   ServerNetworkStats new_stats_docs;
2602   new_stats_docs.srtt = base::Microseconds(25);
2603   new_stats_docs.bandwidth_estimate =
2604       quic::QuicBandwidth::FromBitsPerSecond(250);
2605   server_info_map->GetOrPut(CreateSimpleKey(docs_server))
2606       ->second.server_network_stats = new_stats_docs;
2607   // Add data for mail.google.com:443.
2608   url::SchemeHostPort mail_server("https", "mail.google.com", 443);
2609   ServerNetworkStats stats_mail;
2610   stats_mail.srtt = base::Microseconds(30);
2611   stats_mail.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(300);
2612   server_info_map->GetOrPut(CreateSimpleKey(mail_server))
2613       ->second.server_network_stats = stats_mail;
2614 
2615   // Recency order will be |docs_server|, |google_server| and |mail_server|.
2616   impl_.OnServerInfoLoadedForTesting(std::move(server_info_map));
2617 
2618   const HttpServerProperties::ServerInfoMap& map =
2619       impl_.server_info_map_for_testing();
2620   ASSERT_EQ(3u, map.size());
2621   auto map_it = map.begin();
2622 
2623   EXPECT_EQ(docs_server, map_it->first.server);
2624   EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
2625   ASSERT_TRUE(map_it->second.server_network_stats.has_value());
2626   EXPECT_EQ(new_stats_docs, *map_it->second.server_network_stats);
2627   ++map_it;
2628   EXPECT_EQ(google_server, map_it->first.server);
2629   EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
2630   ASSERT_TRUE(map_it->second.server_network_stats.has_value());
2631   EXPECT_EQ(stats_google, *map_it->second.server_network_stats);
2632   ++map_it;
2633   EXPECT_EQ(mail_server, map_it->first.server);
2634   EXPECT_TRUE(map_it->first.network_anonymization_key.IsEmpty());
2635   ASSERT_TRUE(map_it->second.server_network_stats.has_value());
2636   EXPECT_EQ(stats_mail, *map_it->second.server_network_stats);
2637 }
2638 
TEST_F(HttpServerPropertiesTest,SetServerNetworkStats)2639 TEST_F(HttpServerPropertiesTest, SetServerNetworkStats) {
2640   url::SchemeHostPort foo_http_server("http", "foo", 443);
2641   url::SchemeHostPort foo_https_server("https", "foo", 443);
2642   EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
2643                                                  NetworkAnonymizationKey()));
2644   EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2645                                                  NetworkAnonymizationKey()));
2646 
2647   ServerNetworkStats stats1;
2648   stats1.srtt = base::Microseconds(10);
2649   stats1.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
2650   impl_.SetServerNetworkStats(foo_http_server, NetworkAnonymizationKey(),
2651                               stats1);
2652 
2653   const ServerNetworkStats* stats2 =
2654       impl_.GetServerNetworkStats(foo_http_server, NetworkAnonymizationKey());
2655   EXPECT_EQ(10, stats2->srtt.ToInternalValue());
2656   EXPECT_EQ(100, stats2->bandwidth_estimate.ToBitsPerSecond());
2657   // Https server should have nothing set for server network stats.
2658   EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2659                                                  NetworkAnonymizationKey()));
2660 
2661   impl_.Clear(base::OnceClosure());
2662   EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_http_server,
2663                                                  NetworkAnonymizationKey()));
2664   EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2665                                                  NetworkAnonymizationKey()));
2666 }
2667 
TEST_F(HttpServerPropertiesTest,ClearServerNetworkStats)2668 TEST_F(HttpServerPropertiesTest, ClearServerNetworkStats) {
2669   ServerNetworkStats stats;
2670   stats.srtt = base::Microseconds(10);
2671   stats.bandwidth_estimate = quic::QuicBandwidth::FromBitsPerSecond(100);
2672   url::SchemeHostPort foo_https_server("https", "foo", 443);
2673   impl_.SetServerNetworkStats(foo_https_server, NetworkAnonymizationKey(),
2674                               stats);
2675 
2676   impl_.ClearServerNetworkStats(foo_https_server, NetworkAnonymizationKey());
2677   EXPECT_EQ(nullptr, impl_.GetServerNetworkStats(foo_https_server,
2678                                                  NetworkAnonymizationKey()));
2679 }
2680 
TEST_F(HttpServerPropertiesTest,OnQuicServerInfoMapLoaded)2681 TEST_F(HttpServerPropertiesTest, OnQuicServerInfoMapLoaded) {
2682   quic::QuicServerId google_quic_server_id("www.google.com", 443, true);
2683   HttpServerProperties::QuicServerInfoMapKey google_key(
2684       google_quic_server_id, NetworkAnonymizationKey(),
2685       false /* use_network_anonymization_key */);
2686 
2687   const int kMaxQuicServerEntries = 10;
2688   impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
2689   EXPECT_EQ(10u, impl_.quic_server_info_map().max_size());
2690 
2691   // Check empty map.
2692   std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
2693       init_quic_server_info_map =
2694           std::make_unique<HttpServerProperties::QuicServerInfoMap>(
2695               kMaxQuicServerEntries);
2696   impl_.OnQuicServerInfoMapLoadedForTesting(
2697       std::move(init_quic_server_info_map));
2698   EXPECT_EQ(0u, impl_.quic_server_info_map().size());
2699 
2700   // Check by initializing with www.google.com:443.
2701   std::string google_server_info("google_quic_server_info");
2702   init_quic_server_info_map =
2703       std::make_unique<HttpServerProperties::QuicServerInfoMap>(
2704           kMaxQuicServerEntries);
2705   init_quic_server_info_map->Put(google_key, google_server_info);
2706   impl_.OnQuicServerInfoMapLoadedForTesting(
2707       std::move(init_quic_server_info_map));
2708 
2709   // Verify data for www.google.com:443.
2710   EXPECT_EQ(1u, impl_.quic_server_info_map().size());
2711   EXPECT_EQ(google_server_info,
2712             *impl_.GetQuicServerInfo(google_quic_server_id,
2713                                      NetworkAnonymizationKey()));
2714 
2715   // Test recency order and overwriting of data.
2716   //
2717   // |docs_server| has a QuicServerInfo, which will be overwritten by
2718   // SetQuicServerInfoMap(), because |quic_server_info_map| has an
2719   // entry for |docs_server|.
2720   quic::QuicServerId docs_quic_server_id("docs.google.com", 443, true);
2721   HttpServerProperties::QuicServerInfoMapKey docs_key(
2722       docs_quic_server_id, NetworkAnonymizationKey(),
2723       false /* use_network_anonymization_key */);
2724   std::string docs_server_info("docs_quic_server_info");
2725   impl_.SetQuicServerInfo(docs_quic_server_id, NetworkAnonymizationKey(),
2726                           docs_server_info);
2727 
2728   // Recency order will be |docs_server| and |google_server|.
2729   const HttpServerProperties::QuicServerInfoMap& map =
2730       impl_.quic_server_info_map();
2731   ASSERT_EQ(2u, map.size());
2732   auto map_it = map.begin();
2733   EXPECT_EQ(map_it->first, docs_key);
2734   EXPECT_EQ(docs_server_info, map_it->second);
2735   ++map_it;
2736   EXPECT_EQ(map_it->first, google_key);
2737   EXPECT_EQ(google_server_info, map_it->second);
2738 
2739   // Prepare |quic_server_info_map| to be loaded by
2740   // SetQuicServerInfoMap().
2741   std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
2742       quic_server_info_map =
2743           std::make_unique<HttpServerProperties::QuicServerInfoMap>(
2744               kMaxQuicServerEntries);
2745   // Change the values for |docs_server|.
2746   std::string new_docs_server_info("new_docs_quic_server_info");
2747   quic_server_info_map->Put(docs_key, new_docs_server_info);
2748   // Add data for mail.google.com:443.
2749   quic::QuicServerId mail_quic_server_id("mail.google.com", 443, true);
2750   HttpServerProperties::QuicServerInfoMapKey mail_key(
2751       mail_quic_server_id, NetworkAnonymizationKey(),
2752       false /* use_network_anonymization_key */);
2753   std::string mail_server_info("mail_quic_server_info");
2754   quic_server_info_map->Put(mail_key, mail_server_info);
2755   impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
2756 
2757   // Recency order will be |docs_server|, |google_server| and |mail_server|.
2758   const HttpServerProperties::QuicServerInfoMap& memory_map =
2759       impl_.quic_server_info_map();
2760   ASSERT_EQ(3u, memory_map.size());
2761   auto memory_map_it = memory_map.begin();
2762   EXPECT_EQ(memory_map_it->first, docs_key);
2763   EXPECT_EQ(new_docs_server_info, memory_map_it->second);
2764   ++memory_map_it;
2765   EXPECT_EQ(memory_map_it->first, google_key);
2766   EXPECT_EQ(google_server_info, memory_map_it->second);
2767   ++memory_map_it;
2768   EXPECT_EQ(memory_map_it->first, mail_key);
2769   EXPECT_EQ(mail_server_info, memory_map_it->second);
2770 
2771   // Shrink the size of |quic_server_info_map| and verify the MRU order is
2772   // maintained.
2773   impl_.SetMaxServerConfigsStoredInProperties(2);
2774   EXPECT_EQ(2u, impl_.quic_server_info_map().max_size());
2775 
2776   const HttpServerProperties::QuicServerInfoMap& memory_map1 =
2777       impl_.quic_server_info_map();
2778   ASSERT_EQ(2u, memory_map1.size());
2779   auto memory_map1_it = memory_map1.begin();
2780   EXPECT_EQ(memory_map1_it->first, docs_key);
2781   EXPECT_EQ(new_docs_server_info, memory_map1_it->second);
2782   ++memory_map1_it;
2783   EXPECT_EQ(memory_map1_it->first, google_key);
2784   EXPECT_EQ(google_server_info, memory_map1_it->second);
2785   // |QuicServerInfo| for |mail_quic_server_id| shouldn't be there.
2786   EXPECT_EQ(nullptr, impl_.GetQuicServerInfo(mail_quic_server_id,
2787                                              NetworkAnonymizationKey()));
2788 }
2789 
TEST_F(HttpServerPropertiesTest,SetQuicServerInfo)2790 TEST_F(HttpServerPropertiesTest, SetQuicServerInfo) {
2791   quic::QuicServerId server1("foo", 80, false /* privacy_mode_enabled */);
2792   quic::QuicServerId server2("foo", 80, true /* privacy_mode_enabled */);
2793 
2794   std::string quic_server_info1("quic_server_info1");
2795   std::string quic_server_info2("quic_server_info2");
2796   std::string quic_server_info3("quic_server_info3");
2797 
2798   // Without network isolation keys enabled for HttpServerProperties, passing in
2799   // a NetworkAnonymizationKey should have no effect on behavior.
2800   impl_.SetQuicServerInfo(server1, NetworkAnonymizationKey(),
2801                           quic_server_info1);
2802   EXPECT_EQ(quic_server_info1,
2803             *(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey())));
2804   EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2805   EXPECT_EQ(quic_server_info1,
2806             *(impl_.GetQuicServerInfo(server1, network_anonymization_key1_)));
2807   EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_anonymization_key1_));
2808 
2809   impl_.SetQuicServerInfo(server2, network_anonymization_key1_,
2810                           quic_server_info2);
2811   EXPECT_EQ(quic_server_info1,
2812             *(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey())));
2813   EXPECT_EQ(quic_server_info2,
2814             *(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey())));
2815   EXPECT_EQ(quic_server_info1,
2816             *(impl_.GetQuicServerInfo(server1, network_anonymization_key1_)));
2817   EXPECT_EQ(quic_server_info2,
2818             *(impl_.GetQuicServerInfo(server2, network_anonymization_key1_)));
2819 
2820   impl_.SetQuicServerInfo(server1, network_anonymization_key1_,
2821                           quic_server_info3);
2822   EXPECT_EQ(quic_server_info3,
2823             *(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey())));
2824   EXPECT_EQ(quic_server_info2,
2825             *(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey())));
2826   EXPECT_EQ(quic_server_info3,
2827             *(impl_.GetQuicServerInfo(server1, network_anonymization_key1_)));
2828   EXPECT_EQ(quic_server_info2,
2829             *(impl_.GetQuicServerInfo(server2, network_anonymization_key1_)));
2830 
2831   impl_.Clear(base::OnceClosure());
2832   EXPECT_FALSE(impl_.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2833   EXPECT_FALSE(impl_.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2834   EXPECT_FALSE(impl_.GetQuicServerInfo(server1, network_anonymization_key1_));
2835   EXPECT_FALSE(impl_.GetQuicServerInfo(server2, network_anonymization_key1_));
2836 
2837   base::test::ScopedFeatureList feature_list;
2838   feature_list.InitAndEnableFeature(
2839       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
2840   // Since HttpServerProperties caches the feature value, have to create a new
2841   // one.
2842   HttpServerProperties properties(nullptr /* pref_delegate */,
2843                                   nullptr /* net_log */, test_tick_clock_,
2844                                   &test_clock_);
2845 
2846   properties.SetQuicServerInfo(server1, NetworkAnonymizationKey(),
2847                                quic_server_info1);
2848   EXPECT_EQ(quic_server_info1, *(properties.GetQuicServerInfo(
2849                                    server1, NetworkAnonymizationKey())));
2850   EXPECT_FALSE(
2851       properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2852   EXPECT_FALSE(
2853       properties.GetQuicServerInfo(server1, network_anonymization_key1_));
2854   EXPECT_FALSE(
2855       properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2856 
2857   properties.SetQuicServerInfo(server1, network_anonymization_key1_,
2858                                quic_server_info2);
2859   EXPECT_EQ(quic_server_info1, *(properties.GetQuicServerInfo(
2860                                    server1, NetworkAnonymizationKey())));
2861   EXPECT_FALSE(
2862       properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2863   EXPECT_EQ(quic_server_info2, *(properties.GetQuicServerInfo(
2864                                    server1, network_anonymization_key1_)));
2865   EXPECT_FALSE(
2866       properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2867 
2868   properties.SetQuicServerInfo(server2, network_anonymization_key1_,
2869                                quic_server_info3);
2870   EXPECT_EQ(quic_server_info1, *(properties.GetQuicServerInfo(
2871                                    server1, NetworkAnonymizationKey())));
2872   EXPECT_FALSE(
2873       properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2874   EXPECT_EQ(quic_server_info2, *(properties.GetQuicServerInfo(
2875                                    server1, network_anonymization_key1_)));
2876   EXPECT_EQ(quic_server_info3, *(properties.GetQuicServerInfo(
2877                                    server2, network_anonymization_key1_)));
2878 
2879   properties.Clear(base::OnceClosure());
2880   EXPECT_FALSE(
2881       properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2882   EXPECT_FALSE(
2883       properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2884   EXPECT_FALSE(
2885       properties.GetQuicServerInfo(server1, network_anonymization_key1_));
2886   EXPECT_FALSE(
2887       properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2888 }
2889 
2890 // Tests that GetQuicServerInfo() returns server info of a host
2891 // with the same canonical suffix when there is no exact host match.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatch)2892 TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatch) {
2893   // Set up HttpServerProperties.
2894   // Add a host with a canonical suffix.
2895   quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
2896   std::string foo_server_info("foo_server_info");
2897   impl_.SetQuicServerInfo(foo_server_id, NetworkAnonymizationKey(),
2898                           foo_server_info);
2899 
2900   // Add a host that has a different canonical suffix.
2901   quic::QuicServerId baz_server_id("baz.video.com", 443, false);
2902   std::string baz_server_info("baz_server_info");
2903   impl_.SetQuicServerInfo(baz_server_id, NetworkAnonymizationKey(),
2904                           baz_server_info);
2905 
2906   // Create SchemeHostPort with a host that has the initial canonical suffix.
2907   quic::QuicServerId bar_server_id("bar.googlevideo.com", 443, false);
2908 
2909   // Check the the server info associated with "foo" is returned for "bar".
2910   const std::string* bar_server_info =
2911       impl_.GetQuicServerInfo(bar_server_id, NetworkAnonymizationKey());
2912   ASSERT_TRUE(bar_server_info != nullptr);
2913   EXPECT_EQ(foo_server_info, *bar_server_info);
2914 }
2915 
2916 // Make sure that canonical suffices respect NetworkIsolationKeys when using
2917 // QuicServerInfo methods.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchWithNetworkIsolationKey)2918 TEST_F(HttpServerPropertiesTest,
2919        QuicServerInfoCanonicalSuffixMatchWithNetworkIsolationKey) {
2920   // Two servers with same canonical suffix.
2921   quic::QuicServerId server1("foo.googlevideo.com", 80,
2922                              false /* privacy_mode_enabled */);
2923   quic::QuicServerId server2("bar.googlevideo.com", 80,
2924                              false /* privacy_mode_enabled */);
2925 
2926   std::string server_info1("server_info1");
2927   std::string server_info2("server_info2");
2928 
2929   base::test::ScopedFeatureList feature_list;
2930   feature_list.InitAndEnableFeature(
2931       features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
2932   // Since HttpServerProperties caches the feature value, have to create a new
2933   // one.
2934   HttpServerProperties properties(nullptr /* pref_delegate */,
2935                                   nullptr /* net_log */, test_tick_clock_,
2936                                   &test_clock_);
2937 
2938   // Set QuicServerInfo for one canononical suffix and
2939   // |network_anonymization_key1_|. It should be accessible via another
2940   // SchemeHostPort, but only when the NetworkIsolationKeys match.
2941   properties.SetQuicServerInfo(server1, network_anonymization_key1_,
2942                                server_info1);
2943   const std::string* fetched_server_info =
2944       properties.GetQuicServerInfo(server1, network_anonymization_key1_);
2945   ASSERT_TRUE(fetched_server_info);
2946   EXPECT_EQ(server_info1, *fetched_server_info);
2947   fetched_server_info =
2948       properties.GetQuicServerInfo(server2, network_anonymization_key1_);
2949   ASSERT_TRUE(fetched_server_info);
2950   EXPECT_EQ(server_info1, *fetched_server_info);
2951   EXPECT_FALSE(
2952       properties.GetQuicServerInfo(server1, network_anonymization_key2_));
2953   EXPECT_FALSE(
2954       properties.GetQuicServerInfo(server2, network_anonymization_key2_));
2955   EXPECT_FALSE(
2956       properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2957   EXPECT_FALSE(
2958       properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2959 
2960   // Set different QuicServerInfo for the same canononical suffix and
2961   // |network_anonymization_key2_|. Both infos should be retriveable by using
2962   // the different NetworkIsolationKeys.
2963   properties.SetQuicServerInfo(server1, network_anonymization_key2_,
2964                                server_info2);
2965   fetched_server_info =
2966       properties.GetQuicServerInfo(server1, network_anonymization_key1_);
2967   ASSERT_TRUE(fetched_server_info);
2968   EXPECT_EQ(server_info1, *fetched_server_info);
2969   fetched_server_info =
2970       properties.GetQuicServerInfo(server2, network_anonymization_key1_);
2971   ASSERT_TRUE(fetched_server_info);
2972   EXPECT_EQ(server_info1, *fetched_server_info);
2973   fetched_server_info =
2974       properties.GetQuicServerInfo(server1, network_anonymization_key2_);
2975   ASSERT_TRUE(fetched_server_info);
2976   EXPECT_EQ(server_info2, *fetched_server_info);
2977   fetched_server_info =
2978       properties.GetQuicServerInfo(server2, network_anonymization_key2_);
2979   ASSERT_TRUE(fetched_server_info);
2980   EXPECT_EQ(server_info2, *fetched_server_info);
2981   EXPECT_FALSE(
2982       properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2983   EXPECT_FALSE(
2984       properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
2985 
2986   // Clearing should destroy all information.
2987   properties.Clear(base::OnceClosure());
2988   EXPECT_FALSE(
2989       properties.GetQuicServerInfo(server1, network_anonymization_key1_));
2990   EXPECT_FALSE(
2991       properties.GetQuicServerInfo(server2, network_anonymization_key1_));
2992   EXPECT_FALSE(
2993       properties.GetQuicServerInfo(server1, network_anonymization_key2_));
2994   EXPECT_FALSE(
2995       properties.GetQuicServerInfo(server2, network_anonymization_key2_));
2996   EXPECT_FALSE(
2997       properties.GetQuicServerInfo(server1, NetworkAnonymizationKey()));
2998   EXPECT_FALSE(
2999       properties.GetQuicServerInfo(server2, NetworkAnonymizationKey()));
3000 }
3001 
3002 // Verifies that GetQuicServerInfo() returns the MRU entry if multiple records
3003 // match a given canonical host.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchReturnsMruEntry)3004 TEST_F(HttpServerPropertiesTest,
3005        QuicServerInfoCanonicalSuffixMatchReturnsMruEntry) {
3006   // Set up HttpServerProperties by adding two hosts with the same canonical
3007   // suffixes.
3008   quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
3009   std::string h1_server_info("h1_server_info");
3010   impl_.SetQuicServerInfo(h1_server_id, NetworkAnonymizationKey(),
3011                           h1_server_info);
3012 
3013   quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
3014   std::string h2_server_info("h2_server_info");
3015   impl_.SetQuicServerInfo(h2_server_id, NetworkAnonymizationKey(),
3016                           h2_server_info);
3017 
3018   // Create quic::QuicServerId to use for the search.
3019   quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
3020 
3021   // Check that 'h2' info is returned since it is MRU.
3022   const std::string* server_info =
3023       impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3024   ASSERT_TRUE(server_info != nullptr);
3025   EXPECT_EQ(h2_server_info, *server_info);
3026 
3027   // Access 'h1' info, so it becomes MRU.
3028   impl_.GetQuicServerInfo(h1_server_id, NetworkAnonymizationKey());
3029 
3030   // Check that 'h1' info is returned since it is MRU now.
3031   server_info =
3032       impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3033   ASSERT_TRUE(server_info != nullptr);
3034   EXPECT_EQ(h1_server_info, *server_info);
3035 }
3036 
3037 // Verifies that |GetQuicServerInfo| doesn't change the MRU order of the server
3038 // info map when a record is matched based on a canonical name.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchDoesntChangeOrder)3039 TEST_F(HttpServerPropertiesTest,
3040        QuicServerInfoCanonicalSuffixMatchDoesntChangeOrder) {
3041   // Add a host with a matching canonical name.
3042   quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
3043   HttpServerProperties::QuicServerInfoMapKey h1_key(
3044       h1_server_id, NetworkAnonymizationKey(),
3045       false /* use_network_anonymization_key */);
3046   std::string h1_server_info("h1_server_info");
3047   impl_.SetQuicServerInfo(h1_server_id, NetworkAnonymizationKey(),
3048                           h1_server_info);
3049 
3050   // Add a host hosts with a non-matching canonical name.
3051   quic::QuicServerId h2_server_id("h2.video.com", 443, false);
3052   HttpServerProperties::QuicServerInfoMapKey h2_key(
3053       h2_server_id, NetworkAnonymizationKey(),
3054       false /* use_network_anonymization_key */);
3055   std::string h2_server_info("h2_server_info");
3056   impl_.SetQuicServerInfo(h2_server_id, NetworkAnonymizationKey(),
3057                           h2_server_info);
3058 
3059   // Check that "h2.video.com" is the MRU entry in the map.
3060   EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
3061 
3062   // Search for the entry that matches the canonical name
3063   // ("h1.googlevideo.com").
3064   quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
3065   const std::string* server_info =
3066       impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3067   ASSERT_TRUE(server_info != nullptr);
3068 
3069   // Check that the search (although successful) hasn't changed the MRU order of
3070   // the map.
3071   EXPECT_EQ(h2_key, impl_.quic_server_info_map().begin()->first);
3072 
3073   // Search for "h1.googlevideo.com" directly, so it becomes MRU
3074   impl_.GetQuicServerInfo(h1_server_id, NetworkAnonymizationKey());
3075 
3076   // Check that "h1.googlevideo.com" is the MRU entry now.
3077   EXPECT_EQ(h1_key, impl_.quic_server_info_map().begin()->first);
3078 }
3079 
3080 // Tests that the canonical host matching works for hosts stored in memory cache
3081 // and the ones loaded from persistent storage, i.e. server info added
3082 // using SetQuicServerInfo() and SetQuicServerInfoMap() is taken into
3083 // cosideration when searching for server info for a host with the same
3084 // canonical suffix.
TEST_F(HttpServerPropertiesTest,QuicServerInfoCanonicalSuffixMatchSetInfoMap)3085 TEST_F(HttpServerPropertiesTest, QuicServerInfoCanonicalSuffixMatchSetInfoMap) {
3086   // Add a host info using SetQuicServerInfo(). That will simulate an info
3087   // entry stored in memory cache.
3088   quic::QuicServerId h1_server_id("h1.googlevideo.com", 443, false);
3089   std::string h1_server_info("h1_server_info_memory_cache");
3090   impl_.SetQuicServerInfo(h1_server_id, NetworkAnonymizationKey(),
3091                           h1_server_info);
3092 
3093   // Prepare a map with host info and add it using SetQuicServerInfoMap(). That
3094   // will simulate info records read from the persistence storage.
3095   quic::QuicServerId h2_server_id("h2.googlevideo.com", 443, false);
3096   HttpServerProperties::QuicServerInfoMapKey h2_key(
3097       h2_server_id, NetworkAnonymizationKey(),
3098       false /* use_network_anonymization_key */);
3099   std::string h2_server_info("h2_server_info_from_disk");
3100 
3101   quic::QuicServerId h3_server_id("h3.ggpht.com", 443, false);
3102   HttpServerProperties::QuicServerInfoMapKey h3_key(
3103       h3_server_id, NetworkAnonymizationKey(),
3104       false /* use_network_anonymization_key */);
3105   std::string h3_server_info("h3_server_info_from_disk");
3106 
3107   const int kMaxQuicServerEntries = 10;
3108   impl_.SetMaxServerConfigsStoredInProperties(kMaxQuicServerEntries);
3109 
3110   std::unique_ptr<HttpServerProperties::QuicServerInfoMap>
3111       quic_server_info_map =
3112           std::make_unique<HttpServerProperties::QuicServerInfoMap>(
3113               kMaxQuicServerEntries);
3114   quic_server_info_map->Put(h2_key, h2_server_info);
3115   quic_server_info_map->Put(h3_key, h3_server_info);
3116   impl_.OnQuicServerInfoMapLoadedForTesting(std::move(quic_server_info_map));
3117 
3118   // Check that the server info from the memory cache is returned since unique
3119   // entries from the memory cache are added after entries from the
3120   // persistence storage and, therefore, are most recently used.
3121   quic::QuicServerId foo_server_id("foo.googlevideo.com", 443, false);
3122   const std::string* server_info =
3123       impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3124   ASSERT_TRUE(server_info != nullptr);
3125   EXPECT_EQ(h1_server_info, *server_info);
3126 
3127   // Check that server info that was added using SetQuicServerInfoMap() can be
3128   // found.
3129   foo_server_id = quic::QuicServerId("foo.ggpht.com", 443, false);
3130   server_info =
3131       impl_.GetQuicServerInfo(foo_server_id, NetworkAnonymizationKey());
3132   ASSERT_TRUE(server_info != nullptr);
3133   EXPECT_EQ(h3_server_info, *server_info);
3134 }
3135 
3136 }  // namespace
3137 
3138 }  // namespace net
3139