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.
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/test/simple_test_clock.h"
13 #include "net/base/sdch_manager.h"
14 #include "net/base/sdch_observer.h"
15 #include "net/log/net_log.h"
16 #include "testing/gtest/include/gtest/gtest.h"
21 //------------------------------------------------------------------------------
22 // Provide sample data and compression results with a sample VCDIFF dictionary.
23 // Note an SDCH dictionary has extra meta-data before the VCDIFF dictionary.
24 static const char kTestVcdiffDictionary
[] = "DictionaryFor"
25 "SdchCompression1SdchCompression2SdchCompression3SdchCompression\n";
27 //------------------------------------------------------------------------------
29 class MockSdchObserver
: public SdchObserver
{
32 : dictionary_added_notifications_(0),
33 dictionary_removed_notifications_(0),
34 dictionary_used_notifications_(0),
35 get_dictionary_notifications_(0),
36 clear_dictionaries_notifications_(0) {}
38 int dictionary_added_notifications() const {
39 return dictionary_added_notifications_
;
41 int dictionary_removed_notifications() const {
42 return dictionary_removed_notifications_
;
44 std::string
last_server_hash() const { return last_server_hash_
; }
45 int dictionary_used_notifications() const {
46 return dictionary_used_notifications_
;
48 const GURL
& last_dictionary_request_url() const {
49 return last_dictionary_request_url_
;
51 const GURL
& last_dictionary_url() const { return last_dictionary_url_
; }
52 int get_dictionary_notifications() const {
53 return get_dictionary_notifications_
;
56 int clear_dictionary_notifications() const {
57 return clear_dictionaries_notifications_
;
60 // SdchObserver implementation
61 void OnDictionaryAdded(const GURL
& dictionary_url
,
62 const std::string
& server_hash
) override
{
63 last_server_hash_
= server_hash
;
64 last_dictionary_url_
= dictionary_url
;
65 ++dictionary_added_notifications_
;
67 void OnDictionaryRemoved(const std::string
& server_hash
) override
{
68 last_server_hash_
= server_hash
;
69 ++dictionary_removed_notifications_
;
71 void OnDictionaryUsed(const std::string
& server_hash
) override
{
72 last_server_hash_
= server_hash
;
73 ++dictionary_used_notifications_
;
76 void OnGetDictionary(const GURL
& request_url
,
77 const GURL
& dictionary_url
) override
{
78 ++get_dictionary_notifications_
;
79 last_dictionary_request_url_
= request_url
;
80 last_dictionary_url_
= dictionary_url
;
82 void OnClearDictionaries() override
{
83 ++clear_dictionaries_notifications_
;
87 int dictionary_added_notifications_
;
88 int dictionary_removed_notifications_
;
89 int dictionary_used_notifications_
;
90 int get_dictionary_notifications_
;
91 int clear_dictionaries_notifications_
;
93 std::string last_server_hash_
;
94 GURL last_dictionary_request_url_
;
95 GURL last_dictionary_url_
;
97 DISALLOW_COPY_AND_ASSIGN(MockSdchObserver
);
100 class SdchManagerTest
: public testing::Test
{
103 : sdch_manager_(new SdchManager
) {}
105 ~SdchManagerTest() override
{}
107 SdchManager
* sdch_manager() { return sdch_manager_
.get(); }
109 // Attempt to add a dictionary to the manager and probe for success or
111 bool AddSdchDictionary(const std::string
& dictionary_text
,
113 return sdch_manager_
->AddSdchDictionary(dictionary_text
, gurl
, nullptr) ==
118 scoped_ptr
<SdchManager
> sdch_manager_
;
121 static std::string
NewSdchDictionary(const std::string
& domain
) {
122 std::string dictionary
;
123 if (!domain
.empty()) {
124 dictionary
.append("Domain: ");
125 dictionary
.append(domain
);
126 dictionary
.append("\n");
128 dictionary
.append("\n");
129 dictionary
.append(kTestVcdiffDictionary
, sizeof(kTestVcdiffDictionary
) - 1);
133 TEST_F(SdchManagerTest
, DomainSupported
) {
134 GURL
google_url("http://www.google.com");
136 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(google_url
));
139 TEST_F(SdchManagerTest
, DomainBlacklisting
) {
140 GURL
test_url("http://www.test.com");
141 GURL
google_url("http://www.google.com");
143 sdch_manager()->BlacklistDomain(test_url
, SDCH_OK
);
144 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
145 sdch_manager()->IsInSupportedDomain(test_url
));
146 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(google_url
));
148 sdch_manager()->BlacklistDomain(google_url
, SDCH_OK
);
149 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
150 sdch_manager()->IsInSupportedDomain(google_url
));
153 TEST_F(SdchManagerTest
, DomainBlacklistingCaseSensitivity
) {
154 GURL
test_url("http://www.TesT.com");
155 GURL
test2_url("http://www.tEst.com");
157 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(test_url
));
158 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(test2_url
));
159 sdch_manager()->BlacklistDomain(test_url
, SDCH_OK
);
160 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
161 sdch_manager()->IsInSupportedDomain(test2_url
));
164 TEST_F(SdchManagerTest
, BlacklistingReset
) {
165 GURL
gurl("http://mytest.DoMain.com");
166 std::string
domain(gurl
.host());
168 sdch_manager()->ClearBlacklistings();
169 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), 0);
170 EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain
), 0);
171 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(gurl
));
174 TEST_F(SdchManagerTest
, BlacklistingSingleBlacklist
) {
175 GURL
gurl("http://mytest.DoMain.com");
176 std::string
domain(gurl
.host());
177 sdch_manager()->ClearBlacklistings();
179 sdch_manager()->BlacklistDomain(gurl
, SDCH_OK
);
180 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), 1);
181 EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain
), 1);
183 // Check that any domain lookup reduces the blacklist counter.
184 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
185 sdch_manager()->IsInSupportedDomain(gurl
));
186 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), 0);
187 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(gurl
));
190 TEST_F(SdchManagerTest
, BlacklistingExponential
) {
191 GURL
gurl("http://mytest.DoMain.com");
192 std::string
domain(gurl
.host());
193 sdch_manager()->ClearBlacklistings();
196 for (int i
= 1; i
< 100; ++i
) {
197 sdch_manager()->BlacklistDomain(gurl
, SDCH_OK
);
198 EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain
), exponential
);
200 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), exponential
);
201 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
202 sdch_manager()->IsInSupportedDomain(gurl
));
203 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), exponential
- 1);
205 // Simulate a large number of domain checks (which eventually remove the
207 sdch_manager()->ClearDomainBlacklisting(domain
);
208 EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain
), 0);
209 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(gurl
));
211 // Predict what exponential backoff will be.
212 exponential
= 1 + 2 * exponential
;
214 exponential
= INT_MAX
; // We don't wrap.
218 TEST_F(SdchManagerTest
, CanSetExactMatchDictionary
) {
219 std::string
dictionary_domain("x.y.z.google.com");
220 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
222 // Perfect match should work.
223 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
224 GURL("http://" + dictionary_domain
)));
227 TEST_F(SdchManagerTest
, CanAdvertiseDictionaryOverHTTP
) {
228 std::string
dictionary_domain("x.y.z.google.com");
229 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
231 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
232 GURL("http://" + dictionary_domain
)));
234 // HTTP target URL can advertise dictionary.
235 EXPECT_TRUE(sdch_manager()->GetDictionarySet(
236 GURL("http://" + dictionary_domain
+ "/test")));
239 TEST_F(SdchManagerTest
, CanNotAdvertiseDictionaryOverHTTPS
) {
240 std::string
dictionary_domain("x.y.z.google.com");
241 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
243 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
244 GURL("http://" + dictionary_domain
)));
246 // HTTPS target URL should NOT advertise dictionary.
247 EXPECT_FALSE(sdch_manager()->GetDictionarySet(
248 GURL("https://" + dictionary_domain
+ "/test")));
251 TEST_F(SdchManagerTest
, CanUseHTTPSDictionaryOverHTTPSIfEnabled
) {
252 std::string
dictionary_domain("x.y.z.google.com");
253 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
255 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
256 GURL("https://" + dictionary_domain
)));
258 GURL
target_url("https://" + dictionary_domain
+ "/test");
259 // HTTPS target URL should advertise dictionary if secure scheme support is
261 EXPECT_TRUE(sdch_manager()->GetDictionarySet(target_url
));
263 // Dictionary should be available.
264 std::string client_hash
;
265 std::string server_hash
;
266 sdch_manager()->GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
267 SdchProblemCode problem_code
;
268 scoped_ptr
<SdchManager::DictionarySet
> dict_set(
269 sdch_manager()->GetDictionarySetByHash(
270 target_url
, server_hash
, &problem_code
));
271 EXPECT_EQ(SDCH_OK
, problem_code
);
272 EXPECT_TRUE(dict_set
.get());
273 EXPECT_TRUE(dict_set
->GetDictionaryText(server_hash
));
276 TEST_F(SdchManagerTest
, CanNotUseHTTPDictionaryOverHTTPS
) {
277 std::string
dictionary_domain("x.y.z.google.com");
278 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
280 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
281 GURL("http://" + dictionary_domain
)));
283 GURL
target_url("https://" + dictionary_domain
+ "/test");
284 // HTTPS target URL should not advertise dictionary acquired over HTTP even if
285 // secure scheme support is enabled.
286 EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url
));
288 std::string client_hash
;
289 std::string server_hash
;
290 sdch_manager()->GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
291 SdchProblemCode problem_code
;
292 scoped_ptr
<SdchManager::DictionarySet
> dict_set(
293 sdch_manager()->GetDictionarySetByHash(
294 target_url
, server_hash
, &problem_code
));
295 EXPECT_FALSE(dict_set
.get());
296 EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME
, problem_code
);
299 TEST_F(SdchManagerTest
, CanNotUseHTTPSDictionaryOverHTTP
) {
300 std::string
dictionary_domain("x.y.z.google.com");
301 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
303 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
304 GURL("https://" + dictionary_domain
)));
306 GURL
target_url("http://" + dictionary_domain
+ "/test");
307 // HTTP target URL should not advertise dictionary acquired over HTTPS even if
308 // secure scheme support is enabled.
309 EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url
));
311 std::string client_hash
;
312 std::string server_hash
;
313 sdch_manager()->GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
314 SdchProblemCode problem_code
;
315 scoped_ptr
<SdchManager::DictionarySet
> dict_set(
316 sdch_manager()->GetDictionarySetByHash(
317 target_url
, server_hash
, &problem_code
));
318 EXPECT_FALSE(dict_set
.get());
319 EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME
, problem_code
);
322 TEST_F(SdchManagerTest
, FailToSetDomainMismatchDictionary
) {
323 std::string
dictionary_domain("x.y.z.google.com");
324 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
326 // Fail the "domain match" requirement.
327 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
328 GURL("http://y.z.google.com")));
331 TEST_F(SdchManagerTest
, FailToSetDotHostPrefixDomainDictionary
) {
332 std::string
dictionary_domain("x.y.z.google.com");
333 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
335 // Fail the HD with D being the domain and H having a dot requirement.
336 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
337 GURL("http://w.x.y.z.google.com")));
340 TEST_F(SdchManagerTest
, FailToSetDotHostPrefixDomainDictionaryTrailingDot
) {
341 std::string
dictionary_domain("x.y.z.google.com");
342 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
344 // Fail the HD with D being the domain and H having a dot requirement.
345 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
346 GURL("http://w.x.y.z.google.com.")));
349 TEST_F(SdchManagerTest
, FailToSetRepeatPrefixWithDotDictionary
) {
350 // Make sure that a prefix that matches the domain postfix won't confuse
351 // the validation checks.
352 std::string
dictionary_domain("www.google.com");
353 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
355 // Fail the HD with D being the domain and H having a dot requirement.
356 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
357 GURL("http://www.google.com.www.google.com")));
360 TEST_F(SdchManagerTest
, CanSetLeadingDotDomainDictionary
) {
361 // Make sure that a prefix that matches the domain postfix won't confuse
362 // the validation checks.
363 std::string
dictionary_domain(".google.com");
364 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
366 // Verify that a leading dot in the domain is acceptable, as long as the host
367 // name does not contain any dots preceding the matched domain name.
368 EXPECT_TRUE(AddSdchDictionary(dictionary_text
, GURL("http://www.google.com")));
371 TEST_F(SdchManagerTest
,
372 CanSetLeadingDotDomainDictionaryFromURLWithTrailingDot
) {
373 // Make sure that a prefix that matches the domain postfix won't confuse
374 // the validation checks.
375 std::string
dictionary_domain(".google.com");
376 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
378 // Verify that a leading dot in the domain is acceptable, as long as the host
379 // name does not contain any dots preceding the matched domain name.
380 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
381 GURL("http://www.google.com.")));
384 TEST_F(SdchManagerTest
, CannotSetLeadingDotDomainDictionary
) {
385 // Make sure that a prefix that matches the domain postfix won't confuse
386 // the validation checks.
387 std::string
dictionary_domain(".google.com");
388 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
390 // Verify that a leading dot in the domain does not affect the name containing
392 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
393 GURL("http://www.subdomain.google.com")));
396 TEST_F(SdchManagerTest
, CannotSetLeadingDotDomainDictionaryTrailingDot
) {
397 // Make sure that a prefix that matches the domain postfix won't confuse
398 // the validation checks.
399 std::string
dictionary_domain(".google.com");
400 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
402 // Verify that a trailing period in the URL doesn't affect the check.
403 EXPECT_FALSE(AddSdchDictionary(dictionary_text
,
404 GURL("http://www.subdomain.google.com.")));
407 // Make sure the order of the tests is not helping us or confusing things.
408 // See test CanSetExactMatchDictionary above for first try.
409 TEST_F(SdchManagerTest
, CanStillSetExactMatchDictionary
) {
410 std::string
dictionary_domain("x.y.z.google.com");
411 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
413 // Perfect match should *STILL* work.
414 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
415 GURL("http://" + dictionary_domain
)));
418 // The following are only applicable while we have a latency test in the code,
419 // and can be removed when that functionality is stripped.
420 TEST_F(SdchManagerTest
, LatencyTestControls
) {
421 GURL
url("http://www.google.com");
422 GURL
url2("http://www.google2.com");
424 // First make sure we default to false.
425 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url
));
426 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2
));
428 // That we can set each to true.
429 sdch_manager()->SetAllowLatencyExperiment(url
, true);
430 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url
));
431 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2
));
433 sdch_manager()->SetAllowLatencyExperiment(url2
, true);
434 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url
));
435 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2
));
437 // And can reset them to false.
438 sdch_manager()->SetAllowLatencyExperiment(url
, false);
439 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url
));
440 EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2
));
442 sdch_manager()->SetAllowLatencyExperiment(url2
, false);
443 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url
));
444 EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2
));
447 TEST_F(SdchManagerTest
, CanUseMultipleManagers
) {
448 SdchManager second_manager
;
450 std::string
dictionary_domain_1("x.y.z.google.com");
451 std::string
dictionary_domain_2("x.y.z.chromium.org");
453 std::string
dictionary_text_1(NewSdchDictionary(dictionary_domain_1
));
454 std::string
dictionary_text_2(NewSdchDictionary(dictionary_domain_2
));
456 std::string tmp_hash
;
457 std::string server_hash_1
;
458 std::string server_hash_2
;
460 SdchManager::GenerateHash(dictionary_text_1
, &tmp_hash
, &server_hash_1
);
461 SdchManager::GenerateHash(dictionary_text_2
, &tmp_hash
, &server_hash_2
);
463 // Confirm that if you add directories to one manager, you
464 // can't get them from the other.
465 EXPECT_TRUE(AddSdchDictionary(dictionary_text_1
,
466 GURL("http://" + dictionary_domain_1
)));
467 scoped_ptr
<SdchManager::DictionarySet
> dict_set
;
469 SdchProblemCode problem_code
;
470 dict_set
= sdch_manager()->GetDictionarySetByHash(
471 GURL("http://" + dictionary_domain_1
+ "/random_url"),
472 server_hash_1
, &problem_code
);
473 EXPECT_TRUE(dict_set
);
474 EXPECT_TRUE(dict_set
->GetDictionaryText(server_hash_1
));
475 EXPECT_EQ(SDCH_OK
, problem_code
);
477 second_manager
.AddSdchDictionary(
478 dictionary_text_2
, GURL("http://" + dictionary_domain_2
), nullptr);
479 dict_set
= second_manager
.GetDictionarySetByHash(
480 GURL("http://" + dictionary_domain_2
+ "/random_url"),
481 server_hash_2
, &problem_code
);
482 EXPECT_TRUE(dict_set
);
483 EXPECT_TRUE(dict_set
->GetDictionaryText(server_hash_2
));
484 EXPECT_EQ(SDCH_OK
, problem_code
);
486 dict_set
= sdch_manager()->GetDictionarySetByHash(
487 GURL("http://" + dictionary_domain_2
+ "/random_url"),
488 server_hash_2
, &problem_code
);
489 EXPECT_FALSE(dict_set
);
490 EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND
, problem_code
);
492 dict_set
= second_manager
.GetDictionarySetByHash(
493 GURL("http://" + dictionary_domain_1
+ "/random_url"),
494 server_hash_1
, &problem_code
);
495 EXPECT_FALSE(dict_set
);
496 EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND
, problem_code
);
499 TEST_F(SdchManagerTest
, ClearDictionaryData
) {
500 std::string
dictionary_domain("x.y.z.google.com");
501 GURL
blacklist_url("http://bad.chromium.org");
503 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
504 std::string tmp_hash
;
505 std::string server_hash
;
507 SdchManager::GenerateHash(dictionary_text
, &tmp_hash
, &server_hash
);
509 EXPECT_TRUE(AddSdchDictionary(dictionary_text
,
510 GURL("http://" + dictionary_domain
)));
512 scoped_ptr
<SdchManager::DictionarySet
> dict_set
;
514 SdchProblemCode problem_code
;
515 dict_set
= sdch_manager()->GetDictionarySetByHash(
516 GURL("http://" + dictionary_domain
+ "/random_url"),
517 server_hash
, &problem_code
);
518 EXPECT_TRUE(dict_set
);
519 EXPECT_TRUE(dict_set
->GetDictionaryText(server_hash
));
520 EXPECT_EQ(SDCH_OK
, problem_code
);
522 sdch_manager()->BlacklistDomain(GURL(blacklist_url
), SDCH_OK
);
523 EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET
,
524 sdch_manager()->IsInSupportedDomain(blacklist_url
));
526 sdch_manager()->ClearData();
528 dict_set
= sdch_manager()->GetDictionarySetByHash(
529 GURL("http://" + dictionary_domain
+ "/random_url"),
530 server_hash
, &problem_code
);
531 EXPECT_FALSE(dict_set
);
532 EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND
, problem_code
);
533 EXPECT_EQ(SDCH_OK
, sdch_manager()->IsInSupportedDomain(blacklist_url
));
536 TEST_F(SdchManagerTest
, GetDictionaryNotification
) {
537 GURL
test_request_gurl(GURL("http://www.example.com/data"));
538 GURL
test_dictionary_gurl(GURL("http://www.example.com/dict"));
539 MockSdchObserver observer
;
540 sdch_manager()->AddObserver(&observer
);
542 EXPECT_EQ(0, observer
.get_dictionary_notifications());
543 sdch_manager()->OnGetDictionary(test_request_gurl
, test_dictionary_gurl
);
544 EXPECT_EQ(1, observer
.get_dictionary_notifications());
545 EXPECT_EQ(test_request_gurl
, observer
.last_dictionary_request_url());
546 EXPECT_EQ(test_dictionary_gurl
, observer
.last_dictionary_url());
548 sdch_manager()->RemoveObserver(&observer
);
549 sdch_manager()->OnGetDictionary(test_request_gurl
, test_dictionary_gurl
);
550 EXPECT_EQ(1, observer
.get_dictionary_notifications());
551 EXPECT_EQ(test_request_gurl
, observer
.last_dictionary_request_url());
552 EXPECT_EQ(test_dictionary_gurl
, observer
.last_dictionary_url());
555 TEST_F(SdchManagerTest
, ExpirationCheckedProperly
) {
556 // Create an SDCH dictionary with an expiration time in the past.
557 std::string
dictionary_domain("x.y.z.google.com");
558 std::string
dictionary_text(base::StringPrintf("Domain: %s\nMax-age: -1\n\n",
559 dictionary_domain
.c_str()));
560 dictionary_text
.append(
561 kTestVcdiffDictionary
, sizeof(kTestVcdiffDictionary
) - 1);
562 std::string client_hash
;
563 std::string server_hash
;
564 SdchManager::GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
565 GURL
target_gurl("http://" + dictionary_domain
);
566 AddSdchDictionary(dictionary_text
, target_gurl
);
568 // It should be visible if looked up by hash whether expired or not.
569 SdchProblemCode problem_code
;
570 scoped_ptr
<SdchManager::DictionarySet
> hash_set(
571 sdch_manager()->GetDictionarySetByHash(
572 target_gurl
, server_hash
, &problem_code
).Pass());
573 ASSERT_TRUE(hash_set
);
574 ASSERT_EQ(SDCH_OK
, problem_code
);
576 // Make sure it's not visible for advertisement, but is visible
577 // if looked up by hash.
578 EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_gurl
));
579 EXPECT_TRUE(sdch_manager()->GetDictionarySetByHash(
580 target_gurl
, server_hash
, &problem_code
));
581 EXPECT_EQ(SDCH_OK
, problem_code
);
584 // Confirm dispatch of notification.
585 TEST_F(SdchManagerTest
, SdchDictionaryUsed
) {
586 MockSdchObserver observer
;
587 sdch_manager()->AddObserver(&observer
);
589 EXPECT_EQ(0, observer
.dictionary_used_notifications());
590 sdch_manager()->OnDictionaryUsed("xyzzy");
591 EXPECT_EQ(1, observer
.dictionary_used_notifications());
592 EXPECT_EQ("xyzzy", observer
.last_server_hash());
594 std::string
dictionary_domain("x.y.z.google.com");
595 GURL
target_gurl("http://" + dictionary_domain
);
596 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
597 std::string client_hash
;
598 std::string server_hash
;
599 SdchManager::GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
600 EXPECT_TRUE(AddSdchDictionary(dictionary_text
, target_gurl
));
601 EXPECT_EQ(1, observer
.dictionary_used_notifications());
603 EXPECT_TRUE(sdch_manager()->GetDictionarySet(target_gurl
));
604 EXPECT_EQ(1, observer
.dictionary_used_notifications());
606 sdch_manager()->RemoveObserver(&observer
);
607 EXPECT_EQ(1, observer
.dictionary_used_notifications());
608 sdch_manager()->OnDictionaryUsed("plugh");
609 EXPECT_EQ(1, observer
.dictionary_used_notifications());
612 TEST_F(SdchManagerTest
, AddRemoveNotifications
) {
613 MockSdchObserver observer
;
614 sdch_manager()->AddObserver(&observer
);
616 std::string
dictionary_domain("x.y.z.google.com");
617 GURL
target_gurl("http://" + dictionary_domain
);
618 std::string
dictionary_text(NewSdchDictionary(dictionary_domain
));
619 std::string client_hash
;
620 std::string server_hash
;
621 SdchManager::GenerateHash(dictionary_text
, &client_hash
, &server_hash
);
622 EXPECT_TRUE(AddSdchDictionary(dictionary_text
, target_gurl
));
623 EXPECT_EQ(1, observer
.dictionary_added_notifications());
624 EXPECT_EQ(target_gurl
, observer
.last_dictionary_url());
625 EXPECT_EQ(server_hash
, observer
.last_server_hash());
627 EXPECT_EQ(SDCH_OK
, sdch_manager()->RemoveSdchDictionary(server_hash
));
628 EXPECT_EQ(1, observer
.dictionary_removed_notifications());
629 EXPECT_EQ(server_hash
, observer
.last_server_hash());
631 sdch_manager()->RemoveObserver(&observer
);