| Index: components/safe_browsing_db/v4_get_hash_protocol_manager_unittest.cc
|
| diff --git a/components/safe_browsing_db/v4_get_hash_protocol_manager_unittest.cc b/components/safe_browsing_db/v4_get_hash_protocol_manager_unittest.cc
|
| index edf130ac9dc24a607fddf176e6e960b100cdfe42..e558fc5ae03eeddf7678f467ab26aaa53e5afeab 100644
|
| --- a/components/safe_browsing_db/v4_get_hash_protocol_manager_unittest.cc
|
| +++ b/components/safe_browsing_db/v4_get_hash_protocol_manager_unittest.cc
|
| @@ -9,6 +9,7 @@
|
|
|
| #include "base/base64.h"
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/run_loop.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/test/simple_test_clock.h"
|
| #include "base/time/time.h"
|
| @@ -34,7 +35,7 @@ const char kKeyParam[] = "test_key_param";
|
|
|
| namespace safe_browsing {
|
|
|
| -class SafeBrowsingV4GetHashProtocolManagerTest : public testing::Test {
|
| +class V4GetHashProtocolManagerTest : public testing::Test {
|
| protected:
|
| std::unique_ptr<V4GetHashProtocolManager> CreateProtocolManager() {
|
| V4ProtocolConfig config;
|
| @@ -89,9 +90,10 @@ void ValidateGetV4HashResults(
|
| EXPECT_EQ(expected.metadata, actual.metadata);
|
| EXPECT_EQ(expected.cache_expire_after, actual.cache_expire_after);
|
| }
|
| +
|
| }
|
|
|
| -TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| +TEST_F(V4GetHashProtocolManagerTest,
|
| TestGetHashErrorHandlingNetwork) {
|
| net::TestURLFetcherFactory factory;
|
| std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
| @@ -118,7 +120,7 @@ TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| EXPECT_EQ(1ul, pm->gethash_back_off_mult_);
|
| }
|
|
|
| -TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| +TEST_F(V4GetHashProtocolManagerTest,
|
| TestGetHashErrorHandlingResponseCode) {
|
| net::TestURLFetcherFactory factory;
|
| std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
| @@ -144,14 +146,14 @@ TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| EXPECT_EQ(1ul, pm->gethash_back_off_mult_);
|
| }
|
|
|
| -TEST_F(SafeBrowsingV4GetHashProtocolManagerTest, TestGetHashErrorHandlingOK) {
|
| +TEST_F(V4GetHashProtocolManagerTest, TestGetHashErrorHandlingOK) {
|
| net::TestURLFetcherFactory factory;
|
| std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
|
|
| base::Time now = base::Time::UnixEpoch();
|
| SetTestClock(now, pm.get());
|
|
|
| - std::vector<SBPrefix> prefixes;
|
| + std::vector<SBPrefix> prefixes = {2877448190};
|
| std::vector<SBFullHashResult> expected_full_hashes;
|
| SBFullHashResult hash_result;
|
| hash_result.hash = SBFullHashForString("Everything's shiny, Cap'n.");
|
| @@ -174,9 +176,19 @@ TEST_F(SafeBrowsingV4GetHashProtocolManagerTest, TestGetHashErrorHandlingOK) {
|
| // No error, back off multiplier is unchanged.
|
| EXPECT_EQ(0ul, pm->gethash_error_count_);
|
| EXPECT_EQ(1ul, pm->gethash_back_off_mult_);
|
| +
|
| + // Verify the state of the cache.
|
| + const V4GetHashProtocolManager::PrefixToFullHashResultsMap& cache =
|
| + pm->v4_full_hash_cache()->at(SB_THREAT_TYPE_API_ABUSE);
|
| + // Check the cache.
|
| + EXPECT_EQ(1u, cache.size());
|
| + EXPECT_EQ(1u, cache.count(prefixes[0]));
|
| + const SBCachedFullHashResult& cached_result = cache.at(prefixes[0]);
|
| + EXPECT_EQ(1u, cached_result.full_hashes.size());
|
| + EXPECT_TRUE(SBFullHashEqual(SBFullHashForString("Everything's shiny, Cap'n."), cached_result.full_hashes[0].hash));
|
| }
|
|
|
| -TEST_F(SafeBrowsingV4GetHashProtocolManagerTest, TestGetHashRequest) {
|
| +TEST_F(V4GetHashProtocolManagerTest, TestGetHashRequest) {
|
| std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
|
|
| FindFullHashesRequest req;
|
| @@ -211,7 +223,7 @@ TEST_F(SafeBrowsingV4GetHashProtocolManagerTest, TestGetHashRequest) {
|
| EXPECT_EQ(req_base64, pm->GetHashRequest(prefixes, platform, API_ABUSE));
|
| }
|
|
|
| -TEST_F(SafeBrowsingV4GetHashProtocolManagerTest, TestParseHashResponse) {
|
| +TEST_F(V4GetHashProtocolManagerTest, TestParseHashResponse) {
|
| std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
|
|
| base::Time now = base::Time::UnixEpoch();
|
| @@ -253,7 +265,7 @@ TEST_F(SafeBrowsingV4GetHashProtocolManagerTest, TestParseHashResponse) {
|
| }
|
|
|
| // Adds an entry with an ignored ThreatEntryType.
|
| -TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| +TEST_F(V4GetHashProtocolManagerTest,
|
| TestParseHashResponseWrongThreatEntryType) {
|
| std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
|
|
| @@ -278,7 +290,7 @@ TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| }
|
|
|
| // Adds entries with a ThreatPatternType metadata.
|
| -TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| +TEST_F(V4GetHashProtocolManagerTest,
|
| TestParseHashThreatPatternType) {
|
| std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
|
|
| @@ -357,7 +369,7 @@ TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| }
|
|
|
| // Adds metadata with a key value that is not "permission".
|
| -TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| +TEST_F(V4GetHashProtocolManagerTest,
|
| TestParseHashResponseNonPermissionMetadata) {
|
| std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
|
|
| @@ -389,7 +401,7 @@ TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| EXPECT_EQ(0ul, full_hashes.size());
|
| }
|
|
|
| -TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| +TEST_F(V4GetHashProtocolManagerTest,
|
| TestParseHashResponseInconsistentThreatTypes) {
|
| std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
|
|
| @@ -417,4 +429,204 @@ TEST_F(SafeBrowsingV4GetHashProtocolManagerTest,
|
| EXPECT_FALSE(pm->ParseHashResponse(res_data, &full_hashes, &cache_expire));
|
| }
|
|
|
| +// Checks that results are looked up correctly in the cache.
|
| +TEST_F(V4GetHashProtocolManagerTest, GetCachedResults) {
|
| + base::Time now = base::Time::UnixEpoch();
|
| + std::vector<SBFullHash> full_hashes;
|
| + SBFullHash full_hash = SBFullHashForString("example.com/");
|
| + full_hashes.push_back(full_hash);
|
| + std::vector<SBFullHashResult> cached_results;
|
| + std::vector<SBPrefix> prefixes;
|
| + std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
| + pm->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
|
| + full_hashes, now, &prefixes, &cached_results);
|
| +
|
| + // The cache is empty.
|
| + EXPECT_TRUE(cached_results.empty());
|
| + EXPECT_EQ(1ul, prefixes.size());
|
| + EXPECT_EQ(full_hash.prefix, prefixes[0]);
|
| +
|
| + // Prefix has a cache entry but full hash is not there.
|
| + SBCachedFullHashResult& entry = pm->
|
| + v4_full_hash_cache()->at(SB_THREAT_TYPE_API_ABUSE)[full_hash.prefix] =
|
| + SBCachedFullHashResult(now + base::TimeDelta::FromMinutes(5));
|
| + pm->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
|
| + full_hashes, now, &prefixes, &cached_results);
|
| +
|
| + EXPECT_TRUE(prefixes.empty());
|
| + EXPECT_TRUE(cached_results.empty());
|
| +
|
| + // Expired negative cache entry.
|
| + entry.expire_after = now - base::TimeDelta::FromMinutes(5);
|
| + pm->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
|
| + full_hashes, now, &prefixes, &cached_results);
|
| +
|
| + EXPECT_TRUE(cached_results.empty());
|
| + EXPECT_EQ(1ul, prefixes.size());
|
| + EXPECT_EQ(full_hash.prefix, prefixes[0]);
|
| +
|
| + // Now put the full hash in the cache.
|
| + SBFullHashResult full_hash_result;
|
| + full_hash_result.hash = full_hash;
|
| + full_hash_result.cache_expire_after = now + base::TimeDelta::FromMinutes(3);
|
| + entry.full_hashes.push_back(full_hash_result);
|
| + pm->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
|
| + full_hashes, now, &prefixes, &cached_results);
|
| +
|
| + EXPECT_TRUE(prefixes.empty());
|
| + EXPECT_EQ(1ul, cached_results.size());
|
| + EXPECT_TRUE(SBFullHashEqual(full_hash, cached_results[0].hash));
|
| +
|
| + // Expired full hash in cache.
|
| + entry.full_hashes.clear();
|
| + full_hash_result.cache_expire_after = now - base::TimeDelta::FromMinutes(3);
|
| + entry.full_hashes.push_back(full_hash_result);
|
| + pm->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
|
| + full_hashes, now, &prefixes, &cached_results);
|
| +
|
| + EXPECT_TRUE(cached_results.empty());
|
| + EXPECT_EQ(1ul, prefixes.size());
|
| + EXPECT_EQ(full_hash.prefix, prefixes[0]);
|
| +}
|
| +/*
|
| +// Checks that the cached results and request results are merged.
|
| +TEST_F(V4GetHashProtocolManagerTest, CachedResultsMerged) {
|
| + //TestClient client;
|
| + const GURL url("https://www.example.com/more");
|
| + std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
| + // Set now to max time so the cache expire times are in the future.
|
| + SBFullHash full_hash = SBFullHashForString("example.com/");
|
| + SBFullHashResult full_hash_result;
|
| + full_hash_result.hash = full_hash;
|
| + full_hash_result.metadata.api_permissions.insert("GEOLOCATION");
|
| + full_hash_result.cache_expire_after = base::Time::Max();
|
| + //pm->AddGetFullHashResponse(full_hash_result);
|
| + //pm->SetNegativeCacheDurationMins(base::Time::Max(), 0);
|
| +
|
| + EXPECT_TRUE(pm->v4_full_hash_cache()->empty());
|
| + EXPECT_FALSE(pm->CheckApiBlacklistUrl(url, &client));
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + EXPECT_TRUE(client.callback_invoked());
|
| + const std::set<std::string>& permissions = client.GetBlockedPermissions();
|
| + EXPECT_EQ(1ul, permissions.size());
|
| + EXPECT_EQ(1ul, permissions.count("GEOLOCATION"));
|
| +
|
| + // The results should be cached, so remove them from the protocol manager
|
| + // response.
|
| + //TestClient client2;
|
| + //pm->ClearFullHashResponse();
|
| + //pm->SetNegativeCacheDurationMins(base::Time(), 0);
|
| + EXPECT_FALSE(pm->CheckApiBlacklistUrl(url, &client2));
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + EXPECT_TRUE(client2.callback_invoked());
|
| + const std::set<std::string>& permissions2 =
|
| + client2.GetBlockedPermissions();
|
| + EXPECT_EQ(1ul, permissions2.size());
|
| + EXPECT_EQ(1ul, permissions2.count("GEOLOCATION"));
|
| +
|
| + // Add a different result to the protocol manager response and ensure it is
|
| + // merged with the cached result in the metadata.
|
| + //TestClient client3;
|
| + const GURL url2("https://m.example.com/more");
|
| + full_hash_result.hash = SBFullHashForString("m.example.com/");
|
| + full_hash_result.metadata.api_permissions.insert("NOTIFICATIONS");
|
| + //pm->AddGetFullHashResponse(full_hash_result);
|
| + //pm->SetNegativeCacheDurationMins(base::Time::Max(), 0);
|
| + EXPECT_FALSE(pm->CheckApiBlacklistUrl(url2, &client3));
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + EXPECT_TRUE(client3.callback_invoked());
|
| + const std::set<std::string>& permissions3 =
|
| + client3.GetBlockedPermissions();
|
| + EXPECT_EQ(2ul, permissions3.size());
|
| + EXPECT_EQ(1ul, permissions3.count("GEOLOCATION"));
|
| + EXPECT_EQ(1ul, permissions3.count("NOTIFICATIONS"));
|
| +}
|
| +
|
| +TEST_F(V4GetHashProtocolManagerTest, CachedResultsAreEvicted) {
|
| + base::Time epoch = base::Time::UnixEpoch();
|
| + SBFullHashResult full_hash_result;
|
| + full_hash_result.hash = SBFullHashForString("example.com/");
|
| + full_hash_result.cache_expire_after = epoch;
|
| +
|
| + std::unique_ptr<V4GetHashProtocolManager> pm(CreateProtocolManager());
|
| + V4GetHashProtocolManager::PrefixToFullHashResultsMap& cache =
|
| + pm->v4_full_hash_cache()->at(SB_THREAT_TYPE_API_ABUSE);
|
| +
|
| + // Fill the cache with some expired entries.
|
| + // Both negative cache and full hash expired.
|
| + cache[full_hash_result.hash.prefix] = SBCachedFullHashResult(epoch);
|
| + cache[full_hash_result.hash.prefix].full_hashes.push_back(full_hash_result);
|
| +
|
| + TestClient client;
|
| + const GURL url("https://www.example.com/more");
|
| +
|
| + EXPECT_EQ(1ul, cache.size());
|
| + EXPECT_FALSE(pm->CheckApiBlacklistUrl(url, &client));
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Cache should be empty.
|
| + EXPECT_TRUE(client.callback_invoked());
|
| + EXPECT_TRUE(cache.empty());
|
| +
|
| + // Negative cache still valid and full hash expired.
|
| + cache[full_hash_result.hash.prefix] =
|
| + SBCachedFullHashResult(base::Time::Max());
|
| + cache[full_hash_result.hash.prefix].full_hashes.push_back(full_hash_result);
|
| +
|
| + EXPECT_EQ(1ul, cache.size());
|
| + EXPECT_FALSE(pm->CheckApiBlacklistUrl(url, &client));
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Cache entry should still be there.
|
| + EXPECT_EQ(1ul, cache.size());
|
| + auto entry = cache.find(full_hash_result.hash.prefix);
|
| + EXPECT_NE(cache.end(), entry);
|
| + EXPECT_EQ(base::Time::Max(), entry->second.expire_after);
|
| + EXPECT_EQ(1ul, entry->second.full_hashes.size());
|
| + EXPECT_TRUE(SBFullHashEqual(full_hash_result.hash,
|
| + entry->second.full_hashes[0].hash));
|
| + EXPECT_EQ(full_hash_result.cache_expire_after,
|
| + entry->second.full_hashes[0].cache_expire_after);
|
| +
|
| + // Negative cache still valid and full hash still valid.
|
| + cache[full_hash_result.hash.prefix].full_hashes[0].
|
| + cache_expire_after = base::Time::Max();
|
| +
|
| + EXPECT_EQ(1ul, cache.size());
|
| + EXPECT_FALSE(pm->CheckApiBlacklistUrl(url, &client));
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Cache entry should still be there.
|
| + EXPECT_EQ(1ul, cache.size());
|
| + entry = cache.find(full_hash_result.hash.prefix);
|
| + EXPECT_NE(cache.end(), entry);
|
| + EXPECT_EQ(base::Time::Max(), entry->second.expire_after);
|
| + EXPECT_EQ(1ul, entry->second.full_hashes.size());
|
| + EXPECT_TRUE(SBFullHashEqual(full_hash_result.hash,
|
| + entry->second.full_hashes[0].hash));
|
| + EXPECT_EQ(base::Time::Max(),
|
| + entry->second.full_hashes[0].cache_expire_after);
|
| +
|
| + // Negative cache expired and full hash still valid.
|
| + cache[full_hash_result.hash.prefix].expire_after = epoch;
|
| +
|
| + EXPECT_EQ(1ul, cache.size());
|
| + EXPECT_FALSE(pm->CheckApiBlacklistUrl(url, &client));
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Cache entry should still be there.
|
| + EXPECT_EQ(1ul, cache.size());
|
| + entry = cache.find(full_hash_result.hash.prefix);
|
| + EXPECT_NE(cache.end(), entry);
|
| + EXPECT_EQ(epoch, entry->second.expire_after);
|
| + EXPECT_EQ(1ul, entry->second.full_hashes.size());
|
| + EXPECT_TRUE(SBFullHashEqual(full_hash_result.hash,
|
| + entry->second.full_hashes[0].hash));
|
| + EXPECT_EQ(base::Time::Max(),
|
| + entry->second.full_hashes[0].cache_expire_after);
|
| +}
|
| +*/
|
| } // namespace safe_browsing
|
|
|