Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / browser / net / quota_policy_cookie_store_unittest.cc
blobf7987c553510e81966abfb12169d471cd0e0d1a8
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/files/file_util.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/run_loop.h"
10 #include "base/stl_util.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/test/sequenced_worker_pool_owner.h"
13 #include "base/threading/sequenced_worker_pool.h"
14 #include "base/time/time.h"
15 #include "content/browser/net/quota_policy_cookie_store.h"
16 #include "content/public/test/mock_special_storage_policy.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "net/base/test_data_directory.h"
19 #include "net/cookies/cookie_util.h"
20 #include "net/ssl/ssl_client_cert_type.h"
21 #include "net/test/cert_test_util.h"
22 #include "sql/statement.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace {
26 const base::FilePath::CharType kTestCookiesFilename[] =
27 FILE_PATH_LITERAL("Cookies");
30 namespace content {
31 namespace {
33 typedef std::vector<net::CanonicalCookie*> CanonicalCookieVector;
35 class QuotaPolicyCookieStoreTest : public testing::Test {
36 public:
37 QuotaPolicyCookieStoreTest()
38 : pool_owner_(new base::SequencedWorkerPoolOwner(3, "Background Pool")),
39 loaded_event_(false, false),
40 destroy_event_(false, false) {
43 void OnLoaded(const CanonicalCookieVector& cookies) {
44 cookies_ = cookies;
45 loaded_event_.Signal();
48 void Load(CanonicalCookieVector* cookies) {
49 EXPECT_FALSE(loaded_event_.IsSignaled());
50 store_->Load(base::Bind(&QuotaPolicyCookieStoreTest::OnLoaded,
51 base::Unretained(this)));
52 loaded_event_.Wait();
53 *cookies = cookies_;
56 void ReleaseStore() {
57 EXPECT_TRUE(background_task_runner()->RunsTasksOnCurrentThread());
58 store_ = nullptr;
59 destroy_event_.Signal();
62 void DestroyStoreOnBackgroundThread() {
63 background_task_runner()->PostTask(
64 FROM_HERE, base::Bind(&QuotaPolicyCookieStoreTest::ReleaseStore,
65 base::Unretained(this)));
66 destroy_event_.Wait();
67 DestroyStore();
70 protected:
71 scoped_refptr<base::SequencedTaskRunner> background_task_runner() {
72 return pool_owner_->pool()->GetSequencedTaskRunner(
73 pool_owner_->pool()->GetNamedSequenceToken("background"));
76 scoped_refptr<base::SequencedTaskRunner> client_task_runner() {
77 return pool_owner_->pool()->GetSequencedTaskRunner(
78 pool_owner_->pool()->GetNamedSequenceToken("client"));
81 void CreateAndLoad(storage::SpecialStoragePolicy* storage_policy,
82 CanonicalCookieVector* cookies) {
83 scoped_refptr<net::SQLitePersistentCookieStore> sqlite_store(
84 new net::SQLitePersistentCookieStore(
85 temp_dir_.path().Append(kTestCookiesFilename),
86 client_task_runner(),
87 background_task_runner(),
88 true, nullptr));
89 store_ = new QuotaPolicyCookieStore(sqlite_store.get(), storage_policy);
90 Load(cookies);
93 // Adds a persistent cookie to store_.
94 void AddCookie(const std::string& name,
95 const std::string& value,
96 const std::string& domain,
97 const std::string& path,
98 const base::Time& creation) {
99 store_->AddCookie(
100 net::CanonicalCookie(
101 GURL(), name, value, domain, path, creation, creation, creation,
102 false, false, false, net::COOKIE_PRIORITY_DEFAULT));
105 void DestroyStore() {
106 store_ = nullptr;
107 // Ensure that |store_|'s destructor has run by shutting down the pool and
108 // then forcing the pool to be destructed. This will ensure that all the
109 // tasks that block pool shutdown (e.g. |store_|'s cleanup) have run before
110 // yielding control.
111 pool_owner_->pool()->FlushForTesting();
112 pool_owner_->pool()->Shutdown();
113 pool_owner_.reset(new base::SequencedWorkerPoolOwner(3, "Background Pool"));
116 void SetUp() override {
117 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
120 void TearDown() override {
121 DestroyStore();
122 pool_owner_->pool()->Shutdown();
125 TestBrowserThreadBundle bundle_;
126 scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
127 base::WaitableEvent loaded_event_;
128 base::WaitableEvent destroy_event_;
129 base::ScopedTempDir temp_dir_;
130 scoped_refptr<QuotaPolicyCookieStore> store_;
131 CanonicalCookieVector cookies_;
134 // Test if data is stored as expected in the QuotaPolicy database.
135 TEST_F(QuotaPolicyCookieStoreTest, TestPersistence) {
136 CanonicalCookieVector cookies;
137 CreateAndLoad(nullptr, &cookies);
138 ASSERT_EQ(0U, cookies.size());
140 base::Time t = base::Time::Now();
141 AddCookie("A", "B", "foo.com", "/", t);
142 t += base::TimeDelta::FromInternalValue(10);
143 AddCookie("A", "B", "persistent.com", "/", t);
145 // Replace the store, which forces the current store to flush data to
146 // disk. Then, after reloading the store, confirm that the data was flushed by
147 // making sure it loads successfully. This ensures that all pending commits
148 // are made to the store before allowing it to be closed.
149 DestroyStore();
151 // Reload and test for persistence.
152 STLDeleteElements(&cookies);
153 CreateAndLoad(nullptr, &cookies);
154 EXPECT_EQ(2U, cookies.size());
155 bool found_foo_cookie = false;
156 bool found_persistent_cookie = false;
157 for (const auto& cookie : cookies) {
158 if (cookie->Domain() == "foo.com")
159 found_foo_cookie = true;
160 else if (cookie->Domain() == "persistent.com")
161 found_persistent_cookie = true;
163 EXPECT_TRUE(found_foo_cookie);
164 EXPECT_TRUE(found_persistent_cookie);
166 // Now delete the cookies and check persistence again.
167 store_->DeleteCookie(*cookies[0]);
168 store_->DeleteCookie(*cookies[1]);
169 DestroyStore();
171 // Reload and check if the cookies have been removed.
172 STLDeleteElements(&cookies);
173 CreateAndLoad(nullptr, &cookies);
174 EXPECT_EQ(0U, cookies.size());
175 STLDeleteElements(&cookies);
178 // Test if data is stored as expected in the QuotaPolicy database.
179 TEST_F(QuotaPolicyCookieStoreTest, TestPolicy) {
180 CanonicalCookieVector cookies;
181 CreateAndLoad(nullptr, &cookies);
182 ASSERT_EQ(0U, cookies.size());
184 base::Time t = base::Time::Now();
185 AddCookie("A", "B", "foo.com", "/", t);
186 t += base::TimeDelta::FromInternalValue(10);
187 AddCookie("A", "B", "persistent.com", "/", t);
188 t += base::TimeDelta::FromInternalValue(10);
189 AddCookie("A", "B", "nonpersistent.com", "/", t);
191 // Replace the store, which forces the current store to flush data to
192 // disk. Then, after reloading the store, confirm that the data was flushed by
193 // making sure it loads successfully. This ensures that all pending commits
194 // are made to the store before allowing it to be closed.
195 DestroyStore();
196 // Specify storage policy that makes "nonpersistent.com" session only.
197 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy =
198 new content::MockSpecialStoragePolicy();
199 storage_policy->AddSessionOnly(
200 net::cookie_util::CookieOriginToURL("nonpersistent.com", false));
202 // Reload and test for persistence.
203 STLDeleteElements(&cookies);
204 CreateAndLoad(storage_policy.get(), &cookies);
205 EXPECT_EQ(3U, cookies.size());
207 t += base::TimeDelta::FromInternalValue(10);
208 AddCookie("A", "B", "nonpersistent.com", "/second", t);
210 // Now close the store, and "nonpersistent.com" should be deleted according to
211 // policy.
212 DestroyStore();
213 STLDeleteElements(&cookies);
214 CreateAndLoad(nullptr, &cookies);
216 EXPECT_EQ(2U, cookies.size());
217 for (const auto& cookie : cookies) {
218 EXPECT_NE("nonpersistent.com", cookie->Domain());
220 STLDeleteElements(&cookies);
223 TEST_F(QuotaPolicyCookieStoreTest, ForceKeepSessionState) {
224 CanonicalCookieVector cookies;
225 CreateAndLoad(nullptr, &cookies);
226 ASSERT_EQ(0U, cookies.size());
228 base::Time t = base::Time::Now();
229 AddCookie("A", "B", "foo.com", "/", t);
231 // Recreate |store_| with a storage policy that makes "nonpersistent.com"
232 // session only, but then instruct the store to forcibly keep all cookies.
233 DestroyStore();
234 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy =
235 new content::MockSpecialStoragePolicy();
236 storage_policy->AddSessionOnly(
237 net::cookie_util::CookieOriginToURL("nonpersistent.com", false));
239 // Reload and test for persistence
240 STLDeleteElements(&cookies);
241 CreateAndLoad(storage_policy.get(), &cookies);
242 EXPECT_EQ(1U, cookies.size());
244 t += base::TimeDelta::FromInternalValue(10);
245 AddCookie("A", "B", "persistent.com", "/", t);
246 t += base::TimeDelta::FromInternalValue(10);
247 AddCookie("A", "B", "nonpersistent.com", "/", t);
249 // Now close the store, but the "nonpersistent.com" cookie should not be
250 // deleted.
251 store_->SetForceKeepSessionState();
252 DestroyStore();
253 STLDeleteElements(&cookies);
254 CreateAndLoad(nullptr, &cookies);
256 EXPECT_EQ(3U, cookies.size());
257 STLDeleteElements(&cookies);
260 // Tests that the special storage policy is properly applied even when the store
261 // is destroyed on a background thread.
262 TEST_F(QuotaPolicyCookieStoreTest, TestDestroyOnBackgroundThread) {
263 // Specify storage policy that makes "nonpersistent.com" session only.
264 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy =
265 new content::MockSpecialStoragePolicy();
266 storage_policy->AddSessionOnly(
267 net::cookie_util::CookieOriginToURL("nonpersistent.com", false));
269 CanonicalCookieVector cookies;
270 CreateAndLoad(storage_policy.get(), &cookies);
271 ASSERT_EQ(0U, cookies.size());
273 base::Time t = base::Time::Now();
274 AddCookie("A", "B", "nonpersistent.com", "/", t);
276 // Replace the store, which forces the current store to flush data to
277 // disk. Then, after reloading the store, confirm that the data was flushed by
278 // making sure it loads successfully. This ensures that all pending commits
279 // are made to the store before allowing it to be closed.
280 DestroyStoreOnBackgroundThread();
282 // Reload and test for persistence.
283 STLDeleteElements(&cookies);
284 CreateAndLoad(storage_policy.get(), &cookies);
285 EXPECT_EQ(0U, cookies.size());
287 STLDeleteElements(&cookies);
290 } // namespace
291 } // namespace content