summaryrefslogtreecommitdiffstats
path: root/net/base/cookie_monster_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/base/cookie_monster_unittest.cc')
-rw-r--r--net/base/cookie_monster_unittest.cc267
1 files changed, 137 insertions, 130 deletions
diff --git a/net/base/cookie_monster_unittest.cc b/net/base/cookie_monster_unittest.cc
index 83c7f7d..80d58ed 100644
--- a/net/base/cookie_monster_unittest.cc
+++ b/net/base/cookie_monster_unittest.cc
@@ -1032,16 +1032,17 @@ static int CountInString(const std::string& str, char c) {
return std::count(str.begin(), str.end(), c);
}
-static void TestHostGarbageCollectHelper(int domain_max_cookies,
- int domain_purge_cookies,
- bool new_key_scheme) {
+static void TestHostGarbageCollectHelper(
+ int domain_max_cookies,
+ int domain_purge_cookies,
+ CookieMonster::ExpiryAndKeyScheme key_scheme) {
GURL url_google(kUrlGoogle);
const int more_than_enough_cookies =
(domain_max_cookies + domain_purge_cookies) * 2;
// Add a bunch of cookies on a single host, should purge them.
{
scoped_refptr<net::CookieMonster> cm(new net::CookieMonster(NULL, NULL));
- cm->SetKeyScheme(new_key_scheme);
+ cm->SetExpiryAndKeyScheme(key_scheme);
for (int i = 0; i < more_than_enough_cookies; ++i) {
std::string cookie = base::StringPrintf("a%03d=b", i);
EXPECT_TRUE(cm->SetCookie(url_google, cookie));
@@ -1055,14 +1056,15 @@ static void TestHostGarbageCollectHelper(int domain_max_cookies,
// Add a bunch of cookies on multiple hosts within a single eTLD.
// Should keep at least kDomainMaxCookies - kDomainPurgeCookies
- // between them. If we are using the (new) effective domain keying system
- // we shouldn't go above kDomainMaxCookies for both together.
- // If we're using the (old) domain keying system, each individual
- // domain shouldn't go above kDomainMaxCookies.
+ // between them. If we are using the effective domain keying system
+ // (EKS_KEEP_RECENT_AND_PURGE_ETLDP1) we shouldn't go above
+ // kDomainMaxCookies for both together. If we're using the domain
+ // keying system (EKS_DISCARD_RECENT_AND_PURGE_DOMAIN), each
+ // individual domain shouldn't go above kDomainMaxCookies.
GURL url_google_specific(kUrlGoogleSpecific);
{
scoped_refptr<net::CookieMonster> cm(new net::CookieMonster(NULL, NULL));
- cm->SetKeyScheme(new_key_scheme);
+ cm->SetExpiryAndKeyScheme(key_scheme);
for (int i = 0; i < more_than_enough_cookies; ++i) {
std::string cookie_general = base::StringPrintf("a%03d=b", i);
EXPECT_TRUE(cm->SetCookie(url_google, cookie_general));
@@ -1072,7 +1074,7 @@ static void TestHostGarbageCollectHelper(int domain_max_cookies,
EXPECT_NE(cookies_general.find(cookie_general), std::string::npos);
std::string cookies_specific = cm->GetCookies(url_google_specific);
EXPECT_NE(cookies_specific.find(cookie_specific), std::string::npos);
- if (new_key_scheme) {
+ if (key_scheme == CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1) {
EXPECT_LE((CountInString(cookies_general, '=') +
CountInString(cookies_specific, '=')),
domain_max_cookies);
@@ -1085,7 +1087,7 @@ static void TestHostGarbageCollectHelper(int domain_max_cookies,
// kDomainMaxCookies - kDomainPurgeCookies for both URLs.
std::string cookies_general = cm->GetCookies(url_google);
std::string cookies_specific = cm->GetCookies(url_google_specific);
- if (new_key_scheme) {
+ if (key_scheme == CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1) {
int total_cookies = (CountInString(cookies_general, '=') +
CountInString(cookies_specific, '='));
EXPECT_GE(total_cookies,
@@ -1105,43 +1107,12 @@ static void TestHostGarbageCollectHelper(int domain_max_cookies,
}
TEST(CookieMonsterTest, TestHostGarbageCollection) {
- TestHostGarbageCollectHelper(CookieMonster::kDomainMaxCookies,
- CookieMonster::kDomainPurgeCookies, false);
- TestHostGarbageCollectHelper(CookieMonster::kDomainMaxCookies,
- CookieMonster::kDomainPurgeCookies, true);
-}
-
-TEST(CookieMonsterTest, TestTotalGarbageCollection) {
- scoped_refptr<net::CookieMonster> cm(
- new net::CookieMonster(NULL, NULL, kLastAccessThresholdMilliseconds));
-
- // Add a bunch of cookies on a bunch of host, some should get purged.
- const GURL sticky_cookie("http://a0000.izzle");
- for (int i = 0; i < 4000; ++i) {
- GURL url(base::StringPrintf("http://a%04d.izzle", i));
- EXPECT_TRUE(cm->SetCookie(url, "a=b"));
- EXPECT_EQ("a=b", cm->GetCookies(url));
-
- // Keep touching the first cookie to ensure it's not purged (since it will
- // always have the most recent access time).
- if (!(i % 500)) {
- // Ensure the timestamps will be different enough to update.
- PlatformThread::Sleep(kLastAccessThresholdMilliseconds + 20);
- EXPECT_EQ("a=b", cm->GetCookies(sticky_cookie));
- }
- }
-
- // Check that cookies that still exist.
- for (int i = 0; i < 4000; ++i) {
- GURL url(base::StringPrintf("http://a%04d.izzle", i));
- if ((i == 0) || (i > 1001)) {
- // Cookies should still be around.
- EXPECT_FALSE(cm->GetCookies(url).empty());
- } else if (i < 701) {
- // Cookies should have gotten purged.
- EXPECT_TRUE(cm->GetCookies(url).empty());
- }
- }
+ TestHostGarbageCollectHelper(
+ CookieMonster::kDomainMaxCookies, CookieMonster::kDomainPurgeCookies,
+ CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1);
+ TestHostGarbageCollectHelper(
+ CookieMonster::kDomainMaxCookies, CookieMonster::kDomainPurgeCookies,
+ CookieMonster::EKS_DISCARD_RECENT_AND_PURGE_DOMAIN);
}
// Formerly NetUtilTest.CookieTest back when we used wininet's cookie handling.
@@ -1547,16 +1518,16 @@ TEST(CookieMonsterTest, Delegate) {
EXPECT_TRUE(cm->SetCookie(url_google, "E=F"));
EXPECT_EQ("A=B; C=D; E=F", cm->GetCookies(url_google));
ASSERT_EQ(3u, delegate->changes().size());
- EXPECT_EQ(false, delegate->changes()[0].second);
+ EXPECT_FALSE(delegate->changes()[0].second);
EXPECT_EQ(url_google.host(), delegate->changes()[0].first.Domain());
EXPECT_EQ("A", delegate->changes()[0].first.Name());
EXPECT_EQ("B", delegate->changes()[0].first.Value());
EXPECT_EQ(url_google.host(), delegate->changes()[1].first.Domain());
- EXPECT_EQ(false, delegate->changes()[1].second);
+ EXPECT_FALSE(delegate->changes()[1].second);
EXPECT_EQ("C", delegate->changes()[1].first.Name());
EXPECT_EQ("D", delegate->changes()[1].first.Value());
EXPECT_EQ(url_google.host(), delegate->changes()[2].first.Domain());
- EXPECT_EQ(false, delegate->changes()[2].second);
+ EXPECT_FALSE(delegate->changes()[2].second);
EXPECT_EQ("E", delegate->changes()[2].first.Name());
EXPECT_EQ("F", delegate->changes()[2].first.Value());
delegate->reset();
@@ -1565,7 +1536,7 @@ TEST(CookieMonsterTest, Delegate) {
EXPECT_EQ("A=B; E=F", cm->GetCookies(url_google));
ASSERT_EQ(1u, delegate->changes().size());
EXPECT_EQ(url_google.host(), delegate->changes()[0].first.Domain());
- EXPECT_EQ(true, delegate->changes()[0].second);
+ EXPECT_TRUE(delegate->changes()[0].second);
EXPECT_EQ("C", delegate->changes()[0].first.Name());
EXPECT_EQ("D", delegate->changes()[0].first.Value());
delegate->reset();
@@ -1581,7 +1552,7 @@ TEST(CookieMonsterTest, Delegate) {
ASSERT_EQ(1u, store->commands().size());
EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
ASSERT_EQ(1u, delegate->changes().size());
- EXPECT_EQ(false, delegate->changes()[0].second);
+ EXPECT_FALSE(delegate->changes()[0].second);
EXPECT_EQ(url_google.host(), delegate->changes()[0].first.Domain());
EXPECT_EQ("a", delegate->changes()[0].first.Name());
EXPECT_EQ("val1", delegate->changes()[0].first.Value());
@@ -1601,11 +1572,11 @@ TEST(CookieMonsterTest, Delegate) {
EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
ASSERT_EQ(2u, delegate->changes().size());
EXPECT_EQ(url_google.host(), delegate->changes()[0].first.Domain());
- EXPECT_EQ(true, delegate->changes()[0].second);
+ EXPECT_TRUE(delegate->changes()[0].second);
EXPECT_EQ("a", delegate->changes()[0].first.Name());
EXPECT_EQ("val1", delegate->changes()[0].first.Value());
EXPECT_EQ(url_google.host(), delegate->changes()[1].first.Domain());
- EXPECT_EQ(false, delegate->changes()[1].second);
+ EXPECT_FALSE(delegate->changes()[1].second);
EXPECT_EQ("a", delegate->changes()[1].first.Name());
EXPECT_EQ("val2", delegate->changes()[1].first.Value());
delegate->reset();
@@ -1827,7 +1798,8 @@ TEST(CookieMonsterTest, GetKey) {
scoped_refptr<net::CookieMonster> cm(new net::CookieMonster(NULL, NULL));
// This test is really only interesting if GetKey() actually does something.
- if (cm->use_effective_domain_key_scheme_) {
+ if (cm->expiry_and_key_scheme_ ==
+ CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1) {
EXPECT_EQ("google.com", cm->GetKey("www.google.com"));
EXPECT_EQ("google.izzie", cm->GetKey("www.google.izzie"));
EXPECT_EQ("google.izzie", cm->GetKey(".google.izzie"));
@@ -1847,78 +1819,6 @@ TEST(CookieMonsterTest, GetKey) {
}
}
-// Just act like a backing database. Keep cookie information from
-// Add/Update/Delete and regurgitate it when Load is called.
-class MockSimplePersistentCookieStore
- : public CookieMonster::PersistentCookieStore {
- public:
- typedef std::vector<CookieMonster::CanonicalCookie> CanonicalCookieVector;
-
- virtual bool Load(std::vector<CookieMonster::CanonicalCookie*>* out_cookies);
-
- virtual void AddCookie(const net::CookieMonster::CanonicalCookie& cookie);
-
- virtual void UpdateCookieAccessTime(
- const CookieMonster::CanonicalCookie& cookie);
-
- virtual void DeleteCookie(const CookieMonster::CanonicalCookie& cookie);
-
- private:
- std::vector<CookieMonster::CanonicalCookie> cookies_;
-};
-
-bool MockSimplePersistentCookieStore::Load(
- std::vector<CookieMonster::CanonicalCookie*>* out_cookies) {
- for (CanonicalCookieVector::const_iterator it = cookies_.begin();
- it != cookies_.end(); it++)
- out_cookies->push_back(new CookieMonster::CanonicalCookie(*it));
- return true;
-}
-
-void MockSimplePersistentCookieStore::AddCookie(
- const net::CookieMonster::CanonicalCookie& cookie) {
- for (CanonicalCookieVector::const_iterator it = cookies_.begin();
- it != cookies_.end(); it++) {
- // Caller must assure creation dates unique.
- EXPECT_NE(cookie.CreationDate().ToInternalValue(),
- it->CreationDate().ToInternalValue());
- }
- cookies_.push_back(cookie);
-}
-
-void MockSimplePersistentCookieStore::UpdateCookieAccessTime(
- const CookieMonster::CanonicalCookie& cookie) {
- for (CanonicalCookieVector::iterator it = cookies_.begin();
- it != cookies_.end(); it++) {
- if (it->CreationDate() == cookie.CreationDate())
- it->SetLastAccessDate(base::Time::Now());
- }
-}
-
-void MockSimplePersistentCookieStore::DeleteCookie(
- const CookieMonster::CanonicalCookie& cookie) {
- for (CanonicalCookieVector::iterator it = cookies_.begin();
- it != cookies_.end(); it++) {
- if (it->CreationDate() == cookie.CreationDate()) {
- cookies_.erase(it);
- return;
- }
- }
-}
-
-// Helper type for BackingStoreCommunication; defined outside of the
-// function so that arraysize() macro can beu used.
-struct CookiesInputInfo {
- std::string gurl;
- std::string name;
- std::string value;
- std::string domain;
- std::string path;
- base::Time expires;
- bool secure;
- bool http_only;
-};
-
// Test that cookies transfer from/to the backing store correctly.
TEST(CookieMonsterTest, BackingStoreCommunication) {
// Store details for cookies transforming through the backing store interface.
@@ -1929,6 +1829,16 @@ TEST(CookieMonsterTest, BackingStoreCommunication) {
base::Time new_access_time;
base::Time expires(base::Time::Now() + base::TimeDelta::FromSeconds(100));
+ struct CookiesInputInfo {
+ std::string gurl;
+ std::string name;
+ std::string value;
+ std::string domain;
+ std::string path;
+ base::Time expires;
+ bool secure;
+ bool http_only;
+ };
const CookiesInputInfo input_info[] = {
{"http://a.b.google.com", "a", "1", "", "/path/to/cookie", expires,
false, false},
@@ -1944,7 +1854,7 @@ TEST(CookieMonsterTest, BackingStoreCommunication) {
{
scoped_refptr<net::CookieMonster> cmout = new CookieMonster(store, NULL);
for (const CookiesInputInfo* p = input_info;
- p < &input_info[arraysize(input_info)]; p++) {
+ p < &input_info[ARRAYSIZE_UNSAFE(input_info)]; p++) {
EXPECT_TRUE(cmout->SetCookieWithDetails(GURL(p->gurl), p->name, p->value,
p->domain, p->path, p->expires,
p->secure, p->http_only));
@@ -2027,4 +1937,101 @@ TEST(CookieMonsterTest, CookieOrdering) {
}
}
-} // namespace
+
+// Function for creating a CM with a number of cookies in it,
+// no store (and hence no ability to affect access time).
+static net::CookieMonster* CreateMonsterForGC(int num_cookies) {
+ net::CookieMonster* cm(new net::CookieMonster(NULL, NULL));
+ for (int i = 0; i < num_cookies; i++)
+ cm->SetCookie(GURL(StringPrintf("http://h%05d.izzle", i)), "a=1");
+ return cm;
+}
+
+// This test and CookieMonstertest.TestGCTimes (in cookie_monster_perftest.cc)
+// are somewhat complementary twins. This test is probing for whether
+// garbage collection always happens when it should (i.e. that we actually
+// get rid of cookies when we should). The perftest is probing for
+// whether garbage collection happens when it shouldn't. See comments
+// before that test for more details.
+// Flaky as per http://crbug.com/60015
+TEST(CookieMonsterTest, FLAKY_GarbageCollectionTriggers) {
+ // First we check to make sure that a whole lot of recent cookies
+ // doesn't get rid of anything after garbage collection is checked for.
+ {
+ scoped_refptr<net::CookieMonster> cm =
+ CreateMonsterForGC(CookieMonster::kMaxCookies * 2);
+ EXPECT_EQ(CookieMonster::kMaxCookies * 2, cm->GetAllCookies().size());
+ cm->SetCookie(GURL("http://newdomain.com"), "b=2");
+ EXPECT_EQ(CookieMonster::kMaxCookies * 2 + 1, cm->GetAllCookies().size());
+ }
+
+ // Now we explore a series of relationships between cookie last access
+ // time and size of store to make sure we only get rid of cookies when
+ // we really should.
+ const struct TestCase {
+ int num_cookies;
+ int num_old_cookies;
+ int expected_initial_cookies;
+ // Indexed by ExpiryAndKeyScheme
+ int expected_cookies_after_set[CookieMonster::EKS_LAST_ENTRY];
+ } test_cases[] = {
+ {
+ // A whole lot of recent cookies; gc shouldn't happen.
+ CookieMonster::kMaxCookies * 2,
+ 0,
+ CookieMonster::kMaxCookies * 2,
+ { CookieMonster::kMaxCookies * 2 + 1,
+ CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies }
+ }, {
+ // Some old cookies, but still overflowing max.
+ CookieMonster::kMaxCookies * 2,
+ CookieMonster::kMaxCookies / 2,
+ CookieMonster::kMaxCookies * 2,
+ {CookieMonster::kMaxCookies * 2 - CookieMonster::kMaxCookies / 2 + 1,
+ CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies}
+ }, {
+ // Old cookies enough to bring us right down to our purge line.
+ CookieMonster::kMaxCookies * 2,
+ CookieMonster::kMaxCookies + CookieMonster::kPurgeCookies + 1,
+ CookieMonster::kMaxCookies * 2,
+ {CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies,
+ CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies}
+ }, {
+ // Old cookies enough to bring below our purge line (which we
+ // shouldn't do).
+ CookieMonster::kMaxCookies * 2,
+ CookieMonster::kMaxCookies * 3 / 2,
+ CookieMonster::kMaxCookies * 2,
+ {CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies,
+ CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies}
+ }
+ };
+ const CookieMonster::ExpiryAndKeyScheme schemes[] = {
+ CookieMonster::EKS_KEEP_RECENT_AND_PURGE_ETLDP1,
+ CookieMonster::EKS_DISCARD_RECENT_AND_PURGE_DOMAIN,
+ };
+
+ for (int ci = 0; ci < static_cast<int>(ARRAYSIZE_UNSAFE(test_cases)); ++ci) {
+ // Test both old and new key and expiry schemes.
+ for (int recent_scheme = 0;
+ recent_scheme < static_cast<int>(ARRAYSIZE_UNSAFE(schemes));
+ recent_scheme++) {
+ const TestCase *test_case = &test_cases[ci];
+ scoped_refptr<net::CookieMonster> cm =
+ CreateMonsterFromStoreForGC(
+ test_case->num_cookies, test_case->num_old_cookies,
+ CookieMonster::kSafeFromGlobalPurgeDays * 2);
+ cm->SetExpiryAndKeyScheme(schemes[recent_scheme]);
+ EXPECT_EQ(test_case->expected_initial_cookies,
+ static_cast<int>(cm->GetAllCookies().size()))
+ << "For test case " << ci;
+ // Will trigger GC
+ cm->SetCookie(GURL("http://newdomain.com"), "b=2");
+ EXPECT_EQ(test_case->expected_cookies_after_set[recent_scheme],
+ static_cast<int>((cm->GetAllCookies().size())))
+ << "For test case (" << ci << ", " << recent_scheme << ")";
+ }
+ }
+}
+
+} // namespace