| Index: content/browser/storage_partition_impl_unittest.cc
|
| diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc
|
| index 6aa0c1b0877ed9aa8e814c0f33b6dc14be32f22d..30b24b2afba2bd17298dfae6abe862df1bda43c2 100644
|
| --- a/content/browser/storage_partition_impl_unittest.cc
|
| +++ b/content/browser/storage_partition_impl_unittest.cc
|
| @@ -27,6 +27,10 @@
|
| #include "net/cookies/cookie_store.h"
|
| #include "net/url_request/url_request_context.h"
|
| #include "net/url_request/url_request_context_getter.h"
|
| +#include "storage/browser/fileapi/async_file_util.h"
|
| +#include "storage/browser/fileapi/file_system_context.h"
|
| +#include "storage/browser/fileapi/file_system_operation_context.h"
|
| +#include "storage/browser/fileapi/isolated_context.h"
|
| #include "storage/browser/quota/quota_manager.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| @@ -44,6 +48,10 @@ const char kTestOrigin2[] = "http://host2:1/";
|
| const char kTestOrigin3[] = "http://host3:1/";
|
| const char kTestOriginDevTools[] = "chrome-devtools://abcdefghijklmnopqrstuvw/";
|
|
|
| +const char kPluginPrivateRootName[] = "pluginprivate";
|
| +const char kWidevineCdmPluginId[] = "application_x-ppapi-widevine-cdm";
|
| +const char kClearKeyCdmPluginId[] = "application_x-ppapi-clearkey-cdm";
|
| +
|
| const GURL kOrigin1(kTestOrigin1);
|
| const GURL kOrigin2(kTestOrigin2);
|
| const GURL kOrigin3(kTestOrigin3);
|
| @@ -231,6 +239,144 @@ class RemoveLocalStorageTester {
|
| DISALLOW_COPY_AND_ASSIGN(RemoveLocalStorageTester);
|
| };
|
|
|
| +class RemovePluginPrivateDataTester {
|
| + public:
|
| + explicit RemovePluginPrivateDataTester(
|
| + storage::FileSystemContext* filesystem_context)
|
| + : filesystem_context_(filesystem_context) {}
|
| +
|
| + // Add some files to the PluginPrivateFileSystem. They are created as follows:
|
| + // kOrigin1 - ClearKey - 1 file - timestamp 10 days ago
|
| + // kOrigin2 - Widevine - 2 files - timestamps now and 60 days ago
|
| + void AddPluginPrivateTestData() {
|
| + base::Time now = base::Time::Now();
|
| + base::Time ten_days_ago = now - base::TimeDelta::FromDays(10);
|
| + base::Time sixty_days_ago = now - base::TimeDelta::FromDays(60);
|
| +
|
| + // Create a PluginPrivateFileSystem for ClearKey and add a single file
|
| + // with a timestamp of 1 day ago.
|
| + std::string clearkey_fsid =
|
| + CreateFileSystem(kClearKeyCdmPluginId, kOrigin1);
|
| + storage::FileSystemURL clearkey_file =
|
| + CreateFile(kOrigin1, clearkey_fsid, "foo");
|
| + SetFileTimestamp(clearkey_file, ten_days_ago);
|
| +
|
| + // Create a second PluginPrivateFileSystem for Widevine and add two files
|
| + // with different times.
|
| + std::string widevine_fsid =
|
| + CreateFileSystem(kWidevineCdmPluginId, kOrigin2);
|
| + storage::FileSystemURL widevine_file1 =
|
| + CreateFile(kOrigin2, widevine_fsid, "bar1");
|
| + storage::FileSystemURL widevine_file2 =
|
| + CreateFile(kOrigin2, widevine_fsid, "bar2");
|
| + SetFileTimestamp(widevine_file1, now);
|
| + SetFileTimestamp(widevine_file2, sixty_days_ago);
|
| + }
|
| +
|
| + // Returns true, if the given origin exists in a PluginPrivateFileSystem.
|
| + bool DataExistsForOrigin(const GURL& origin) {
|
| + storage::FileSystemBackend* backend =
|
| + filesystem_context_->GetFileSystemBackend(
|
| + storage::kFileSystemTypePluginPrivate);
|
| + storage::FileSystemQuotaUtil* quota_util = backend->GetQuotaUtil();
|
| +
|
| + // Determine the set of origins used.
|
| + std::set<GURL> origins;
|
| + quota_util->GetOriginsForTypeOnFileTaskRunner(
|
| + storage::kFileSystemTypePluginPrivate, &origins);
|
| + return origins.find(origin) != origins.end();
|
| + }
|
| +
|
| + private:
|
| + // Creates a PluginPrivateFileSystem for the |plugin_name| and |origin|
|
| + // provided. Returns the file system ID for the created
|
| + // PluginPrivateFileSystem.
|
| + std::string CreateFileSystem(const std::string& plugin_name,
|
| + const GURL& origin) {
|
| + AwaitCompletionHelper await_completion;
|
| + std::string fsid = storage::IsolatedContext::GetInstance()
|
| + ->RegisterFileSystemForVirtualPath(
|
| + storage::kFileSystemTypePluginPrivate,
|
| + kPluginPrivateRootName, base::FilePath());
|
| + EXPECT_TRUE(storage::ValidateIsolatedFileSystemId(fsid));
|
| + filesystem_context_->OpenPluginPrivateFileSystem(
|
| + origin, storage::kFileSystemTypePluginPrivate, fsid, plugin_name,
|
| + storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
|
| + base::Bind(&RemovePluginPrivateDataTester::OnFileSystemOpened,
|
| + base::Unretained(this), &await_completion));
|
| + await_completion.BlockUntilNotified();
|
| + return fsid;
|
| + }
|
| +
|
| + // Creates a file named |file_name| in the PluginPrivateFileSystem identified
|
| + // by |origin| and |fsid|. Returns the URL for the created file. The file
|
| + // musty not already exist or the test will fail.
|
| + storage::FileSystemURL CreateFile(const GURL& origin,
|
| + const std::string& fsid,
|
| + const std::string& file_name) {
|
| + AwaitCompletionHelper await_completion;
|
| + std::string root = storage::GetIsolatedFileSystemRootURIString(
|
| + origin, fsid, kPluginPrivateRootName);
|
| + storage::FileSystemURL file_url =
|
| + filesystem_context_->CrackURL(GURL(root + file_name));
|
| + storage::AsyncFileUtil* file_util = filesystem_context_->GetAsyncFileUtil(
|
| + storage::kFileSystemTypePluginPrivate);
|
| + std::unique_ptr<storage::FileSystemOperationContext> operation_context =
|
| + base::WrapUnique(
|
| + new storage::FileSystemOperationContext(filesystem_context_));
|
| + operation_context->set_allowed_bytes_growth(
|
| + storage::QuotaManager::kNoLimit);
|
| + file_util->EnsureFileExists(
|
| + std::move(operation_context), file_url,
|
| + base::Bind(&RemovePluginPrivateDataTester::OnFileCreated,
|
| + base::Unretained(this), &await_completion));
|
| + await_completion.BlockUntilNotified();
|
| + return file_url;
|
| + }
|
| +
|
| + // Sets the last_access_time and last_modified_time to |time_stamp| on the
|
| + // file specified by |file_url|. The file must already exist.
|
| + void SetFileTimestamp(const storage::FileSystemURL& file_url,
|
| + const base::Time& time_stamp) {
|
| + AwaitCompletionHelper await_completion;
|
| + storage::AsyncFileUtil* file_util = filesystem_context_->GetAsyncFileUtil(
|
| + storage::kFileSystemTypePluginPrivate);
|
| + std::unique_ptr<storage::FileSystemOperationContext> operation_context =
|
| + base::WrapUnique(
|
| + new storage::FileSystemOperationContext(filesystem_context_));
|
| + file_util->Touch(std::move(operation_context), file_url, time_stamp,
|
| + time_stamp,
|
| + base::Bind(&RemovePluginPrivateDataTester::OnFileTouched,
|
| + base::Unretained(this), &await_completion));
|
| + await_completion.BlockUntilNotified();
|
| + }
|
| +
|
| + void OnFileSystemOpened(AwaitCompletionHelper* await_completion,
|
| + base::File::Error result) {
|
| + EXPECT_EQ(base::File::FILE_OK, result) << base::File::ErrorToString(result);
|
| + await_completion->Notify();
|
| + }
|
| +
|
| + void OnFileCreated(AwaitCompletionHelper* await_completion,
|
| + base::File::Error result,
|
| + bool created) {
|
| + EXPECT_EQ(base::File::FILE_OK, result) << base::File::ErrorToString(result);
|
| + EXPECT_TRUE(created);
|
| + await_completion->Notify();
|
| + }
|
| +
|
| + void OnFileTouched(AwaitCompletionHelper* await_completion,
|
| + base::File::Error result) {
|
| + EXPECT_EQ(base::File::FILE_OK, result) << base::File::ErrorToString(result);
|
| + await_completion->Notify();
|
| + }
|
| +
|
| + // We don't own this pointer.
|
| + storage::FileSystemContext* filesystem_context_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(RemovePluginPrivateDataTester);
|
| +};
|
| +
|
| bool IsWebSafeSchemeForTest(const std::string& scheme) {
|
| return scheme == "http";
|
| }
|
| @@ -344,6 +490,18 @@ void ClearData(content::StoragePartition* partition,
|
| time, time, run_loop->QuitClosure());
|
| }
|
|
|
| +void ClearPluginPrivateData(content::StoragePartition* partition,
|
| + const GURL& storage_origin,
|
| + const base::Time delete_begin,
|
| + const base::Time delete_end,
|
| + base::RunLoop* run_loop) {
|
| + partition->ClearData(
|
| + StoragePartitionImpl::REMOVE_DATA_MASK_PLUGIN_PRIVATE_DATA,
|
| + StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL, storage_origin,
|
| + StoragePartition::OriginMatcherFunction(), delete_begin, delete_end,
|
| + run_loop->QuitClosure());
|
| +}
|
| +
|
| } // namespace
|
|
|
| class StoragePartitionImplTest : public testing::Test {
|
| @@ -975,6 +1133,68 @@ TEST_F(StoragePartitionImplTest, RemoveLocalStorageForLastWeek) {
|
| EXPECT_TRUE(tester.DOMStorageExistsForOrigin(kOrigin3));
|
| }
|
|
|
| +TEST_F(StoragePartitionImplTest, RemovePluginPrivateDataForever) {
|
| + StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
|
| + BrowserContext::GetDefaultStoragePartition(browser_context()));
|
| +
|
| + RemovePluginPrivateDataTester tester(partition->GetFileSystemContext());
|
| + tester.AddPluginPrivateTestData();
|
| + EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin1));
|
| + EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin2));
|
| +
|
| + base::RunLoop run_loop;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::Bind(&ClearPluginPrivateData, partition, GURL(),
|
| + base::Time(), base::Time::Max(), &run_loop));
|
| + run_loop.Run();
|
| +
|
| + EXPECT_FALSE(tester.DataExistsForOrigin(kOrigin1));
|
| + EXPECT_FALSE(tester.DataExistsForOrigin(kOrigin2));
|
| +}
|
| +
|
| +TEST_F(StoragePartitionImplTest, RemovePluginPrivateDataLastWeek) {
|
| + StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
|
| + BrowserContext::GetDefaultStoragePartition(browser_context()));
|
| + base::Time a_week_ago = base::Time::Now() - base::TimeDelta::FromDays(7);
|
| +
|
| + RemovePluginPrivateDataTester tester(partition->GetFileSystemContext());
|
| + tester.AddPluginPrivateTestData();
|
| + EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin1));
|
| + EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin2));
|
| +
|
| + base::RunLoop run_loop;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::Bind(&ClearPluginPrivateData, partition, GURL(),
|
| + a_week_ago, base::Time::Max(), &run_loop));
|
| + run_loop.Run();
|
| +
|
| + // Origin1 has 1 file from 10 days ago, so it should remain around.
|
| + // Origin2 has a current file, so it should be removed (even though the
|
| + // second file is much older).
|
| + EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin1));
|
| + EXPECT_FALSE(tester.DataExistsForOrigin(kOrigin2));
|
| +}
|
| +
|
| +TEST_F(StoragePartitionImplTest, RemovePluginPrivateDataForOrigin) {
|
| + StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
|
| + BrowserContext::GetDefaultStoragePartition(browser_context()));
|
| +
|
| + RemovePluginPrivateDataTester tester(partition->GetFileSystemContext());
|
| + tester.AddPluginPrivateTestData();
|
| + EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin1));
|
| + EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin2));
|
| +
|
| + base::RunLoop run_loop;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::Bind(&ClearPluginPrivateData, partition, kOrigin1,
|
| + base::Time(), base::Time::Max(), &run_loop));
|
| + run_loop.Run();
|
| +
|
| + // Only Origin1 should be deleted.
|
| + EXPECT_FALSE(tester.DataExistsForOrigin(kOrigin1));
|
| + EXPECT_TRUE(tester.DataExistsForOrigin(kOrigin2));
|
| +}
|
| +
|
| TEST(StoragePartitionImplStaticTest, CreatePredicateForHostCookies) {
|
| GURL url("http://www.example.com/");
|
| GURL url2("https://www.example.com/");
|
|
|