Home | History | Annotate | Download | only in fileapi
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/basictypes.h"
      6 #include "base/files/file_util.h"
      7 #include "base/files/scoped_temp_dir.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/message_loop/message_loop_proxy.h"
     11 #include "base/run_loop.h"
     12 #include "content/public/test/async_file_test_helper.h"
     13 #include "content/public/test/test_file_system_context.h"
     14 #include "content/public/test/test_file_system_options.h"
     15 #include "storage/browser/fileapi/file_system_context.h"
     16 #include "storage/browser/fileapi/isolated_context.h"
     17 #include "storage/browser/fileapi/obfuscated_file_util.h"
     18 #include "storage/browser/fileapi/plugin_private_file_system_backend.h"
     19 #include "storage/common/fileapi/file_system_util.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 
     22 using content::AsyncFileTestHelper;
     23 using storage::FileSystemContext;
     24 using storage::FileSystemURL;
     25 using storage::IsolatedContext;
     26 
     27 namespace content {
     28 
     29 namespace {
     30 
     31 const GURL kOrigin("http://www.example.com");
     32 const std::string kPlugin1("plugin1");
     33 const std::string kPlugin2("plugin2");
     34 const storage::FileSystemType kType = storage::kFileSystemTypePluginPrivate;
     35 const std::string kRootName = "pluginprivate";
     36 
     37 void DidOpenFileSystem(base::File::Error* error_out,
     38                        base::File::Error error) {
     39   *error_out = error;
     40 }
     41 
     42 std::string RegisterFileSystem() {
     43   return IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
     44       kType, kRootName, base::FilePath());
     45 }
     46 
     47 }  // namespace
     48 
     49 class PluginPrivateFileSystemBackendTest : public testing::Test {
     50  protected:
     51   virtual void SetUp() OVERRIDE {
     52     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
     53     context_ = CreateFileSystemContextForTesting(
     54         NULL /* quota_manager_proxy */,
     55         data_dir_.path());
     56   }
     57 
     58   FileSystemURL CreateURL(const GURL& root_url, const std::string& relative) {
     59     FileSystemURL root = context_->CrackURL(root_url);
     60     return context_->CreateCrackedFileSystemURL(
     61         root.origin(),
     62         root.mount_type(),
     63         root.virtual_path().AppendASCII(relative));
     64   }
     65 
     66   storage::PluginPrivateFileSystemBackend* backend() const {
     67     return context_->plugin_private_backend();
     68   }
     69 
     70   const base::FilePath& base_path() const { return backend()->base_path(); }
     71 
     72   base::ScopedTempDir data_dir_;
     73   base::MessageLoop message_loop_;
     74   scoped_refptr<FileSystemContext> context_;
     75   std::string filesystem_id_;
     76 };
     77 
     78 TEST_F(PluginPrivateFileSystemBackendTest, OpenFileSystemBasic) {
     79   const std::string filesystem_id1 = RegisterFileSystem();
     80   base::File::Error error = base::File::FILE_ERROR_FAILED;
     81   backend()->OpenPrivateFileSystem(
     82       kOrigin,
     83       kType,
     84       filesystem_id1,
     85       kPlugin1,
     86       storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
     87       base::Bind(&DidOpenFileSystem, &error));
     88   base::RunLoop().RunUntilIdle();
     89   ASSERT_EQ(base::File::FILE_OK, error);
     90 
     91   // Run this again with FAIL_IF_NONEXISTENT to see if it succeeds.
     92   const std::string filesystem_id2 = RegisterFileSystem();
     93   error = base::File::FILE_ERROR_FAILED;
     94   backend()->OpenPrivateFileSystem(
     95       kOrigin,
     96       kType,
     97       filesystem_id2,
     98       kPlugin1,
     99       storage::OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT,
    100       base::Bind(&DidOpenFileSystem, &error));
    101   base::RunLoop().RunUntilIdle();
    102   ASSERT_EQ(base::File::FILE_OK, error);
    103 
    104   const GURL root_url(storage::GetIsolatedFileSystemRootURIString(
    105       kOrigin, filesystem_id1, kRootName));
    106   FileSystemURL file = CreateURL(root_url, "foo");
    107   base::FilePath platform_path;
    108   EXPECT_EQ(base::File::FILE_OK,
    109             AsyncFileTestHelper::CreateFile(context_.get(), file));
    110   EXPECT_EQ(base::File::FILE_OK,
    111             AsyncFileTestHelper::GetPlatformPath(context_.get(), file,
    112                                                  &platform_path));
    113   EXPECT_TRUE(base_path().AppendASCII("000").AppendASCII(kPlugin1).IsParent(
    114       platform_path));
    115 }
    116 
    117 TEST_F(PluginPrivateFileSystemBackendTest, PluginIsolation) {
    118   // Open filesystem for kPlugin1 and kPlugin2.
    119   const std::string filesystem_id1 = RegisterFileSystem();
    120   base::File::Error error = base::File::FILE_ERROR_FAILED;
    121   backend()->OpenPrivateFileSystem(
    122       kOrigin,
    123       kType,
    124       filesystem_id1,
    125       kPlugin1,
    126       storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
    127       base::Bind(&DidOpenFileSystem, &error));
    128   base::RunLoop().RunUntilIdle();
    129   ASSERT_EQ(base::File::FILE_OK, error);
    130 
    131   const std::string filesystem_id2 = RegisterFileSystem();
    132   error = base::File::FILE_ERROR_FAILED;
    133   backend()->OpenPrivateFileSystem(
    134       kOrigin,
    135       kType,
    136       filesystem_id2,
    137       kPlugin2,
    138       storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
    139       base::Bind(&DidOpenFileSystem, &error));
    140   base::RunLoop().RunUntilIdle();
    141   ASSERT_EQ(base::File::FILE_OK, error);
    142 
    143   // Create 'foo' in kPlugin1.
    144   const GURL root_url1(storage::GetIsolatedFileSystemRootURIString(
    145       kOrigin, filesystem_id1, kRootName));
    146   FileSystemURL file1 = CreateURL(root_url1, "foo");
    147   base::FilePath platform_path;
    148   EXPECT_EQ(base::File::FILE_OK,
    149             AsyncFileTestHelper::CreateFile(context_.get(), file1));
    150   EXPECT_TRUE(AsyncFileTestHelper::FileExists(
    151       context_.get(), file1, AsyncFileTestHelper::kDontCheckSize));
    152 
    153   // See the same path is not available in kPlugin2.
    154   const GURL root_url2(storage::GetIsolatedFileSystemRootURIString(
    155       kOrigin, filesystem_id2, kRootName));
    156   FileSystemURL file2 = CreateURL(root_url2, "foo");
    157   EXPECT_FALSE(AsyncFileTestHelper::FileExists(
    158       context_.get(), file2, AsyncFileTestHelper::kDontCheckSize));
    159 }
    160 
    161 // TODO(kinuko,nhiroki): also test if DeleteOriginDataOnFileThread
    162 // works fine when there's multiple plugin partitions.
    163 
    164 }  // namespace content
    165