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

Side by Side Diff: content/browser/storage_partition_impl_unittest.cc

Issue 1979733002: Add ability to clear content licenses (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: changes Created 4 years, 6 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
14 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
15 #include "content/browser/browser_thread_impl.h" 15 #include "content/browser/browser_thread_impl.h"
16 #include "content/browser/gpu/shader_disk_cache.h" 16 #include "content/browser/gpu/shader_disk_cache.h"
17 #include "content/browser/quota/mock_quota_manager.h" 17 #include "content/browser/quota/mock_quota_manager.h"
18 #include "content/browser/storage_partition_impl.h" 18 #include "content/browser/storage_partition_impl.h"
19 #include "content/public/browser/local_storage_usage_info.h" 19 #include "content/public/browser/local_storage_usage_info.h"
20 #include "content/public/browser/storage_partition.h" 20 #include "content/public/browser/storage_partition.h"
21 #include "content/public/test/mock_special_storage_policy.h" 21 #include "content/public/test/mock_special_storage_policy.h"
22 #include "content/public/test/test_browser_context.h" 22 #include "content/public/test/test_browser_context.h"
23 #include "content/public/test/test_browser_thread.h" 23 #include "content/public/test/test_browser_thread.h"
24 #include "content/public/test/test_browser_thread_bundle.h" 24 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "net/base/test_completion_callback.h" 25 #include "net/base/test_completion_callback.h"
26 #include "net/cookies/canonical_cookie.h" 26 #include "net/cookies/canonical_cookie.h"
27 #include "net/cookies/cookie_store.h" 27 #include "net/cookies/cookie_store.h"
28 #include "net/url_request/url_request_context.h" 28 #include "net/url_request/url_request_context.h"
29 #include "net/url_request/url_request_context_getter.h" 29 #include "net/url_request/url_request_context_getter.h"
30 #include "storage/browser/fileapi/async_file_util.h"
31 #include "storage/browser/fileapi/file_system_context.h"
32 #include "storage/browser/fileapi/file_system_operation_context.h"
33 #include "storage/browser/fileapi/isolated_context.h"
30 #include "storage/browser/quota/quota_manager.h" 34 #include "storage/browser/quota/quota_manager.h"
31 #include "testing/gtest/include/gtest/gtest.h" 35 #include "testing/gtest/include/gtest/gtest.h"
32 36
33 using net::CanonicalCookie; 37 using net::CanonicalCookie;
34 38
35 namespace content { 39 namespace content {
36 namespace { 40 namespace {
37 41
38 const int kDefaultClientId = 42; 42 const int kDefaultClientId = 42;
39 const char kCacheKey[] = "key"; 43 const char kCacheKey[] = "key";
40 const char kCacheValue[] = "cached value"; 44 const char kCacheValue[] = "cached value";
41 45
42 const char kTestOrigin1[] = "http://host1:1/"; 46 const char kTestOrigin1[] = "http://host1:1/";
43 const char kTestOrigin2[] = "http://host2:1/"; 47 const char kTestOrigin2[] = "http://host2:1/";
44 const char kTestOrigin3[] = "http://host3:1/"; 48 const char kTestOrigin3[] = "http://host3:1/";
45 const char kTestOriginDevTools[] = "chrome-devtools://abcdefghijklmnopqrstuvw/"; 49 const char kTestOriginDevTools[] = "chrome-devtools://abcdefghijklmnopqrstuvw/";
46 50
51 const char kPluginPrivateRootName[] = "pluginprivate";
nhiroki 2016/05/24 01:40:03 ppapi::kPluginPrivateRootName may work.
jrummell 2016/05/24 22:15:33 Done.
52 const char kWidevineCdmPluginId[] = "application_x-ppapi-widevine-cdm";
53 const char kClearKeyCdmPluginId[] = "application_x-ppapi-clearkey-cdm";
54
47 const GURL kOrigin1(kTestOrigin1); 55 const GURL kOrigin1(kTestOrigin1);
48 const GURL kOrigin2(kTestOrigin2); 56 const GURL kOrigin2(kTestOrigin2);
49 const GURL kOrigin3(kTestOrigin3); 57 const GURL kOrigin3(kTestOrigin3);
50 const GURL kOriginDevTools(kTestOriginDevTools); 58 const GURL kOriginDevTools(kTestOriginDevTools);
51 59
52 const base::FilePath::CharType kDomStorageOrigin1[] = 60 const base::FilePath::CharType kDomStorageOrigin1[] =
53 FILE_PATH_LITERAL("http_host1_1.localstorage"); 61 FILE_PATH_LITERAL("http_host1_1.localstorage");
54 62
55 const base::FilePath::CharType kDomStorageOrigin2[] = 63 const base::FilePath::CharType kDomStorageOrigin2[] =
56 FILE_PATH_LITERAL("http_host2_1.localstorage"); 64 FILE_PATH_LITERAL("http_host2_1.localstorage");
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 TestBrowserContext* profile_; 232 TestBrowserContext* profile_;
225 content::DOMStorageContext* dom_storage_context_; 233 content::DOMStorageContext* dom_storage_context_;
226 234
227 std::vector<content::LocalStorageUsageInfo> infos_; 235 std::vector<content::LocalStorageUsageInfo> infos_;
228 236
229 AwaitCompletionHelper await_completion_; 237 AwaitCompletionHelper await_completion_;
230 238
231 DISALLOW_COPY_AND_ASSIGN(RemoveLocalStorageTester); 239 DISALLOW_COPY_AND_ASSIGN(RemoveLocalStorageTester);
232 }; 240 };
233 241
242 class RemovePluginPrivateDataTester {
243 public:
244 explicit RemovePluginPrivateDataTester(
245 storage::FileSystemContext* filesystem_context)
246 : filesystem_context_(filesystem_context) {}
247
248 // Add some files to the PluginPrivateFileSystem. They are created as follows:
249 // kOrigin1 - ClearKey - 1 file - timestamp 10 days ago
250 // kOrigin2 - Widevine - 2 files - timestamps now and 60 days ago
251 void AddPluginPrivateTestData() {
252 base::Time now = base::Time::Now();
253 base::Time ten_days_ago = now - base::TimeDelta::FromDays(10);
254 base::Time sixty_days_ago = now - base::TimeDelta::FromDays(60);
255
256 // Create a PluginPrivateFileSystem for ClearKey and add a single file
257 // with a timestamp of 1 day ago.
258 std::string clearkey_fsid =
259 CreateFileSystem(kClearKeyCdmPluginId, kOrigin1);
260 storage::FileSystemURL clearkey_file =
261 CreateFile(kOrigin1, clearkey_fsid, "foo");
262 SetFileTimestamp(clearkey_file, ten_days_ago);
263
264 // Create a second PluginPrivateFileSystem for Widevine and add two files
265 // with different times.
266 std::string widevine_fsid =
267 CreateFileSystem(kWidevineCdmPluginId, kOrigin2);
268 storage::FileSystemURL widevine_file1 =
269 CreateFile(kOrigin2, widevine_fsid, "bar1");
270 storage::FileSystemURL widevine_file2 =
271 CreateFile(kOrigin2, widevine_fsid, "bar2");
272 SetFileTimestamp(widevine_file1, now);
273 SetFileTimestamp(widevine_file2, sixty_days_ago);
274 }
275
276 // Returns true, if the given origin exists in a PluginPrivateFileSystem.
277 bool DataExistsForOrigin(const GURL& origin) {
278 storage::FileSystemBackend* backend =
279 filesystem_context_->GetFileSystemBackend(
280 storage::kFileSystemTypePluginPrivate);
281 storage::FileSystemQuotaUtil* quota_util = backend->GetQuotaUtil();
282
283 // Determine the set of origins used.
284 std::set<GURL> origins;
285 quota_util->GetOriginsForTypeOnFileTaskRunner(
286 storage::kFileSystemTypePluginPrivate, &origins);
287 return origins.find(origin) != origins.end();
288 }
289
290 private:
291 // Creates a PluginPrivateFileSystem for the |plugin_name| and |origin|
292 // provided. Returns the file system ID for the created
293 // PluginPrivateFileSystem.
294 std::string CreateFileSystem(const std::string& plugin_name,
295 const GURL& origin) {
296 AwaitCompletionHelper await_completion;
297 std::string fsid = storage::IsolatedContext::GetInstance()
298 ->RegisterFileSystemForVirtualPath(
299 storage::kFileSystemTypePluginPrivate,
300 kPluginPrivateRootName, base::FilePath());
301 EXPECT_TRUE(storage::ValidateIsolatedFileSystemId(fsid));
302 filesystem_context_->OpenPluginPrivateFileSystem(
303 origin, storage::kFileSystemTypePluginPrivate, fsid, plugin_name,
304 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
305 base::Bind(&RemovePluginPrivateDataTester::OnFileSystemOpened,
306 base::Unretained(this), &await_completion));
307 await_completion.BlockUntilNotified();
308 return fsid;
309 }
310
311 // Creates a file named |file_name| in the PluginPrivateFileSystem identified
312 // by |origin| and |fsid|. Returns the URL for the created file. The file
313 // musty not already exist or the test will fail.
nhiroki 2016/05/24 01:40:03 s/musty/must
jrummell 2016/05/24 22:15:33 Done.
314 storage::FileSystemURL CreateFile(const GURL& origin,
315 const std::string& fsid,
316 const std::string& file_name) {
317 AwaitCompletionHelper await_completion;
318 std::string root = storage::GetIsolatedFileSystemRootURIString(
319 origin, fsid, kPluginPrivateRootName);
320 storage::FileSystemURL file_url =
321 filesystem_context_->CrackURL(GURL(root + file_name));
322 storage::AsyncFileUtil* file_util = filesystem_context_->GetAsyncFileUtil(
323 storage::kFileSystemTypePluginPrivate);
324 std::unique_ptr<storage::FileSystemOperationContext> operation_context =
325 base::WrapUnique(
326 new storage::FileSystemOperationContext(filesystem_context_));
327 operation_context->set_allowed_bytes_growth(
328 storage::QuotaManager::kNoLimit);
329 file_util->EnsureFileExists(
330 std::move(operation_context), file_url,
331 base::Bind(&RemovePluginPrivateDataTester::OnFileCreated,
332 base::Unretained(this), &await_completion));
333 await_completion.BlockUntilNotified();
334 return file_url;
335 }
336
337 // Sets the last_access_time and last_modified_time to |time_stamp| on the
338 // file specified by |file_url|. The file must already exist.
339 void SetFileTimestamp(const storage::FileSystemURL& file_url,
340 const base::Time& time_stamp) {
341 AwaitCompletionHelper await_completion;
342 storage::AsyncFileUtil* file_util = filesystem_context_->GetAsyncFileUtil(
343 storage::kFileSystemTypePluginPrivate);
344 std::unique_ptr<storage::FileSystemOperationContext> operation_context =
345 base::WrapUnique(
346 new storage::FileSystemOperationContext(filesystem_context_));
347 file_util->Touch(std::move(operation_context), file_url, time_stamp,
348 time_stamp,
349 base::Bind(&RemovePluginPrivateDataTester::OnFileTouched,
350 base::Unretained(this), &await_completion));
351 await_completion.BlockUntilNotified();
352 }
353
354 void OnFileSystemOpened(AwaitCompletionHelper* await_completion,
355 base::File::Error result) {
356 EXPECT_EQ(base::File::FILE_OK, result) << base::File::ErrorToString(result);
357 await_completion->Notify();
358 }
359
360 void OnFileCreated(AwaitCompletionHelper* await_completion,
361 base::File::Error result,
362 bool created) {
363 EXPECT_EQ(base::File::FILE_OK, result) << base::File::ErrorToString(result);
364 EXPECT_TRUE(created);
365 await_completion->Notify();
366 }
367
368 void OnFileTouched(AwaitCompletionHelper* await_completion,
369 base::File::Error result) {
370 EXPECT_EQ(base::File::FILE_OK, result) << base::File::ErrorToString(result);
371 await_completion->Notify();
372 }
373
374 // We don't own this pointer.
375 storage::FileSystemContext* filesystem_context_;
376
377 DISALLOW_COPY_AND_ASSIGN(RemovePluginPrivateDataTester);
378 };
379
234 bool IsWebSafeSchemeForTest(const std::string& scheme) { 380 bool IsWebSafeSchemeForTest(const std::string& scheme) {
235 return scheme == "http"; 381 return scheme == "http";
236 } 382 }
237 383
238 bool DoesOriginMatchForUnprotectedWeb( 384 bool DoesOriginMatchForUnprotectedWeb(
239 const GURL& origin, 385 const GURL& origin,
240 storage::SpecialStoragePolicy* special_storage_policy) { 386 storage::SpecialStoragePolicy* special_storage_policy) {
241 if (IsWebSafeSchemeForTest(origin.scheme())) 387 if (IsWebSafeSchemeForTest(origin.scheme()))
242 return !special_storage_policy->IsStorageProtected(origin.GetOrigin()); 388 return !special_storage_policy->IsStorageProtected(origin.GetOrigin());
243 389
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 void ClearData(content::StoragePartition* partition, 483 void ClearData(content::StoragePartition* partition,
338 base::RunLoop* run_loop) { 484 base::RunLoop* run_loop) {
339 base::Time time; 485 base::Time time;
340 partition->ClearData( 486 partition->ClearData(
341 StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE, 487 StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE,
342 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL, 488 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL,
343 GURL(), StoragePartition::OriginMatcherFunction(), 489 GURL(), StoragePartition::OriginMatcherFunction(),
344 time, time, run_loop->QuitClosure()); 490 time, time, run_loop->QuitClosure());
345 } 491 }
346 492
493 void ClearPluginPrivateData(content::StoragePartition* partition,
494 const GURL& storage_origin,
495 const base::Time delete_begin,
496 const base::Time delete_end,
497 base::RunLoop* run_loop) {
498 partition->ClearData(
499 StoragePartitionImpl::REMOVE_DATA_MASK_PLUGIN_PRIVATE_DATA,
500 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL, storage_origin,
501 StoragePartition::OriginMatcherFunction(), delete_begin, delete_end,
502 run_loop->QuitClosure());
503 }
504
347 } // namespace 505 } // namespace
348 506
349 class StoragePartitionImplTest : public testing::Test { 507 class StoragePartitionImplTest : public testing::Test {
350 public: 508 public:
351 StoragePartitionImplTest() 509 StoragePartitionImplTest()
352 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 510 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
353 browser_context_(new TestBrowserContext()) { 511 browser_context_(new TestBrowserContext()) {
354 } 512 }
355 513
356 MockQuotaManager* GetMockManager() { 514 MockQuotaManager* GetMockManager() {
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 base::Bind(&DoesOriginMatchForBothProtectedAndUnprotectedWeb), 1126 base::Bind(&DoesOriginMatchForBothProtectedAndUnprotectedWeb),
969 &run_loop)); 1127 &run_loop));
970 run_loop.Run(); 1128 run_loop.Run();
971 1129
972 // kOrigin1 and kOrigin2 do not have age more than a week. 1130 // kOrigin1 and kOrigin2 do not have age more than a week.
973 EXPECT_FALSE(tester.DOMStorageExistsForOrigin(kOrigin1)); 1131 EXPECT_FALSE(tester.DOMStorageExistsForOrigin(kOrigin1));
974 EXPECT_FALSE(tester.DOMStorageExistsForOrigin(kOrigin2)); 1132 EXPECT_FALSE(tester.DOMStorageExistsForOrigin(kOrigin2));
975 EXPECT_TRUE(tester.DOMStorageExistsForOrigin(kOrigin3)); 1133 EXPECT_TRUE(tester.DOMStorageExistsForOrigin(kOrigin3));
976 } 1134 }
977 1135
1136 TEST_F(StoragePartitionImplTest, RemovePluginPrivateDataForever) {
1137 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
1138 BrowserContext::GetDefaultStoragePartition(browser_context()));
1139
1140 RemovePluginPrivateDataTester tester(partition->GetFileSystemContext());
1141 tester.AddPluginPrivateTestData();
1142 EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin1));
1143 EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin2));
1144
1145 base::RunLoop run_loop;
1146 base::ThreadTaskRunnerHandle::Get()->PostTask(
1147 FROM_HERE, base::Bind(&ClearPluginPrivateData, partition, GURL(),
1148 base::Time(), base::Time::Max(), &run_loop));
1149 run_loop.Run();
1150
1151 EXPECT_FALSE(tester.DataExistsForOrigin(kOrigin1));
1152 EXPECT_FALSE(tester.DataExistsForOrigin(kOrigin2));
1153 }
1154
1155 TEST_F(StoragePartitionImplTest, RemovePluginPrivateDataLastWeek) {
1156 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
1157 BrowserContext::GetDefaultStoragePartition(browser_context()));
1158 base::Time a_week_ago = base::Time::Now() - base::TimeDelta::FromDays(7);
1159
1160 RemovePluginPrivateDataTester tester(partition->GetFileSystemContext());
1161 tester.AddPluginPrivateTestData();
1162 EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin1));
1163 EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin2));
1164
1165 base::RunLoop run_loop;
1166 base::ThreadTaskRunnerHandle::Get()->PostTask(
1167 FROM_HERE, base::Bind(&ClearPluginPrivateData, partition, GURL(),
1168 a_week_ago, base::Time::Max(), &run_loop));
1169 run_loop.Run();
1170
1171 // Origin1 has 1 file from 10 days ago, so it should remain around.
1172 // Origin2 has a current file, so it should be removed (even though the
1173 // second file is much older).
1174 EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin1));
1175 EXPECT_FALSE(tester.DataExistsForOrigin(kOrigin2));
1176 }
1177
1178 TEST_F(StoragePartitionImplTest, RemovePluginPrivateDataForOrigin) {
1179 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
1180 BrowserContext::GetDefaultStoragePartition(browser_context()));
1181
1182 RemovePluginPrivateDataTester tester(partition->GetFileSystemContext());
1183 tester.AddPluginPrivateTestData();
1184 EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin1));
1185 EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin2));
1186
1187 base::RunLoop run_loop;
1188 base::ThreadTaskRunnerHandle::Get()->PostTask(
1189 FROM_HERE, base::Bind(&ClearPluginPrivateData, partition, kOrigin1,
1190 base::Time(), base::Time::Max(), &run_loop));
1191 run_loop.Run();
1192
1193 // Only Origin1 should be deleted.
1194 EXPECT_FALSE(tester.DataExistsForOrigin(kOrigin1));
1195 EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin2));
1196 }
1197
978 TEST(StoragePartitionImplStaticTest, CreatePredicateForHostCookies) { 1198 TEST(StoragePartitionImplStaticTest, CreatePredicateForHostCookies) {
979 GURL url("http://www.example.com/"); 1199 GURL url("http://www.example.com/");
980 GURL url2("https://www.example.com/"); 1200 GURL url2("https://www.example.com/");
981 GURL url3("https://www.google.com/"); 1201 GURL url3("https://www.google.com/");
982 1202
983 net::CookieOptions options; 1203 net::CookieOptions options;
984 net::CookieStore::CookiePredicate predicate = 1204 net::CookieStore::CookiePredicate predicate =
985 StoragePartitionImpl::CreatePredicateForHostCookies(url); 1205 StoragePartitionImpl::CreatePredicateForHostCookies(url);
986 1206
987 base::Time now = base::Time::Now(); 1207 base::Time now = base::Time::Now();
988 std::vector<std::unique_ptr<CanonicalCookie>> valid_cookies; 1208 std::vector<std::unique_ptr<CanonicalCookie>> valid_cookies;
989 valid_cookies.push_back(CanonicalCookie::Create(url, "A=B", now, options)); 1209 valid_cookies.push_back(CanonicalCookie::Create(url, "A=B", now, options));
990 valid_cookies.push_back(CanonicalCookie::Create(url, "C=F", now, options)); 1210 valid_cookies.push_back(CanonicalCookie::Create(url, "C=F", now, options));
991 // We should match a different scheme with the same host. 1211 // We should match a different scheme with the same host.
992 valid_cookies.push_back(CanonicalCookie::Create(url2, "A=B", now, options)); 1212 valid_cookies.push_back(CanonicalCookie::Create(url2, "A=B", now, options));
993 1213
994 std::vector<std::unique_ptr<CanonicalCookie>> invalid_cookies; 1214 std::vector<std::unique_ptr<CanonicalCookie>> invalid_cookies;
995 // We don't match domain cookies. 1215 // We don't match domain cookies.
996 invalid_cookies.push_back( 1216 invalid_cookies.push_back(
997 CanonicalCookie::Create(url2, "A=B;domain=.example.com", now, options)); 1217 CanonicalCookie::Create(url2, "A=B;domain=.example.com", now, options));
998 invalid_cookies.push_back(CanonicalCookie::Create(url3, "A=B", now, options)); 1218 invalid_cookies.push_back(CanonicalCookie::Create(url3, "A=B", now, options));
999 1219
1000 for (const auto& cookie : valid_cookies) 1220 for (const auto& cookie : valid_cookies)
1001 EXPECT_TRUE(predicate.Run(*cookie)) << cookie->DebugString(); 1221 EXPECT_TRUE(predicate.Run(*cookie)) << cookie->DebugString();
1002 for (const auto& cookie : invalid_cookies) 1222 for (const auto& cookie : invalid_cookies)
1003 EXPECT_FALSE(predicate.Run(*cookie)) << cookie->DebugString(); 1223 EXPECT_FALSE(predicate.Run(*cookie)) << cookie->DebugString();
1004 } 1224 }
1005 1225
1006 } // namespace content 1226 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698