Process Alt-Svc headers.
[chromium-blink-merge.git] / content / browser / net / quota_policy_cookie_store_unittest.cc
blob070d52482ef3facacab9cd7473be00cc53156b80
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/memory/scoped_vector.h"
10 #include "base/run_loop.h"
11 #include "base/stl_util.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/test/sequenced_worker_pool_owner.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "base/time/time.h"
16 #include "content/browser/net/quota_policy_cookie_store.h"
17 #include "content/public/test/mock_special_storage_policy.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "net/base/test_data_directory.h"
20 #include "net/cookies/cookie_util.h"
21 #include "net/ssl/ssl_client_cert_type.h"
22 #include "net/test/cert_test_util.h"
23 #include "sql/statement.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 namespace {
27 const base::FilePath::CharType kTestCookiesFilename[] =
28 FILE_PATH_LITERAL("Cookies");
31 namespace content {
32 namespace {
34 typedef std::vector<net::CanonicalCookie*> CanonicalCookieVector;
36 class QuotaPolicyCookieStoreTest : public testing::Test {
37 public:
38 QuotaPolicyCookieStoreTest()
39 : pool_owner_(new base::SequencedWorkerPoolOwner(3, "Background Pool")),
40 loaded_event_(false, false),
41 destroy_event_(false, false) {
44 void OnLoaded(const CanonicalCookieVector& cookies) {
45 cookies_ = cookies;
46 loaded_event_.Signal();
49 void Load(CanonicalCookieVector* cookies) {
50 EXPECT_FALSE(loaded_event_.IsSignaled());
51 store_->Load(base::Bind(&QuotaPolicyCookieStoreTest::OnLoaded,
52 base::Unretained(this)));
53 loaded_event_.Wait();
54 *cookies = cookies_;
57 void ReleaseStore() {
58 EXPECT_TRUE(background_task_runner()->RunsTasksOnCurrentThread());
59 store_ = nullptr;
60 destroy_event_.Signal();
63 void DestroyStoreOnBackgroundThread() {
64 background_task_runner()->PostTask(
65 FROM_HERE, base::Bind(&QuotaPolicyCookieStoreTest::ReleaseStore,
66 base::Unretained(this)));
67 destroy_event_.Wait();
68 DestroyStore();
71 protected:
72 scoped_refptr<base::SequencedTaskRunner> background_task_runner() {
73 return pool_owner_->pool()->GetSequencedTaskRunner(
74 pool_owner_->pool()->GetNamedSequenceToken("background"));
77 scoped_refptr<base::SequencedTaskRunner> client_task_runner() {
78 return pool_owner_->pool()->GetSequencedTaskRunner(
79 pool_owner_->pool()->GetNamedSequenceToken("client"));
82 void CreateAndLoad(storage::SpecialStoragePolicy* storage_policy,
83 CanonicalCookieVector* cookies) {
84 scoped_refptr<net::SQLitePersistentCookieStore> sqlite_store(
85 new net::SQLitePersistentCookieStore(
86 temp_dir_.path().Append(kTestCookiesFilename),
87 client_task_runner(),
88 background_task_runner(),
89 true, nullptr));
90 store_ = new QuotaPolicyCookieStore(sqlite_store.get(), storage_policy);
91 Load(cookies);
94 // Adds a persistent cookie to store_.
95 void AddCookie(const std::string& name,
96 const std::string& value,
97 const std::string& domain,
98 const std::string& path,
99 const base::Time& creation) {
100 store_->AddCookie(
101 net::CanonicalCookie(
102 GURL(), name, value, domain, path, creation, creation, creation,
103 false, false, false, net::COOKIE_PRIORITY_DEFAULT));
106 void DestroyStore() {
107 store_ = nullptr;
108 // Ensure that |store_|'s destructor has run by shutting down the pool and
109 // then forcing the pool to be destructed. This will ensure that all the
110 // tasks that block pool shutdown (e.g. |store_|'s cleanup) have run before
111 // yielding control.
112 pool_owner_->pool()->FlushForTesting();
113 pool_owner_->pool()->Shutdown();
114 pool_owner_.reset(new base::SequencedWorkerPoolOwner(3, "Background Pool"));
117 void SetUp() override {
118 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
121 void TearDown() override {
122 DestroyStore();
123 pool_owner_->pool()->Shutdown();
126 TestBrowserThreadBundle bundle_;
127 scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
128 base::WaitableEvent loaded_event_;
129 base::WaitableEvent destroy_event_;
130 base::ScopedTempDir temp_dir_;
131 scoped_refptr<QuotaPolicyCookieStore> store_;
132 CanonicalCookieVector cookies_;
135 // Test if data is stored as expected in the QuotaPolicy database.
136 TEST_F(QuotaPolicyCookieStoreTest, TestPersistence) {
137 CanonicalCookieVector cookies;
138 CreateAndLoad(nullptr, &cookies);
139 ASSERT_EQ(0U, cookies.size());
141 base::Time t = base::Time::Now();
142 AddCookie("A", "B", "foo.com", "/", t);
143 t += base::TimeDelta::FromInternalValue(10);
144 AddCookie("A", "B", "persistent.com", "/", t);
146 // Replace the store, which forces the current store to flush data to
147 // disk. Then, after reloading the store, confirm that the data was flushed by
148 // making sure it loads successfully. This ensures that all pending commits
149 // are made to the store before allowing it to be closed.
150 DestroyStore();
152 // Reload and test for persistence.
153 STLDeleteElements(&cookies);
154 CreateAndLoad(nullptr, &cookies);
155 EXPECT_EQ(2U, cookies.size());
156 bool found_foo_cookie = false;
157 bool found_persistent_cookie = false;
158 for (const auto& cookie : cookies) {
159 if (cookie->Domain() == "foo.com")
160 found_foo_cookie = true;
161 else if (cookie->Domain() == "persistent.com")
162 found_persistent_cookie = true;
164 EXPECT_TRUE(found_foo_cookie);
165 EXPECT_TRUE(found_persistent_cookie);
167 // Now delete the cookies and check persistence again.
168 store_->DeleteCookie(*cookies[0]);
169 store_->DeleteCookie(*cookies[1]);
170 DestroyStore();
172 // Reload and check if the cookies have been removed.
173 STLDeleteElements(&cookies);
174 CreateAndLoad(nullptr, &cookies);
175 EXPECT_EQ(0U, cookies.size());
176 STLDeleteElements(&cookies);
179 // Test if data is stored as expected in the QuotaPolicy database.
180 TEST_F(QuotaPolicyCookieStoreTest, TestPolicy) {
181 CanonicalCookieVector cookies;
182 CreateAndLoad(nullptr, &cookies);
183 ASSERT_EQ(0U, cookies.size());
185 base::Time t = base::Time::Now();
186 AddCookie("A", "B", "foo.com", "/", t);
187 t += base::TimeDelta::FromInternalValue(10);
188 AddCookie("A", "B", "persistent.com", "/", t);
189 t += base::TimeDelta::FromInternalValue(10);
190 AddCookie("A", "B", "nonpersistent.com", "/", t);
192 // Replace the store, which forces the current store to flush data to
193 // disk. Then, after reloading the store, confirm that the data was flushed by
194 // making sure it loads successfully. This ensures that all pending commits
195 // are made to the store before allowing it to be closed.
196 DestroyStore();
197 // Specify storage policy that makes "nonpersistent.com" session only.
198 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy =
199 new content::MockSpecialStoragePolicy();
200 storage_policy->AddSessionOnly(
201 net::cookie_util::CookieOriginToURL("nonpersistent.com", false));
203 // Reload and test for persistence.
204 STLDeleteElements(&cookies);
205 CreateAndLoad(storage_policy.get(), &cookies);
206 EXPECT_EQ(3U, cookies.size());
208 t += base::TimeDelta::FromInternalValue(10);
209 AddCookie("A", "B", "nonpersistent.com", "/second", t);
211 // Now close the store, and "nonpersistent.com" should be deleted according to
212 // policy.
213 DestroyStore();
214 STLDeleteElements(&cookies);
215 CreateAndLoad(nullptr, &cookies);
217 EXPECT_EQ(2U, cookies.size());
218 for (const auto& cookie : cookies) {
219 EXPECT_NE("nonpersistent.com", cookie->Domain());
221 STLDeleteElements(&cookies);
224 TEST_F(QuotaPolicyCookieStoreTest, ForceKeepSessionState) {
225 CanonicalCookieVector cookies;
226 CreateAndLoad(nullptr, &cookies);
227 ASSERT_EQ(0U, cookies.size());
229 base::Time t = base::Time::Now();
230 AddCookie("A", "B", "foo.com", "/", t);
232 // Recreate |store_| with a storage policy that makes "nonpersistent.com"
233 // session only, but then instruct the store to forcibly keep all cookies.
234 DestroyStore();
235 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy =
236 new content::MockSpecialStoragePolicy();
237 storage_policy->AddSessionOnly(
238 net::cookie_util::CookieOriginToURL("nonpersistent.com", false));
240 // Reload and test for persistence
241 STLDeleteElements(&cookies);
242 CreateAndLoad(storage_policy.get(), &cookies);
243 EXPECT_EQ(1U, cookies.size());
245 t += base::TimeDelta::FromInternalValue(10);
246 AddCookie("A", "B", "persistent.com", "/", t);
247 t += base::TimeDelta::FromInternalValue(10);
248 AddCookie("A", "B", "nonpersistent.com", "/", t);
250 // Now close the store, but the "nonpersistent.com" cookie should not be
251 // deleted.
252 store_->SetForceKeepSessionState();
253 DestroyStore();
254 STLDeleteElements(&cookies);
255 CreateAndLoad(nullptr, &cookies);
257 EXPECT_EQ(3U, cookies.size());
258 STLDeleteElements(&cookies);
261 // Tests that the special storage policy is properly applied even when the store
262 // is destroyed on a background thread.
263 TEST_F(QuotaPolicyCookieStoreTest, TestDestroyOnBackgroundThread) {
264 // Specify storage policy that makes "nonpersistent.com" session only.
265 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy =
266 new content::MockSpecialStoragePolicy();
267 storage_policy->AddSessionOnly(
268 net::cookie_util::CookieOriginToURL("nonpersistent.com", false));
270 CanonicalCookieVector cookies;
271 CreateAndLoad(storage_policy.get(), &cookies);
272 ASSERT_EQ(0U, cookies.size());
274 base::Time t = base::Time::Now();
275 AddCookie("A", "B", "nonpersistent.com", "/", t);
277 // Replace the store, which forces the current store to flush data to
278 // disk. Then, after reloading the store, confirm that the data was flushed by
279 // making sure it loads successfully. This ensures that all pending commits
280 // are made to the store before allowing it to be closed.
281 DestroyStoreOnBackgroundThread();
283 // Reload and test for persistence.
284 STLDeleteElements(&cookies);
285 CreateAndLoad(storage_policy.get(), &cookies);
286 EXPECT_EQ(0U, cookies.size());
288 STLDeleteElements(&cookies);
291 } // namespace
292 } // namespace content