| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <limits.h> |
| |
| #include <string> |
| |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/test/simple_test_clock.h" |
| #include "net/base/sdch_manager.h" |
| #include "net/base/sdch_observer.h" |
| #include "net/log/net_log.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| namespace net { |
| |
| //------------------------------------------------------------------------------ |
| // Provide sample data and compression results with a sample VCDIFF dictionary. |
| // Note an SDCH dictionary has extra meta-data before the VCDIFF dictionary. |
| static const char kTestVcdiffDictionary[] = "DictionaryFor" |
| "SdchCompression1SdchCompression2SdchCompression3SdchCompression\n"; |
| |
| //------------------------------------------------------------------------------ |
| |
| class MockSdchObserver : public SdchObserver { |
| public: |
| MockSdchObserver() |
| : dictionary_added_notifications_(0), |
| dictionary_removed_notifications_(0), |
| dictionary_used_notifications_(0), |
| get_dictionary_notifications_(0), |
| clear_dictionaries_notifications_(0) {} |
| |
| int dictionary_added_notifications() const { |
| return dictionary_added_notifications_; |
| } |
| int dictionary_removed_notifications() const { |
| return dictionary_removed_notifications_; |
| } |
| std::string last_server_hash() const { return last_server_hash_; } |
| int dictionary_used_notifications() const { |
| return dictionary_used_notifications_; |
| } |
| const GURL& last_dictionary_request_url() const { |
| return last_dictionary_request_url_; |
| } |
| const GURL& last_dictionary_url() const { return last_dictionary_url_; } |
| int get_dictionary_notifications() const { |
| return get_dictionary_notifications_; |
| } |
| |
| int clear_dictionary_notifications() const { |
| return clear_dictionaries_notifications_; |
| } |
| |
| // SdchObserver implementation |
| void OnDictionaryAdded(const GURL& dictionary_url, |
| const std::string& server_hash) override { |
| last_server_hash_ = server_hash; |
| last_dictionary_url_ = dictionary_url; |
| ++dictionary_added_notifications_; |
| } |
| void OnDictionaryRemoved(const std::string& server_hash) override { |
| last_server_hash_ = server_hash; |
| ++dictionary_removed_notifications_; |
| } |
| void OnDictionaryUsed(const std::string& server_hash) override { |
| last_server_hash_ = server_hash; |
| ++dictionary_used_notifications_; |
| } |
| |
| void OnGetDictionary(const GURL& request_url, |
| const GURL& dictionary_url) override { |
| ++get_dictionary_notifications_; |
| last_dictionary_request_url_ = request_url; |
| last_dictionary_url_ = dictionary_url; |
| } |
| void OnClearDictionaries() override { |
| ++clear_dictionaries_notifications_; |
| } |
| |
| private: |
| int dictionary_added_notifications_; |
| int dictionary_removed_notifications_; |
| int dictionary_used_notifications_; |
| int get_dictionary_notifications_; |
| int clear_dictionaries_notifications_; |
| |
| std::string last_server_hash_; |
| GURL last_dictionary_request_url_; |
| GURL last_dictionary_url_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MockSdchObserver); |
| }; |
| |
| class SdchManagerTest : public testing::Test { |
| protected: |
| SdchManagerTest() |
| : sdch_manager_(new SdchManager) {} |
| |
| ~SdchManagerTest() override {} |
| |
| SdchManager* sdch_manager() { return sdch_manager_.get(); } |
| |
| // Attempt to add a dictionary to the manager and probe for success or |
| // failure. |
| bool AddSdchDictionary(const std::string& dictionary_text, |
| const GURL& gurl) { |
| return sdch_manager_->AddSdchDictionary(dictionary_text, gurl, nullptr) == |
| SDCH_OK; |
| } |
| |
| private: |
| scoped_ptr<SdchManager> sdch_manager_; |
| }; |
| |
| static std::string NewSdchDictionary(const std::string& domain) { |
| std::string dictionary; |
| if (!domain.empty()) { |
| dictionary.append("Domain: "); |
| dictionary.append(domain); |
| dictionary.append("\n"); |
| } |
| dictionary.append("\n"); |
| dictionary.append(kTestVcdiffDictionary, sizeof(kTestVcdiffDictionary) - 1); |
| return dictionary; |
| } |
| |
| TEST_F(SdchManagerTest, DomainSupported) { |
| GURL google_url("http://www.google.com"); |
| |
| EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(google_url)); |
| } |
| |
| TEST_F(SdchManagerTest, DomainBlacklisting) { |
| GURL test_url("http://www.test.com"); |
| GURL google_url("http://www.google.com"); |
| |
| sdch_manager()->BlacklistDomain(test_url, SDCH_OK); |
| EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET, |
| sdch_manager()->IsInSupportedDomain(test_url)); |
| EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(google_url)); |
| |
| sdch_manager()->BlacklistDomain(google_url, SDCH_OK); |
| EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET, |
| sdch_manager()->IsInSupportedDomain(google_url)); |
| } |
| |
| TEST_F(SdchManagerTest, DomainBlacklistingCaseSensitivity) { |
| GURL test_url("http://www.TesT.com"); |
| GURL test2_url("http://www.tEst.com"); |
| |
| EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(test_url)); |
| EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(test2_url)); |
| sdch_manager()->BlacklistDomain(test_url, SDCH_OK); |
| EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET, |
| sdch_manager()->IsInSupportedDomain(test2_url)); |
| } |
| |
| TEST_F(SdchManagerTest, BlacklistingReset) { |
| GURL gurl("http://mytest.DoMain.com"); |
| std::string domain(gurl.host()); |
| |
| sdch_manager()->ClearBlacklistings(); |
| EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0); |
| EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), 0); |
| EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(gurl)); |
| } |
| |
| TEST_F(SdchManagerTest, BlacklistingSingleBlacklist) { |
| GURL gurl("http://mytest.DoMain.com"); |
| std::string domain(gurl.host()); |
| sdch_manager()->ClearBlacklistings(); |
| |
| sdch_manager()->BlacklistDomain(gurl, SDCH_OK); |
| EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 1); |
| EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), 1); |
| |
| // Check that any domain lookup reduces the blacklist counter. |
| EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET, |
| sdch_manager()->IsInSupportedDomain(gurl)); |
| EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0); |
| EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(gurl)); |
| } |
| |
| TEST_F(SdchManagerTest, BlacklistingExponential) { |
| GURL gurl("http://mytest.DoMain.com"); |
| std::string domain(gurl.host()); |
| sdch_manager()->ClearBlacklistings(); |
| |
| int exponential = 1; |
| for (int i = 1; i < 100; ++i) { |
| sdch_manager()->BlacklistDomain(gurl, SDCH_OK); |
| EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), exponential); |
| |
| EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), exponential); |
| EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET, |
| sdch_manager()->IsInSupportedDomain(gurl)); |
| EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), exponential - 1); |
| |
| // Simulate a large number of domain checks (which eventually remove the |
| // blacklisting). |
| sdch_manager()->ClearDomainBlacklisting(domain); |
| EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0); |
| EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(gurl)); |
| |
| // Predict what exponential backoff will be. |
| exponential = 1 + 2 * exponential; |
| if (exponential < 0) |
| exponential = INT_MAX; // We don't wrap. |
| } |
| } |
| |
| TEST_F(SdchManagerTest, CanSetExactMatchDictionary) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Perfect match should work. |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, |
| GURL("http://" + dictionary_domain))); |
| } |
| |
| TEST_F(SdchManagerTest, CanAdvertiseDictionaryOverHTTP) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, |
| GURL("http://" + dictionary_domain))); |
| |
| // HTTP target URL can advertise dictionary. |
| EXPECT_TRUE(sdch_manager()->GetDictionarySet( |
| GURL("http://" + dictionary_domain + "/test"))); |
| } |
| |
| TEST_F(SdchManagerTest, CanNotAdvertiseDictionaryOverHTTPS) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, |
| GURL("http://" + dictionary_domain))); |
| |
| // HTTPS target URL should NOT advertise dictionary. |
| EXPECT_FALSE(sdch_manager()->GetDictionarySet( |
| GURL("https://" + dictionary_domain + "/test"))); |
| } |
| |
| TEST_F(SdchManagerTest, CanUseHTTPSDictionaryOverHTTPSIfEnabled) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, |
| GURL("https://" + dictionary_domain))); |
| |
| GURL target_url("https://" + dictionary_domain + "/test"); |
| // HTTPS target URL should advertise dictionary if secure scheme support is |
| // enabled. |
| EXPECT_TRUE(sdch_manager()->GetDictionarySet(target_url)); |
| |
| // Dictionary should be available. |
| std::string client_hash; |
| std::string server_hash; |
| sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash); |
| SdchProblemCode problem_code; |
| scoped_ptr<SdchManager::DictionarySet> dict_set( |
| sdch_manager()->GetDictionarySetByHash( |
| target_url, server_hash, &problem_code)); |
| EXPECT_EQ(SDCH_OK, problem_code); |
| EXPECT_TRUE(dict_set.get()); |
| EXPECT_TRUE(dict_set->GetDictionaryText(server_hash)); |
| } |
| |
| TEST_F(SdchManagerTest, CanNotUseHTTPDictionaryOverHTTPS) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, |
| GURL("http://" + dictionary_domain))); |
| |
| GURL target_url("https://" + dictionary_domain + "/test"); |
| // HTTPS target URL should not advertise dictionary acquired over HTTP even if |
| // secure scheme support is enabled. |
| EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url)); |
| |
| std::string client_hash; |
| std::string server_hash; |
| sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash); |
| SdchProblemCode problem_code; |
| scoped_ptr<SdchManager::DictionarySet> dict_set( |
| sdch_manager()->GetDictionarySetByHash( |
| target_url, server_hash, &problem_code)); |
| EXPECT_FALSE(dict_set.get()); |
| EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME, problem_code); |
| } |
| |
| TEST_F(SdchManagerTest, CanNotUseHTTPSDictionaryOverHTTP) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, |
| GURL("https://" + dictionary_domain))); |
| |
| GURL target_url("http://" + dictionary_domain + "/test"); |
| // HTTP target URL should not advertise dictionary acquired over HTTPS even if |
| // secure scheme support is enabled. |
| EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url)); |
| |
| std::string client_hash; |
| std::string server_hash; |
| sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash); |
| SdchProblemCode problem_code; |
| scoped_ptr<SdchManager::DictionarySet> dict_set( |
| sdch_manager()->GetDictionarySetByHash( |
| target_url, server_hash, &problem_code)); |
| EXPECT_FALSE(dict_set.get()); |
| EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME, problem_code); |
| } |
| |
| TEST_F(SdchManagerTest, FailToSetDomainMismatchDictionary) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Fail the "domain match" requirement. |
| EXPECT_FALSE(AddSdchDictionary(dictionary_text, |
| GURL("http://y.z.google.com"))); |
| } |
| |
| TEST_F(SdchManagerTest, FailToSetDotHostPrefixDomainDictionary) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Fail the HD with D being the domain and H having a dot requirement. |
| EXPECT_FALSE(AddSdchDictionary(dictionary_text, |
| GURL("http://w.x.y.z.google.com"))); |
| } |
| |
| TEST_F(SdchManagerTest, FailToSetDotHostPrefixDomainDictionaryTrailingDot) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Fail the HD with D being the domain and H having a dot requirement. |
| EXPECT_FALSE(AddSdchDictionary(dictionary_text, |
| GURL("http://w.x.y.z.google.com."))); |
| } |
| |
| TEST_F(SdchManagerTest, FailToSetRepeatPrefixWithDotDictionary) { |
| // Make sure that a prefix that matches the domain postfix won't confuse |
| // the validation checks. |
| std::string dictionary_domain("www.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Fail the HD with D being the domain and H having a dot requirement. |
| EXPECT_FALSE(AddSdchDictionary(dictionary_text, |
| GURL("http://www.google.com.www.google.com"))); |
| } |
| |
| TEST_F(SdchManagerTest, CanSetLeadingDotDomainDictionary) { |
| // Make sure that a prefix that matches the domain postfix won't confuse |
| // the validation checks. |
| std::string dictionary_domain(".google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Verify that a leading dot in the domain is acceptable, as long as the host |
| // name does not contain any dots preceding the matched domain name. |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, GURL("http://www.google.com"))); |
| } |
| |
| TEST_F(SdchManagerTest, |
| CanSetLeadingDotDomainDictionaryFromURLWithTrailingDot) { |
| // Make sure that a prefix that matches the domain postfix won't confuse |
| // the validation checks. |
| std::string dictionary_domain(".google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Verify that a leading dot in the domain is acceptable, as long as the host |
| // name does not contain any dots preceding the matched domain name. |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, |
| GURL("http://www.google.com."))); |
| } |
| |
| TEST_F(SdchManagerTest, CannotSetLeadingDotDomainDictionary) { |
| // Make sure that a prefix that matches the domain postfix won't confuse |
| // the validation checks. |
| std::string dictionary_domain(".google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Verify that a leading dot in the domain does not affect the name containing |
| // dots failure. |
| EXPECT_FALSE(AddSdchDictionary(dictionary_text, |
| GURL("http://www.subdomain.google.com"))); |
| } |
| |
| TEST_F(SdchManagerTest, CannotSetLeadingDotDomainDictionaryTrailingDot) { |
| // Make sure that a prefix that matches the domain postfix won't confuse |
| // the validation checks. |
| std::string dictionary_domain(".google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Verify that a trailing period in the URL doesn't affect the check. |
| EXPECT_FALSE(AddSdchDictionary(dictionary_text, |
| GURL("http://www.subdomain.google.com."))); |
| } |
| |
| // Make sure the order of the tests is not helping us or confusing things. |
| // See test CanSetExactMatchDictionary above for first try. |
| TEST_F(SdchManagerTest, CanStillSetExactMatchDictionary) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| |
| // Perfect match should *STILL* work. |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, |
| GURL("http://" + dictionary_domain))); |
| } |
| |
| // The following are only applicable while we have a latency test in the code, |
| // and can be removed when that functionality is stripped. |
| TEST_F(SdchManagerTest, LatencyTestControls) { |
| GURL url("http://www.google.com"); |
| GURL url2("http://www.google2.com"); |
| |
| // First make sure we default to false. |
| EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url)); |
| EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2)); |
| |
| // That we can set each to true. |
| sdch_manager()->SetAllowLatencyExperiment(url, true); |
| EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url)); |
| EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2)); |
| |
| sdch_manager()->SetAllowLatencyExperiment(url2, true); |
| EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url)); |
| EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2)); |
| |
| // And can reset them to false. |
| sdch_manager()->SetAllowLatencyExperiment(url, false); |
| EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url)); |
| EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2)); |
| |
| sdch_manager()->SetAllowLatencyExperiment(url2, false); |
| EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url)); |
| EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2)); |
| } |
| |
| TEST_F(SdchManagerTest, CanUseMultipleManagers) { |
| SdchManager second_manager; |
| |
| std::string dictionary_domain_1("x.y.z.google.com"); |
| std::string dictionary_domain_2("x.y.z.chromium.org"); |
| |
| std::string dictionary_text_1(NewSdchDictionary(dictionary_domain_1)); |
| std::string dictionary_text_2(NewSdchDictionary(dictionary_domain_2)); |
| |
| std::string tmp_hash; |
| std::string server_hash_1; |
| std::string server_hash_2; |
| |
| SdchManager::GenerateHash(dictionary_text_1, &tmp_hash, &server_hash_1); |
| SdchManager::GenerateHash(dictionary_text_2, &tmp_hash, &server_hash_2); |
| |
| // Confirm that if you add directories to one manager, you |
| // can't get them from the other. |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text_1, |
| GURL("http://" + dictionary_domain_1))); |
| scoped_ptr<SdchManager::DictionarySet> dict_set; |
| |
| SdchProblemCode problem_code; |
| dict_set = sdch_manager()->GetDictionarySetByHash( |
| GURL("http://" + dictionary_domain_1 + "/random_url"), |
| server_hash_1, &problem_code); |
| EXPECT_TRUE(dict_set); |
| EXPECT_TRUE(dict_set->GetDictionaryText(server_hash_1)); |
| EXPECT_EQ(SDCH_OK, problem_code); |
| |
| second_manager.AddSdchDictionary( |
| dictionary_text_2, GURL("http://" + dictionary_domain_2), nullptr); |
| dict_set = second_manager.GetDictionarySetByHash( |
| GURL("http://" + dictionary_domain_2 + "/random_url"), |
| server_hash_2, &problem_code); |
| EXPECT_TRUE(dict_set); |
| EXPECT_TRUE(dict_set->GetDictionaryText(server_hash_2)); |
| EXPECT_EQ(SDCH_OK, problem_code); |
| |
| dict_set = sdch_manager()->GetDictionarySetByHash( |
| GURL("http://" + dictionary_domain_2 + "/random_url"), |
| server_hash_2, &problem_code); |
| EXPECT_FALSE(dict_set); |
| EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND, problem_code); |
| |
| dict_set = second_manager.GetDictionarySetByHash( |
| GURL("http://" + dictionary_domain_1 + "/random_url"), |
| server_hash_1, &problem_code); |
| EXPECT_FALSE(dict_set); |
| EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND, problem_code); |
| } |
| |
| TEST_F(SdchManagerTest, ClearDictionaryData) { |
| std::string dictionary_domain("x.y.z.google.com"); |
| GURL blacklist_url("http://bad.chromium.org"); |
| |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| std::string tmp_hash; |
| std::string server_hash; |
| |
| SdchManager::GenerateHash(dictionary_text, &tmp_hash, &server_hash); |
| |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, |
| GURL("http://" + dictionary_domain))); |
| |
| scoped_ptr<SdchManager::DictionarySet> dict_set; |
| |
| SdchProblemCode problem_code; |
| dict_set = sdch_manager()->GetDictionarySetByHash( |
| GURL("http://" + dictionary_domain + "/random_url"), |
| server_hash, &problem_code); |
| EXPECT_TRUE(dict_set); |
| EXPECT_TRUE(dict_set->GetDictionaryText(server_hash)); |
| EXPECT_EQ(SDCH_OK, problem_code); |
| |
| sdch_manager()->BlacklistDomain(GURL(blacklist_url), SDCH_OK); |
| EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET, |
| sdch_manager()->IsInSupportedDomain(blacklist_url)); |
| |
| sdch_manager()->ClearData(); |
| |
| dict_set = sdch_manager()->GetDictionarySetByHash( |
| GURL("http://" + dictionary_domain + "/random_url"), |
| server_hash, &problem_code); |
| EXPECT_FALSE(dict_set); |
| EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND, problem_code); |
| EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(blacklist_url)); |
| } |
| |
| TEST_F(SdchManagerTest, GetDictionaryNotification) { |
| GURL test_request_gurl(GURL("http://www.example.com/data")); |
| GURL test_dictionary_gurl(GURL("http://www.example.com/dict")); |
| MockSdchObserver observer; |
| sdch_manager()->AddObserver(&observer); |
| |
| EXPECT_EQ(0, observer.get_dictionary_notifications()); |
| sdch_manager()->OnGetDictionary(test_request_gurl, test_dictionary_gurl); |
| EXPECT_EQ(1, observer.get_dictionary_notifications()); |
| EXPECT_EQ(test_request_gurl, observer.last_dictionary_request_url()); |
| EXPECT_EQ(test_dictionary_gurl, observer.last_dictionary_url()); |
| |
| sdch_manager()->RemoveObserver(&observer); |
| sdch_manager()->OnGetDictionary(test_request_gurl, test_dictionary_gurl); |
| EXPECT_EQ(1, observer.get_dictionary_notifications()); |
| EXPECT_EQ(test_request_gurl, observer.last_dictionary_request_url()); |
| EXPECT_EQ(test_dictionary_gurl, observer.last_dictionary_url()); |
| } |
| |
| TEST_F(SdchManagerTest, ExpirationCheckedProperly) { |
| // Create an SDCH dictionary with an expiration time in the past. |
| std::string dictionary_domain("x.y.z.google.com"); |
| std::string dictionary_text(base::StringPrintf("Domain: %s\nMax-age: -1\n\n", |
| dictionary_domain.c_str())); |
| dictionary_text.append( |
| kTestVcdiffDictionary, sizeof(kTestVcdiffDictionary) - 1); |
| std::string client_hash; |
| std::string server_hash; |
| SdchManager::GenerateHash(dictionary_text, &client_hash, &server_hash); |
| GURL target_gurl("http://" + dictionary_domain); |
| AddSdchDictionary(dictionary_text, target_gurl); |
| |
| // It should be visible if looked up by hash whether expired or not. |
| SdchProblemCode problem_code; |
| scoped_ptr<SdchManager::DictionarySet> hash_set( |
| sdch_manager()->GetDictionarySetByHash( |
| target_gurl, server_hash, &problem_code).Pass()); |
| ASSERT_TRUE(hash_set); |
| ASSERT_EQ(SDCH_OK, problem_code); |
| |
| // Make sure it's not visible for advertisement, but is visible |
| // if looked up by hash. |
| EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_gurl)); |
| EXPECT_TRUE(sdch_manager()->GetDictionarySetByHash( |
| target_gurl, server_hash, &problem_code)); |
| EXPECT_EQ(SDCH_OK, problem_code); |
| } |
| |
| // Confirm dispatch of notification. |
| TEST_F(SdchManagerTest, SdchDictionaryUsed) { |
| MockSdchObserver observer; |
| sdch_manager()->AddObserver(&observer); |
| |
| EXPECT_EQ(0, observer.dictionary_used_notifications()); |
| sdch_manager()->OnDictionaryUsed("xyzzy"); |
| EXPECT_EQ(1, observer.dictionary_used_notifications()); |
| EXPECT_EQ("xyzzy", observer.last_server_hash()); |
| |
| std::string dictionary_domain("x.y.z.google.com"); |
| GURL target_gurl("http://" + dictionary_domain); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| std::string client_hash; |
| std::string server_hash; |
| SdchManager::GenerateHash(dictionary_text, &client_hash, &server_hash); |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, target_gurl)); |
| EXPECT_EQ(1, observer.dictionary_used_notifications()); |
| |
| EXPECT_TRUE(sdch_manager()->GetDictionarySet(target_gurl)); |
| EXPECT_EQ(1, observer.dictionary_used_notifications()); |
| |
| sdch_manager()->RemoveObserver(&observer); |
| EXPECT_EQ(1, observer.dictionary_used_notifications()); |
| sdch_manager()->OnDictionaryUsed("plugh"); |
| EXPECT_EQ(1, observer.dictionary_used_notifications()); |
| } |
| |
| TEST_F(SdchManagerTest, AddRemoveNotifications) { |
| MockSdchObserver observer; |
| sdch_manager()->AddObserver(&observer); |
| |
| std::string dictionary_domain("x.y.z.google.com"); |
| GURL target_gurl("http://" + dictionary_domain); |
| std::string dictionary_text(NewSdchDictionary(dictionary_domain)); |
| std::string client_hash; |
| std::string server_hash; |
| SdchManager::GenerateHash(dictionary_text, &client_hash, &server_hash); |
| EXPECT_TRUE(AddSdchDictionary(dictionary_text, target_gurl)); |
| EXPECT_EQ(1, observer.dictionary_added_notifications()); |
| EXPECT_EQ(target_gurl, observer.last_dictionary_url()); |
| EXPECT_EQ(server_hash, observer.last_server_hash()); |
| |
| EXPECT_EQ(SDCH_OK, sdch_manager()->RemoveSdchDictionary(server_hash)); |
| EXPECT_EQ(1, observer.dictionary_removed_notifications()); |
| EXPECT_EQ(server_hash, observer.last_server_hash()); |
| |
| sdch_manager()->RemoveObserver(&observer); |
| } |
| |
| } // namespace net |