Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(716)

Unified Diff: content/browser/net/sqlite_persistent_cookie_store_unittest.cc

Issue 1134113007: Revert of Moves SQLitePersistentCookieStore to net/extras/sqlite. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cookies
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/net/sqlite_persistent_cookie_store_perftest.cc ('k') | content/content_browser.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/net/sqlite_persistent_cookie_store_unittest.cc
diff --git a/content/browser/net/sqlite_persistent_cookie_store_unittest.cc b/content/browser/net/sqlite_persistent_cookie_store_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..af7859a26a9f1695dc4e8aa7a809245b2ebfad18
--- /dev/null
+++ b/content/browser/net/sqlite_persistent_cookie_store_unittest.cc
@@ -0,0 +1,681 @@
+// Copyright (c) 2012 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 "content/browser/net/sqlite_persistent_cookie_store.h"
+
+#include <map>
+#include <set>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/sequenced_task_runner.h"
+#include "base/stl_util.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/sequenced_worker_pool_owner.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "base/time/time.h"
+#include "content/public/browser/cookie_store_factory.h"
+#include "crypto/encryptor.h"
+#include "crypto/symmetric_key.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_constants.h"
+#include "net/extras/sqlite/cookie_crypto_delegate.h"
+#include "sql/connection.h"
+#include "sql/meta_table.h"
+#include "sql/statement.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+const base::FilePath::CharType kCookieFilename[] = FILE_PATH_LITERAL("Cookies");
+
+class CookieCryptor : public net::CookieCryptoDelegate {
+ public:
+ CookieCryptor();
+ bool EncryptString(const std::string& plaintext,
+ std::string* ciphertext) override;
+ bool DecryptString(const std::string& ciphertext,
+ std::string* plaintext) override;
+
+ private:
+ scoped_ptr<crypto::SymmetricKey> key_;
+ crypto::Encryptor encryptor_;
+};
+
+CookieCryptor::CookieCryptor() : key_(
+ crypto::SymmetricKey::DeriveKeyFromPassword(
+ crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256)) {
+ std::string iv("the iv: 16 bytes");
+ encryptor_.Init(key_.get(), crypto::Encryptor::CBC, iv);
+}
+
+bool CookieCryptor::EncryptString(const std::string& plaintext,
+ std::string* ciphertext) {
+ return encryptor_.Encrypt(plaintext, ciphertext);
+}
+
+bool CookieCryptor::DecryptString(const std::string& ciphertext,
+ std::string* plaintext) {
+ return encryptor_.Decrypt(ciphertext, plaintext);
+}
+
+} // namespace
+
+typedef std::vector<net::CanonicalCookie*> CanonicalCookieVector;
+
+class SQLitePersistentCookieStoreTest : public testing::Test {
+ public:
+ SQLitePersistentCookieStoreTest()
+ : pool_owner_(new base::SequencedWorkerPoolOwner(3, "Background Pool")),
+ loaded_event_(false, false),
+ key_loaded_event_(false, false),
+ db_thread_event_(false, false) {
+ }
+
+ void OnLoaded(const CanonicalCookieVector& cookies) {
+ cookies_ = cookies;
+ loaded_event_.Signal();
+ }
+
+ void OnKeyLoaded(const CanonicalCookieVector& cookies) {
+ cookies_ = cookies;
+ key_loaded_event_.Signal();
+ }
+
+ void Load(CanonicalCookieVector* cookies) {
+ EXPECT_FALSE(loaded_event_.IsSignaled());
+ store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded,
+ base::Unretained(this)));
+ loaded_event_.Wait();
+ *cookies = cookies_;
+ }
+
+ void Flush() {
+ base::WaitableEvent event(false, false);
+ store_->Flush(base::Bind(&base::WaitableEvent::Signal,
+ base::Unretained(&event)));
+ event.Wait();
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("background"));
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> client_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("client"));
+ }
+
+ void DestroyStore() {
+ store_ = NULL;
+ // Make sure we wait until the destructor has run by shutting down the pool
+ // resetting the owner (whose destructor blocks on the pool completion).
+ pool_owner_->pool()->Shutdown();
+ // Create a new pool for the few tests that create multiple stores. In other
+ // cases this is wasted but harmless.
+ pool_owner_.reset(new base::SequencedWorkerPoolOwner(3, "Background Pool"));
+ }
+
+ void CreateAndLoad(bool crypt_cookies,
+ bool restore_old_session_cookies,
+ CanonicalCookieVector* cookies) {
+ if (crypt_cookies)
+ cookie_crypto_delegate_.reset(new CookieCryptor());
+
+ store_ = new SQLitePersistentCookieStore(
+ temp_dir_.path().Append(kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
+ restore_old_session_cookies,
+ NULL,
+ cookie_crypto_delegate_.get());
+ Load(cookies);
+ }
+
+ void InitializeStore(bool crypt, bool restore_old_session_cookies) {
+ CanonicalCookieVector cookies;
+ CreateAndLoad(crypt, restore_old_session_cookies, &cookies);
+ EXPECT_EQ(0U, cookies.size());
+ }
+
+ // We have to create this method to wrap WaitableEvent::Wait, since we cannot
+ // bind a non-void returning method as a Closure.
+ void WaitOnDBEvent() {
+ db_thread_event_.Wait();
+ }
+
+ // Adds a persistent cookie to store_.
+ void AddCookie(const std::string& name,
+ const std::string& value,
+ const std::string& domain,
+ const std::string& path,
+ const base::Time& creation) {
+ store_->AddCookie(net::CanonicalCookie(
+ GURL(), name, value, domain, path, creation, creation, creation, false,
+ false, false, net::COOKIE_PRIORITY_DEFAULT));
+ }
+
+ void AddCookieWithExpiration(const std::string& name,
+ const std::string& value,
+ const std::string& domain,
+ const std::string& path,
+ const base::Time& creation,
+ const base::Time& expiration) {
+ store_->AddCookie(net::CanonicalCookie(
+ GURL(), name, value, domain, path, creation, expiration, creation,
+ false, false, false, net::COOKIE_PRIORITY_DEFAULT));
+ }
+
+ std::string ReadRawDBContents() {
+ std::string contents;
+ if (!base::ReadFileToString(temp_dir_.path().Append(kCookieFilename),
+ &contents))
+ return std::string();
+ return contents;
+ }
+
+ void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
+
+ void TearDown() override {
+ DestroyStore();
+ pool_owner_->pool()->Shutdown();
+ }
+
+ protected:
+ base::MessageLoop main_loop_;
+ scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
+ base::WaitableEvent loaded_event_;
+ base::WaitableEvent key_loaded_event_;
+ base::WaitableEvent db_thread_event_;
+ CanonicalCookieVector cookies_;
+ base::ScopedTempDir temp_dir_;
+ scoped_refptr<SQLitePersistentCookieStore> store_;
+ scoped_ptr<net::CookieCryptoDelegate> cookie_crypto_delegate_;
+};
+
+TEST_F(SQLitePersistentCookieStoreTest, TestInvalidMetaTableRecovery) {
+ InitializeStore(false, false);
+ AddCookie("A", "B", "foo.bar", "/", base::Time::Now());
+ DestroyStore();
+
+ // Load up the store and verify that it has good data in it.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(false, false, &cookies);
+ ASSERT_EQ(1U, cookies.size());
+ ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str());
+ ASSERT_STREQ("A", cookies[0]->Name().c_str());
+ ASSERT_STREQ("B", cookies[0]->Value().c_str());
+ DestroyStore();
+ STLDeleteElements(&cookies);
+
+ // Now corrupt the meta table.
+ {
+ sql::Connection db;
+ ASSERT_TRUE(db.Open(temp_dir_.path().Append(kCookieFilename)));
+ sql::MetaTable meta_table_;
+ meta_table_.Init(&db, 1, 1);
+ ASSERT_TRUE(db.Execute("DELETE FROM meta"));
+ db.Close();
+ }
+
+ // Upon loading, the database should be reset to a good, blank state.
+ CreateAndLoad(false, false, &cookies);
+ ASSERT_EQ(0U, cookies.size());
+
+ // Verify that, after, recovery, the database persists properly.
+ AddCookie("X", "Y", "foo.bar", "/", base::Time::Now());
+ DestroyStore();
+ CreateAndLoad(false, false, &cookies);
+ ASSERT_EQ(1U, cookies.size());
+ ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str());
+ ASSERT_STREQ("X", cookies[0]->Name().c_str());
+ ASSERT_STREQ("Y", cookies[0]->Value().c_str());
+ STLDeleteElements(&cookies);
+}
+
+// Test if data is stored as expected in the SQLite database.
+TEST_F(SQLitePersistentCookieStoreTest, TestPersistance) {
+ InitializeStore(false, false);
+ AddCookie("A", "B", "foo.bar", "/", base::Time::Now());
+ // Replace the store effectively destroying the current one and forcing it
+ // to write its data to disk. Then we can see if after loading it again it
+ // is still there.
+ DestroyStore();
+ // Reload and test for persistence
+ CanonicalCookieVector cookies;
+ CreateAndLoad(false, false, &cookies);
+ ASSERT_EQ(1U, cookies.size());
+ ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str());
+ ASSERT_STREQ("A", cookies[0]->Name().c_str());
+ ASSERT_STREQ("B", cookies[0]->Value().c_str());
+
+ // Now delete the cookie and check persistence again.
+ store_->DeleteCookie(*cookies[0]);
+ DestroyStore();
+ STLDeleteElements(&cookies);
+
+ // Reload and check if the cookie has been removed.
+ CreateAndLoad(false, false, &cookies);
+ ASSERT_EQ(0U, cookies.size());
+}
+
+TEST_F(SQLitePersistentCookieStoreTest, TestSessionCookiesDeletedOnStartup) {
+ // Initialize the cookie store with 3 persistent cookies, 5 transient
+ // cookies.
+ InitializeStore(false, false);
+
+ // Add persistent cookies.
+ base::Time t = base::Time::Now();
+ AddCookie("A", "B", "a1.com", "/", t);
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookie("A", "B", "a2.com", "/", t);
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookie("A", "B", "a3.com", "/", t);
+
+ // Add transient cookies.
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookieWithExpiration("A", "B", "b1.com", "/", t, base::Time());
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookieWithExpiration("A", "B", "b2.com", "/", t, base::Time());
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookieWithExpiration("A", "B", "b3.com", "/", t, base::Time());
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookieWithExpiration("A", "B", "b4.com", "/", t, base::Time());
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookieWithExpiration("A", "B", "b5.com", "/", t, base::Time());
+ DestroyStore();
+
+ // Load the store a second time. Before the store finishes loading, add a
+ // transient cookie and flush it to disk.
+ store_ = new SQLitePersistentCookieStore(
+ temp_dir_.path().Append(kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
+ false, NULL, NULL);
+
+ // Posting a blocking task to db_thread_ makes sure that the DB thread waits
+ // until both Load and Flush have been posted to its task queue.
+ background_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&SQLitePersistentCookieStoreTest::WaitOnDBEvent,
+ base::Unretained(this)));
+ store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded,
+ base::Unretained(this)));
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookieWithExpiration("A", "B", "c.com", "/", t, base::Time());
+ base::WaitableEvent event(false, false);
+ store_->Flush(base::Bind(&base::WaitableEvent::Signal,
+ base::Unretained(&event)));
+
+ // Now the DB-thread queue contains:
+ // (active:)
+ // 1. Wait (on db_event)
+ // (pending:)
+ // 2. "Init And Chain-Load First Domain"
+ // 3. Add Cookie (c.com)
+ // 4. Flush Cookie (c.com)
+ db_thread_event_.Signal();
+ event.Wait();
+ loaded_event_.Wait();
+ STLDeleteElements(&cookies_);
+ DestroyStore();
+
+ // Load the store a third time, this time restoring session cookies. The
+ // store should contain exactly 4 cookies: the 3 persistent, and "c.com",
+ // which was added during the second cookie store load.
+ store_ = new SQLitePersistentCookieStore(
+ temp_dir_.path().Append(kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
+ true, NULL, NULL);
+ store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded,
+ base::Unretained(this)));
+ loaded_event_.Wait();
+ ASSERT_EQ(4u, cookies_.size());
+ STLDeleteElements(&cookies_);
+}
+
+// Test that priority load of cookies for a specfic domain key could be
+// completed before the entire store is loaded
+TEST_F(SQLitePersistentCookieStoreTest, TestLoadCookiesForKey) {
+ InitializeStore(false, false);
+ base::Time t = base::Time::Now();
+ AddCookie("A", "B", "foo.bar", "/", t);
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookie("A", "B", "www.aaa.com", "/", t);
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookie("A", "B", "travel.aaa.com", "/", t);
+ t += base::TimeDelta::FromInternalValue(10);
+ AddCookie("A", "B", "www.bbb.com", "/", t);
+ DestroyStore();
+
+ store_ = new SQLitePersistentCookieStore(
+ temp_dir_.path().Append(kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
+ false, NULL, NULL);
+
+ // Posting a blocking task to db_thread_ makes sure that the DB thread waits
+ // until both Load and LoadCookiesForKey have been posted to its task queue.
+ background_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&SQLitePersistentCookieStoreTest::WaitOnDBEvent,
+ base::Unretained(this)));
+ store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded,
+ base::Unretained(this)));
+ store_->LoadCookiesForKey("aaa.com",
+ base::Bind(&SQLitePersistentCookieStoreTest::OnKeyLoaded,
+ base::Unretained(this)));
+ background_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&SQLitePersistentCookieStoreTest::WaitOnDBEvent,
+ base::Unretained(this)));
+
+ // Now the DB-thread queue contains:
+ // (active:)
+ // 1. Wait (on db_event)
+ // (pending:)
+ // 2. "Init And Chain-Load First Domain"
+ // 3. Priority Load (aaa.com)
+ // 4. Wait (on db_event)
+ db_thread_event_.Signal();
+ key_loaded_event_.Wait();
+ ASSERT_EQ(loaded_event_.IsSignaled(), false);
+ std::set<std::string> cookies_loaded;
+ for (CanonicalCookieVector::const_iterator it = cookies_.begin();
+ it != cookies_.end();
+ ++it) {
+ cookies_loaded.insert((*it)->Domain().c_str());
+ }
+ STLDeleteElements(&cookies_);
+ ASSERT_GT(4U, cookies_loaded.size());
+ ASSERT_EQ(true, cookies_loaded.find("www.aaa.com") != cookies_loaded.end());
+ ASSERT_EQ(true,
+ cookies_loaded.find("travel.aaa.com") != cookies_loaded.end());
+
+ db_thread_event_.Signal();
+ loaded_event_.Wait();
+ for (CanonicalCookieVector::const_iterator it = cookies_.begin();
+ it != cookies_.end();
+ ++it) {
+ cookies_loaded.insert((*it)->Domain().c_str());
+ }
+ ASSERT_EQ(4U, cookies_loaded.size());
+ ASSERT_EQ(cookies_loaded.find("foo.bar") != cookies_loaded.end(),
+ true);
+ ASSERT_EQ(cookies_loaded.find("www.bbb.com") != cookies_loaded.end(), true);
+ STLDeleteElements(&cookies_);
+}
+
+// Test that we can force the database to be written by calling Flush().
+TEST_F(SQLitePersistentCookieStoreTest, TestFlush) {
+ InitializeStore(false, false);
+ // File timestamps don't work well on all platforms, so we'll determine
+ // whether the DB file has been modified by checking its size.
+ base::FilePath path = temp_dir_.path().Append(kCookieFilename);
+ base::File::Info info;
+ ASSERT_TRUE(base::GetFileInfo(path, &info));
+ int64 base_size = info.size;
+
+ // Write some large cookies, so the DB will have to expand by several KB.
+ for (char c = 'a'; c < 'z'; ++c) {
+ // Each cookie needs a unique timestamp for creation_utc (see DB schema).
+ base::Time t = base::Time::Now() + base::TimeDelta::FromMicroseconds(c);
+ std::string name(1, c);
+ std::string value(1000, c);
+ AddCookie(name, value, "foo.bar", "/", t);
+ }
+
+ Flush();
+
+ // We forced a write, so now the file will be bigger.
+ ASSERT_TRUE(base::GetFileInfo(path, &info));
+ ASSERT_GT(info.size, base_size);
+}
+
+// Test loading old session cookies from the disk.
+TEST_F(SQLitePersistentCookieStoreTest, TestLoadOldSessionCookies) {
+ InitializeStore(false, true);
+
+ // Add a session cookie.
+ store_->AddCookie(net::CanonicalCookie(GURL(), "C", "D", "sessioncookie.com",
+ "/", base::Time::Now(), base::Time(),
+ base::Time::Now(), false, false, false,
+ net::COOKIE_PRIORITY_DEFAULT));
+
+ // Force the store to write its data to the disk.
+ DestroyStore();
+
+ // Create a store that loads session cookies and test that the session cookie
+ // was loaded.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(false, true, &cookies);
+
+ ASSERT_EQ(1U, cookies.size());
+ ASSERT_STREQ("sessioncookie.com", cookies[0]->Domain().c_str());
+ ASSERT_STREQ("C", cookies[0]->Name().c_str());
+ ASSERT_STREQ("D", cookies[0]->Value().c_str());
+ ASSERT_EQ(net::COOKIE_PRIORITY_DEFAULT, cookies[0]->Priority());
+
+ STLDeleteElements(&cookies);
+}
+
+// Test loading old session cookies from the disk.
+TEST_F(SQLitePersistentCookieStoreTest, TestDontLoadOldSessionCookies) {
+ InitializeStore(false, true);
+
+ // Add a session cookie.
+ store_->AddCookie(net::CanonicalCookie(GURL(), "C", "D", "sessioncookie.com",
+ "/", base::Time::Now(), base::Time(),
+ base::Time::Now(), false, false, false,
+ net::COOKIE_PRIORITY_DEFAULT));
+
+ // Force the store to write its data to the disk.
+ DestroyStore();
+
+ // Create a store that doesn't load old session cookies and test that the
+ // session cookie was not loaded.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(false, false, &cookies);
+ ASSERT_EQ(0U, cookies.size());
+
+ // The store should also delete the session cookie. Wait until that has been
+ // done.
+ DestroyStore();
+
+ // Create a store that loads old session cookies and test that the session
+ // cookie is gone.
+ CreateAndLoad(false, true, &cookies);
+ ASSERT_EQ(0U, cookies.size());
+}
+
+TEST_F(SQLitePersistentCookieStoreTest, PersistIsPersistent) {
+ InitializeStore(false, true);
+ static const char kSessionName[] = "session";
+ static const char kPersistentName[] = "persistent";
+
+ // Add a session cookie.
+ store_->AddCookie(net::CanonicalCookie(
+ GURL(), kSessionName, "val", "sessioncookie.com", "/", base::Time::Now(),
+ base::Time(), base::Time::Now(), false, false, false,
+ net::COOKIE_PRIORITY_DEFAULT));
+ // Add a persistent cookie.
+ store_->AddCookie(net::CanonicalCookie(
+ GURL(), kPersistentName, "val", "sessioncookie.com", "/",
+ base::Time::Now() - base::TimeDelta::FromDays(1),
+ base::Time::Now() + base::TimeDelta::FromDays(1), base::Time::Now(),
+ false, false, false, net::COOKIE_PRIORITY_DEFAULT));
+
+ // Force the store to write its data to the disk.
+ DestroyStore();
+
+ // Create a store that loads session cookie and test that the IsPersistent
+ // attribute is restored.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(false, true, &cookies);
+ ASSERT_EQ(2U, cookies.size());
+
+ std::map<std::string, net::CanonicalCookie*> cookie_map;
+ for (CanonicalCookieVector::const_iterator it = cookies.begin();
+ it != cookies.end();
+ ++it) {
+ cookie_map[(*it)->Name()] = *it;
+ }
+
+ std::map<std::string, net::CanonicalCookie*>::const_iterator it =
+ cookie_map.find(kSessionName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_FALSE(cookie_map[kSessionName]->IsPersistent());
+
+ it = cookie_map.find(kPersistentName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_TRUE(cookie_map[kPersistentName]->IsPersistent());
+
+ STLDeleteElements(&cookies);
+}
+
+TEST_F(SQLitePersistentCookieStoreTest, PriorityIsPersistent) {
+ static const char kLowName[] = "low";
+ static const char kMediumName[] = "medium";
+ static const char kHighName[] = "high";
+ static const char kCookieDomain[] = "sessioncookie.com";
+ static const char kCookieValue[] = "value";
+ static const char kCookiePath[] = "/";
+
+ InitializeStore(false, true);
+
+ // Add a low-priority persistent cookie.
+ store_->AddCookie(net::CanonicalCookie(
+ GURL(), kLowName, kCookieValue, kCookieDomain, kCookiePath,
+ base::Time::Now() - base::TimeDelta::FromMinutes(1),
+ base::Time::Now() + base::TimeDelta::FromDays(1), base::Time::Now(),
+ false, false, false, net::COOKIE_PRIORITY_LOW));
+
+ // Add a medium-priority persistent cookie.
+ store_->AddCookie(net::CanonicalCookie(
+ GURL(), kMediumName, kCookieValue, kCookieDomain, kCookiePath,
+ base::Time::Now() - base::TimeDelta::FromMinutes(2),
+ base::Time::Now() + base::TimeDelta::FromDays(1), base::Time::Now(),
+ false, false, false, net::COOKIE_PRIORITY_MEDIUM));
+
+ // Add a high-priority peristent cookie.
+ store_->AddCookie(net::CanonicalCookie(
+ GURL(), kHighName, kCookieValue, kCookieDomain, kCookiePath,
+ base::Time::Now() - base::TimeDelta::FromMinutes(3),
+ base::Time::Now() + base::TimeDelta::FromDays(1), base::Time::Now(),
+ false, false, false, net::COOKIE_PRIORITY_HIGH));
+
+ // Force the store to write its data to the disk.
+ DestroyStore();
+
+ // Create a store that loads session cookie and test that the priority
+ // attribute values are restored.
+ CanonicalCookieVector cookies;
+ CreateAndLoad(false, true, &cookies);
+ ASSERT_EQ(3U, cookies.size());
+
+ // Put the cookies into a map, by name, so we can easily find them.
+ std::map<std::string, net::CanonicalCookie*> cookie_map;
+ for (CanonicalCookieVector::const_iterator it = cookies.begin();
+ it != cookies.end();
+ ++it) {
+ cookie_map[(*it)->Name()] = *it;
+ }
+
+ // Validate that each cookie has the correct priority.
+ std::map<std::string, net::CanonicalCookie*>::const_iterator it =
+ cookie_map.find(kLowName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_EQ(net::COOKIE_PRIORITY_LOW, cookie_map[kLowName]->Priority());
+
+ it = cookie_map.find(kMediumName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookie_map[kMediumName]->Priority());
+
+ it = cookie_map.find(kHighName);
+ ASSERT_TRUE(it != cookie_map.end());
+ EXPECT_EQ(net::COOKIE_PRIORITY_HIGH, cookie_map[kHighName]->Priority());
+
+ STLDeleteElements(&cookies);
+}
+
+TEST_F(SQLitePersistentCookieStoreTest, UpdateToEncryption) {
+ CanonicalCookieVector cookies;
+
+ // Create unencrypted cookie store and write something to it.
+ InitializeStore(false, false);
+ AddCookie("name", "value123XYZ", "foo.bar", "/", base::Time::Now());
+ DestroyStore();
+
+ // Verify that "value" is visible in the file. This is necessary in order to
+ // have confidence in a later test that "encrypted_value" is not visible.
+ std::string contents = ReadRawDBContents();
+ EXPECT_NE(0U, contents.length());
+ EXPECT_NE(contents.find("value123XYZ"), std::string::npos);
+
+ // Create encrypted cookie store and ensure old cookie still reads.
+ STLDeleteElements(&cookies_);
+ EXPECT_EQ(0U, cookies_.size());
+ CreateAndLoad(true, false, &cookies);
+ EXPECT_EQ(1U, cookies_.size());
+ EXPECT_EQ("name", cookies_[0]->Name());
+ EXPECT_EQ("value123XYZ", cookies_[0]->Value());
+
+ // Make sure we can update existing cookie and add new cookie as encrypted.
+ store_->DeleteCookie(*(cookies_[0]));
+ AddCookie("name", "encrypted_value123XYZ", "foo.bar", "/", base::Time::Now());
+ AddCookie("other", "something456ABC", "foo.bar", "/",
+ base::Time::Now() + base::TimeDelta::FromInternalValue(10));
+ DestroyStore();
+ STLDeleteElements(&cookies_);
+ CreateAndLoad(true, false, &cookies);
+ EXPECT_EQ(2U, cookies_.size());
+ net::CanonicalCookie* cookie_name = NULL;
+ net::CanonicalCookie* cookie_other = NULL;
+ if (cookies_[0]->Name() == "name") {
+ cookie_name = cookies_[0];
+ cookie_other = cookies_[1];
+ } else {
+ cookie_name = cookies_[1];
+ cookie_other = cookies_[0];
+ }
+ EXPECT_EQ("encrypted_value123XYZ", cookie_name->Value());
+ EXPECT_EQ("something456ABC", cookie_other->Value());
+ DestroyStore();
+ STLDeleteElements(&cookies_);
+
+ // Examine the real record to make sure plaintext version doesn't exist.
+ sql::Connection db;
+ sql::Statement smt;
+ int resultcount = 0;
+ ASSERT_TRUE(db.Open(temp_dir_.path().Append(kCookieFilename)));
+ smt.Assign(db.GetCachedStatement(SQL_FROM_HERE,
+ "SELECT * "
+ "FROM cookies "
+ "WHERE host_key = 'foo.bar'"));
+ while (smt.Step()) {
+ resultcount++;
+ for (int i=0; i < smt.ColumnCount(); i++) {
+ EXPECT_EQ(smt.ColumnString(i).find("value"), std::string::npos);
+ EXPECT_EQ(smt.ColumnString(i).find("something"), std::string::npos);
+ }
+ }
+ EXPECT_EQ(2, resultcount);
+
+ // Verify that "encrypted_value" is NOT visible in the file.
+ contents = ReadRawDBContents();
+ EXPECT_NE(0U, contents.length());
+ EXPECT_EQ(contents.find("encrypted_value123XYZ"), std::string::npos);
+ EXPECT_EQ(contents.find("something456ABC"), std::string::npos);
+}
+
+} // namespace content
« no previous file with comments | « content/browser/net/sqlite_persistent_cookie_store_perftest.cc ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698