Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / net / base / sdch_manager_unittest.cc
blobb5429b4c7a2decd15f253f61541060197003ef58
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <limits.h>
7 #include <string>
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "net/base/sdch_manager.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 namespace net {
16 //------------------------------------------------------------------------------
17 // Provide sample data and compression results with a sample VCDIFF dictionary.
18 // Note an SDCH dictionary has extra meta-data before the VCDIFF dictionary.
19 static const char kTestVcdiffDictionary[] = "DictionaryFor"
20 "SdchCompression1SdchCompression2SdchCompression3SdchCompression\n";
22 //------------------------------------------------------------------------------
24 class SdchManagerTest : public testing::Test {
25 protected:
26 SdchManagerTest()
27 : sdch_manager_(new SdchManager) {
30 SdchManager* sdch_manager() { return sdch_manager_.get(); }
32 // Reset globals back to default state.
33 virtual void TearDown() {
34 SdchManager::EnableSdchSupport(true);
35 SdchManager::EnableSecureSchemeSupport(false);
38 private:
39 scoped_ptr<SdchManager> sdch_manager_;
42 //------------------------------------------------------------------------------
43 static std::string NewSdchDictionary(const std::string& domain) {
44 std::string dictionary;
45 if (!domain.empty()) {
46 dictionary.append("Domain: ");
47 dictionary.append(domain);
48 dictionary.append("\n");
50 dictionary.append("\n");
51 dictionary.append(kTestVcdiffDictionary, sizeof(kTestVcdiffDictionary) - 1);
52 return dictionary;
55 TEST_F(SdchManagerTest, DomainSupported) {
56 GURL google_url("http://www.google.com");
58 SdchManager::EnableSdchSupport(false);
59 EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(google_url));
60 SdchManager::EnableSdchSupport(true);
61 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(google_url));
64 TEST_F(SdchManagerTest, DomainBlacklisting) {
65 GURL test_url("http://www.test.com");
66 GURL google_url("http://www.google.com");
68 sdch_manager()->BlacklistDomain(test_url, SdchManager::MIN_PROBLEM_CODE);
69 EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(test_url));
70 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(google_url));
72 sdch_manager()->BlacklistDomain(google_url, SdchManager::MIN_PROBLEM_CODE);
73 EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(google_url));
76 TEST_F(SdchManagerTest, DomainBlacklistingCaseSensitivity) {
77 GURL test_url("http://www.TesT.com");
78 GURL test2_url("http://www.tEst.com");
80 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(test_url));
81 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(test2_url));
82 sdch_manager()->BlacklistDomain(test_url, SdchManager::MIN_PROBLEM_CODE);
83 EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(test2_url));
86 TEST_F(SdchManagerTest, BlacklistingReset) {
87 GURL gurl("http://mytest.DoMain.com");
88 std::string domain(gurl.host());
90 sdch_manager()->ClearBlacklistings();
91 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0);
92 EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), 0);
93 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(gurl));
96 TEST_F(SdchManagerTest, BlacklistingSingleBlacklist) {
97 GURL gurl("http://mytest.DoMain.com");
98 std::string domain(gurl.host());
99 sdch_manager()->ClearBlacklistings();
101 sdch_manager()->BlacklistDomain(gurl, SdchManager::MIN_PROBLEM_CODE);
102 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 1);
103 EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), 1);
105 // Check that any domain lookup reduces the blacklist counter.
106 EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(gurl));
107 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0);
108 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(gurl));
111 TEST_F(SdchManagerTest, BlacklistingExponential) {
112 GURL gurl("http://mytest.DoMain.com");
113 std::string domain(gurl.host());
114 sdch_manager()->ClearBlacklistings();
116 int exponential = 1;
117 for (int i = 1; i < 100; ++i) {
118 sdch_manager()->BlacklistDomain(gurl, SdchManager::MIN_PROBLEM_CODE);
119 EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), exponential);
121 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), exponential);
122 EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(gurl));
123 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), exponential - 1);
125 // Simulate a large number of domain checks (which eventually remove the
126 // blacklisting).
127 sdch_manager()->ClearDomainBlacklisting(domain);
128 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0);
129 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(gurl));
131 // Predict what exponential backoff will be.
132 exponential = 1 + 2 * exponential;
133 if (exponential < 0)
134 exponential = INT_MAX; // We don't wrap.
138 TEST_F(SdchManagerTest, CanSetExactMatchDictionary) {
139 std::string dictionary_domain("x.y.z.google.com");
140 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
142 // Perfect match should work.
143 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
144 GURL("http://" + dictionary_domain)));
147 TEST_F(SdchManagerTest, CanAdvertiseDictionaryOverHTTP) {
148 std::string dictionary_domain("x.y.z.google.com");
149 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
151 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
152 GURL("http://" + dictionary_domain)));
154 std::string dictionary_list;
155 // HTTP target URL can advertise dictionary.
156 sdch_manager()->GetAvailDictionaryList(
157 GURL("http://" + dictionary_domain + "/test"),
158 &dictionary_list);
159 EXPECT_FALSE(dictionary_list.empty());
162 TEST_F(SdchManagerTest, CanNotAdvertiseDictionaryOverHTTPS) {
163 std::string dictionary_domain("x.y.z.google.com");
164 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
166 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
167 GURL("http://" + dictionary_domain)));
169 std::string dictionary_list;
170 // HTTPS target URL should NOT advertise dictionary.
171 sdch_manager()->GetAvailDictionaryList(
172 GURL("https://" + dictionary_domain + "/test"),
173 &dictionary_list);
174 EXPECT_TRUE(dictionary_list.empty());
177 TEST_F(SdchManagerTest, CanUseHTTPSDictionaryOverHTTPSIfEnabled) {
178 std::string dictionary_domain("x.y.z.google.com");
179 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
181 EXPECT_FALSE(sdch_manager()->AddSdchDictionary(
182 dictionary_text, GURL("https://" + dictionary_domain)));
183 SdchManager::EnableSecureSchemeSupport(true);
184 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(
185 dictionary_text, GURL("https://" + dictionary_domain)));
187 GURL target_url("https://" + dictionary_domain + "/test");
188 std::string dictionary_list;
189 // HTTPS target URL should advertise dictionary if secure scheme support is
190 // enabled.
191 sdch_manager()->GetAvailDictionaryList(target_url, &dictionary_list);
192 EXPECT_FALSE(dictionary_list.empty());
194 // Dictionary should be available.
195 scoped_refptr<SdchManager::Dictionary> dictionary;
196 std::string client_hash;
197 std::string server_hash;
198 sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
199 sdch_manager()->GetVcdiffDictionary(server_hash, target_url, &dictionary);
200 EXPECT_TRUE(dictionary.get() != NULL);
203 TEST_F(SdchManagerTest, CanNotUseHTTPDictionaryOverHTTPS) {
204 std::string dictionary_domain("x.y.z.google.com");
205 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
207 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
208 GURL("http://" + dictionary_domain)));
210 GURL target_url("https://" + dictionary_domain + "/test");
211 std::string dictionary_list;
212 // HTTPS target URL should not advertise dictionary acquired over HTTP even if
213 // secure scheme support is enabled.
214 SdchManager::EnableSecureSchemeSupport(true);
215 sdch_manager()->GetAvailDictionaryList(target_url, &dictionary_list);
216 EXPECT_TRUE(dictionary_list.empty());
218 scoped_refptr<SdchManager::Dictionary> dictionary;
219 std::string client_hash;
220 std::string server_hash;
221 sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
222 sdch_manager()->GetVcdiffDictionary(server_hash, target_url, &dictionary);
223 EXPECT_TRUE(dictionary.get() == NULL);
226 TEST_F(SdchManagerTest, CanNotUseHTTPSDictionaryOverHTTP) {
227 std::string dictionary_domain("x.y.z.google.com");
228 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
230 SdchManager::EnableSecureSchemeSupport(true);
231 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
232 GURL("https://" + dictionary_domain)));
234 GURL target_url("http://" + dictionary_domain + "/test");
235 std::string dictionary_list;
236 // HTTP target URL should not advertise dictionary acquired over HTTPS even if
237 // secure scheme support is enabled.
238 sdch_manager()->GetAvailDictionaryList(target_url, &dictionary_list);
239 EXPECT_TRUE(dictionary_list.empty());
241 scoped_refptr<SdchManager::Dictionary> dictionary;
242 std::string client_hash;
243 std::string server_hash;
244 sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
245 sdch_manager()->GetVcdiffDictionary(server_hash, target_url, &dictionary);
246 EXPECT_TRUE(dictionary.get() == NULL);
249 TEST_F(SdchManagerTest, FailToSetDomainMismatchDictionary) {
250 std::string dictionary_domain("x.y.z.google.com");
251 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
253 // Fail the "domain match" requirement.
254 EXPECT_FALSE(sdch_manager()->AddSdchDictionary(dictionary_text,
255 GURL("http://y.z.google.com")));
258 TEST_F(SdchManagerTest, FailToSetDotHostPrefixDomainDictionary) {
259 std::string dictionary_domain("x.y.z.google.com");
260 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
262 // Fail the HD with D being the domain and H having a dot requirement.
263 EXPECT_FALSE(sdch_manager()->AddSdchDictionary(dictionary_text,
264 GURL("http://w.x.y.z.google.com")));
267 TEST_F(SdchManagerTest, FailToSetRepeatPrefixWithDotDictionary) {
268 // Make sure that a prefix that matches the domain postfix won't confuse
269 // the validation checks.
270 std::string dictionary_domain("www.google.com");
271 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
273 // Fail the HD with D being the domain and H having a dot requirement.
274 EXPECT_FALSE(sdch_manager()->AddSdchDictionary(dictionary_text,
275 GURL("http://www.google.com.www.google.com")));
278 TEST_F(SdchManagerTest, CanSetLeadingDotDomainDictionary) {
279 // Make sure that a prefix that matches the domain postfix won't confuse
280 // the validation checks.
281 std::string dictionary_domain(".google.com");
282 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
284 // Verify that a leading dot in the domain is acceptable, as long as the host
285 // name does not contain any dots preceding the matched domain name.
286 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
287 GURL("http://www.google.com")));
290 // Make sure the order of the tests is not helping us or confusing things.
291 // See test CanSetExactMatchDictionary above for first try.
292 TEST_F(SdchManagerTest, CanStillSetExactMatchDictionary) {
293 std::string dictionary_domain("x.y.z.google.com");
294 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
296 // Perfect match should *STILL* work.
297 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
298 GURL("http://" + dictionary_domain)));
301 // Make sure the DOS protection precludes the addition of too many dictionaries.
302 TEST_F(SdchManagerTest, TooManyDictionaries) {
303 std::string dictionary_domain(".google.com");
304 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
306 size_t count = 0;
307 while (count <= SdchManager::kMaxDictionaryCount + 1) {
308 if (!sdch_manager()->AddSdchDictionary(dictionary_text,
309 GURL("http://www.google.com")))
310 break;
312 dictionary_text += " "; // Create dictionary with different SHA signature.
313 ++count;
315 EXPECT_EQ(SdchManager::kMaxDictionaryCount, count);
318 TEST_F(SdchManagerTest, DictionaryNotTooLarge) {
319 std::string dictionary_domain(".google.com");
320 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
322 dictionary_text.append(
323 SdchManager::kMaxDictionarySize - dictionary_text.size(), ' ');
324 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(dictionary_text,
325 GURL("http://" + dictionary_domain)));
328 TEST_F(SdchManagerTest, DictionaryTooLarge) {
329 std::string dictionary_domain(".google.com");
330 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
332 dictionary_text.append(
333 SdchManager::kMaxDictionarySize + 1 - dictionary_text.size(), ' ');
334 EXPECT_FALSE(sdch_manager()->AddSdchDictionary(dictionary_text,
335 GURL("http://" + dictionary_domain)));
338 TEST_F(SdchManagerTest, PathMatch) {
339 bool (*PathMatch)(const std::string& path, const std::string& restriction) =
340 SdchManager::Dictionary::PathMatch;
341 // Perfect match is supported.
342 EXPECT_TRUE(PathMatch("/search", "/search"));
343 EXPECT_TRUE(PathMatch("/search/", "/search/"));
345 // Prefix only works if last character of restriction is a slash, or first
346 // character in path after a match is a slash. Validate each case separately.
348 // Rely on the slash in the path (not at the end of the restriction).
349 EXPECT_TRUE(PathMatch("/search/something", "/search"));
350 EXPECT_TRUE(PathMatch("/search/s", "/search"));
351 EXPECT_TRUE(PathMatch("/search/other", "/search"));
352 EXPECT_TRUE(PathMatch("/search/something", "/search"));
354 // Rely on the slash at the end of the restriction.
355 EXPECT_TRUE(PathMatch("/search/something", "/search/"));
356 EXPECT_TRUE(PathMatch("/search/s", "/search/"));
357 EXPECT_TRUE(PathMatch("/search/other", "/search/"));
358 EXPECT_TRUE(PathMatch("/search/something", "/search/"));
360 // Make sure less that sufficient prefix match is false.
361 EXPECT_FALSE(PathMatch("/sear", "/search"));
362 EXPECT_FALSE(PathMatch("/", "/search"));
363 EXPECT_FALSE(PathMatch(std::string(), "/search"));
365 // Add examples with several levels of direcories in the restriction.
366 EXPECT_FALSE(PathMatch("/search/something", "search/s"));
367 EXPECT_FALSE(PathMatch("/search/", "/search/s"));
369 // Make sure adding characters to path will also fail.
370 EXPECT_FALSE(PathMatch("/searching", "/search/"));
371 EXPECT_FALSE(PathMatch("/searching", "/search"));
373 // Make sure we're case sensitive.
374 EXPECT_FALSE(PathMatch("/ABC", "/abc"));
375 EXPECT_FALSE(PathMatch("/abc", "/ABC"));
378 // The following are only applicable while we have a latency test in the code,
379 // and can be removed when that functionality is stripped.
380 TEST_F(SdchManagerTest, LatencyTestControls) {
381 GURL url("http://www.google.com");
382 GURL url2("http://www.google2.com");
384 // First make sure we default to false.
385 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url));
386 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2));
388 // That we can set each to true.
389 sdch_manager()->SetAllowLatencyExperiment(url, true);
390 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url));
391 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2));
393 sdch_manager()->SetAllowLatencyExperiment(url2, true);
394 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url));
395 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2));
397 // And can reset them to false.
398 sdch_manager()->SetAllowLatencyExperiment(url, false);
399 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url));
400 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2));
402 sdch_manager()->SetAllowLatencyExperiment(url2, false);
403 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url));
404 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2));
407 TEST_F(SdchManagerTest, CanUseMultipleManagers) {
408 SdchManager second_manager;
410 std::string dictionary_domain_1("x.y.z.google.com");
411 std::string dictionary_domain_2("x.y.z.chromium.org");
413 std::string dictionary_text_1(NewSdchDictionary(dictionary_domain_1));
414 std::string dictionary_text_2(NewSdchDictionary(dictionary_domain_2));
416 std::string tmp_hash;
417 std::string server_hash_1;
418 std::string server_hash_2;
420 SdchManager::GenerateHash(dictionary_text_1, &tmp_hash, &server_hash_1);
421 SdchManager::GenerateHash(dictionary_text_2, &tmp_hash, &server_hash_2);
423 // Confirm that if you add directories to one manager, you
424 // can't get them from the other.
425 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(
426 dictionary_text_1, GURL("http://" + dictionary_domain_1)));
427 scoped_refptr<SdchManager::Dictionary> dictionary;
428 sdch_manager()->GetVcdiffDictionary(
429 server_hash_1,
430 GURL("http://" + dictionary_domain_1 + "/random_url"),
431 &dictionary);
432 EXPECT_TRUE(dictionary.get());
434 EXPECT_TRUE(second_manager.AddSdchDictionary(
435 dictionary_text_2, GURL("http://" + dictionary_domain_2)));
436 second_manager.GetVcdiffDictionary(
437 server_hash_2,
438 GURL("http://" + dictionary_domain_2 + "/random_url"),
439 &dictionary);
440 EXPECT_TRUE(dictionary.get());
442 sdch_manager()->GetVcdiffDictionary(
443 server_hash_2,
444 GURL("http://" + dictionary_domain_2 + "/random_url"),
445 &dictionary);
446 EXPECT_FALSE(dictionary.get());
448 second_manager.GetVcdiffDictionary(
449 server_hash_1,
450 GURL("http://" + dictionary_domain_1 + "/random_url"),
451 &dictionary);
452 EXPECT_FALSE(dictionary.get());
455 TEST_F(SdchManagerTest, HttpsCorrectlySupported) {
456 GURL url("http://www.google.com");
457 GURL secure_url("https://www.google.com");
459 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(url));
460 EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(secure_url));
462 SdchManager::EnableSecureSchemeSupport(true);
463 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(url));
464 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(secure_url));
467 TEST_F(SdchManagerTest, ClearDictionaryData) {
468 std::string dictionary_domain("x.y.z.google.com");
469 GURL blacklist_url("http://bad.chromium.org");
471 std::string dictionary_text(NewSdchDictionary(dictionary_domain));
472 std::string tmp_hash;
473 std::string server_hash;
475 SdchManager::GenerateHash(dictionary_text, &tmp_hash, &server_hash);
477 EXPECT_TRUE(sdch_manager()->AddSdchDictionary(
478 dictionary_text, GURL("http://" + dictionary_domain)));
479 scoped_refptr<SdchManager::Dictionary> dictionary;
480 sdch_manager()->GetVcdiffDictionary(
481 server_hash,
482 GURL("http://" + dictionary_domain + "/random_url"),
483 &dictionary);
484 EXPECT_TRUE(dictionary.get());
486 sdch_manager()->BlacklistDomain(GURL(blacklist_url),
487 SdchManager::MIN_PROBLEM_CODE);
488 EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(blacklist_url));
490 sdch_manager()->ClearData();
492 dictionary = NULL;
493 sdch_manager()->GetVcdiffDictionary(
494 server_hash,
495 GURL("http://" + dictionary_domain + "/random_url"),
496 &dictionary);
497 EXPECT_FALSE(dictionary.get());
498 EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(blacklist_url));
501 } // namespace net