15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/expiring_cache.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <functional> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Pointee; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::StrEq; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxCacheEntries = 10; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ExpiringCache<std::string, std::string, base::TimeTicks, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::less<base::TimeTicks> > Cache; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TestFunctor { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator()(const std::string& now, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& expiration) const { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return now != expiration; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ExpiringCacheTest, Basic) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta kTTL = base::TimeDelta::FromSeconds(10); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cache cache(kMaxCacheEntries); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start at t=0. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, cache.size()); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add an entry at t=0 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("entry1", now)); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("entry1", "test1", now, now + kTTL); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("entry1", now), Pointee(StrEq("test1"))); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, cache.size()); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance to t=5. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now += base::TimeDelta::FromSeconds(5); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add an entry at t=5. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("entry2", now)); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("entry2", "test2", now, now + kTTL); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("entry2", now), Pointee(StrEq("test2"))); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, cache.size()); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance to t=9. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now += base::TimeDelta::FromSeconds(4); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the entries added are still retrievable and usable. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("entry1", now), Pointee(StrEq("test1"))); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("entry2", now), Pointee(StrEq("test2"))); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance to t=10; entry1 is now expired. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now += base::TimeDelta::FromSeconds(1); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("entry1", now)); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("entry2", now), Pointee(StrEq("test2"))); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The expired element should no longer be in the cache. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, cache.size()); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update entry1 so it is no longer expired. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("entry1", "test1", now, now + kTTL); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Both entries should be retrievable and usable. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, cache.size()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("entry1", now), Pointee(StrEq("test1"))); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("entry2", now), Pointee(StrEq("test2"))); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance to t=20; both entries are now expired. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now += base::TimeDelta::FromSeconds(10); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("entry1", now)); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("entry2", now)); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ExpiringCacheTest, Compact) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta kTTL = base::TimeDelta::FromSeconds(10); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cache cache(kMaxCacheEntries); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start at t=0. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, cache.size()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add five valid entries at t=10 that expire at t=20. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks t10 = now + kTTL; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 5; ++i) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name = base::StringPrintf("valid%d", i); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put(name, "I'm valid!", t10, t10 + kTTL); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, cache.size()); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add three entries at t=0 that expire at t=10. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 3; ++i) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name = base::StringPrintf("expired%d", i); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put(name, "I'm expired.", now, t10); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(8U, cache.size()); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add two negative (instantly expired) entries at t=0 that expire at t=0. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name = base::StringPrintf("negative%d", i); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put(name, "I was never valid.", now, now); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(10U, cache.size()); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid0")); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid1")); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid2")); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid3")); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid4")); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "expired0")); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "expired1")); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "expired2")); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "negative0")); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "negative1")); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shrink the new max constraints bound and compact. The "negative" and 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "expired" entries should be dropped. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.max_entries_ = 6; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Compact(now); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, cache.size()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid0")); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid1")); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid2")); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid3")); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ContainsKey(cache.entries_, "valid4")); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(ContainsKey(cache.entries_, "expired0")); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(ContainsKey(cache.entries_, "expired1")); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(ContainsKey(cache.entries_, "expired2")); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(ContainsKey(cache.entries_, "negative0")); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(ContainsKey(cache.entries_, "negative1")); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shrink further -- this time the compact will start dropping valid entries 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to make space. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.max_entries_ = 4; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Compact(now); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, cache.size()); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Add entries while the cache is at capacity, causing evictions. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ExpiringCacheTest, SetWithCompact) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta kTTL = base::TimeDelta::FromSeconds(10); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cache cache(3); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // t=10 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now = base::TimeTicks() + kTTL; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test1", "test1", now, now + kTTL); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test2", "test2", now, now + kTTL); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("expired", "expired", now, now); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, cache.size()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should all be retrievable except "expired". 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test1", now), Pointee(StrEq("test1"))); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test2", now), Pointee(StrEq("test2"))); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("expired", now)); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adding the fourth entry will cause "expired" to be evicted. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test3", "test3", now, now + kTTL); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, cache.size()); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("expired", now)); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test1", now), Pointee(StrEq("test1"))); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test2", now), Pointee(StrEq("test2"))); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test3", now), Pointee(StrEq("test3"))); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add two more entries. Something should be evicted, however "test5" 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should definitely be in there (since it was last inserted). 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test4", "test4", now, now + kTTL); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, cache.size()); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test5", "test5", now, now + kTTL); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, cache.size()); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test5", now), Pointee(StrEq("test5"))); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ExpiringCacheTest, Clear) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta kTTL = base::TimeDelta::FromSeconds(10); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cache cache(kMaxCacheEntries); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start at t=0. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, cache.size()); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add three entries. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test1", "foo", now, now + kTTL); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test2", "foo", now, now + kTTL); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test3", "foo", now, now + kTTL); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, cache.size()); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Clear(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, cache.size()); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ExpiringCacheTest, GetTruncatesExpiredEntries) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta kTTL = base::TimeDelta::FromSeconds(10); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cache cache(kMaxCacheEntries); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start at t=0. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks now; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, cache.size()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add three entries at t=0. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test1", "foo1", now, now + kTTL); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test2", "foo2", now, now + kTTL); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test3", "foo3", now, now + kTTL); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, cache.size()); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the entries were added. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test1", now), Pointee(StrEq("foo1"))); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test2", now), Pointee(StrEq("foo2"))); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test3", now), Pointee(StrEq("foo3"))); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add five entries at t=10. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now += kTTL; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 5; ++i) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name = base::StringPrintf("valid%d", i); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put(name, name, now, now + kTTL); // Expire at t=20. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(8U, cache.size()); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now access two expired entries and ensure the cache size goes down. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("test1", now)); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("test2", now)); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(6U, cache.size()); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Accessing non-expired entries should return entries and not adjust the 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cache size. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 5; ++i) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name = base::StringPrintf("valid%d", i); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get(name, now), Pointee(StrEq(name))); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(6U, cache.size()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ExpiringCacheTest, CustomFunctor) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExpiringCache<std::string, std::string, std::string, TestFunctor> cache(5); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kNow("Now"); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kLater("A little bit later"); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kMuchLater("Much later"); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kHeatDeath("The heat death of the universe"); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, cache.size()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add three entries at t=kNow that expire at kLater. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test1", "foo1", kNow, kLater); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test2", "foo2", kNow, kLater); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test3", "foo3", kNow, kLater); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, cache.size()); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add two entries at t=kNow that expire at kMuchLater 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test4", "foo4", kNow, kMuchLater); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test5", "foo5", kNow, kMuchLater); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, cache.size()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the entries were added. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test1", kNow), Pointee(StrEq("foo1"))); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test2", kNow), Pointee(StrEq("foo2"))); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test3", kNow), Pointee(StrEq("foo3"))); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test4", kNow), Pointee(StrEq("foo4"))); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test5", kNow), Pointee(StrEq("foo5"))); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add one entry at t=kLater that expires at kHeatDeath, which will expire 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // one of test1-3. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test6", "foo6", kLater, kHeatDeath); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test6", kLater), Pointee(StrEq("foo6"))); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, cache.size()); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now compact at kMuchLater, which should remove all but "test6". 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.max_entries_ = 2; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Compact(kMuchLater); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, cache.size()); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test6", kMuchLater), Pointee(StrEq("foo6"))); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally, "test6" should not be valid at the end of the universe. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("test6", kHeatDeath)); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because comparison is based on equality, not strict weak ordering, we 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be able to add something at kHeatDeath that expires at kMuchLater. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.Put("test7", "foo7", kHeatDeath, kMuchLater); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, cache.size()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test7", kNow), Pointee(StrEq("foo7"))); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test7", kLater), Pointee(StrEq("foo7"))); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_THAT(cache.Get("test7", kHeatDeath), Pointee(StrEq("foo7"))); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(cache.Get("test7", kMuchLater)); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 312