Home | History | Annotate | Download | only in browsing_data
      1 // Copyright (c) 2012 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 "testing/gtest/include/gtest/gtest.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/files/file_util.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/stl_util.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
     14 #include "chrome/test/base/testing_profile.h"
     15 #include "content/public/browser/storage_partition.h"
     16 #include "content/public/test/test_browser_thread.h"
     17 #include "content/public/test/test_browser_thread_bundle.h"
     18 #include "storage/browser/fileapi/file_system_context.h"
     19 #include "storage/browser/fileapi/file_system_url.h"
     20 #include "storage/common/fileapi/file_system_types.h"
     21 
     22 using content::BrowserContext;
     23 using content::BrowserThread;
     24 
     25 namespace {
     26 
     27 // Shorter names for storage::* constants.
     28 const storage::FileSystemType kTemporary = storage::kFileSystemTypeTemporary;
     29 const storage::FileSystemType kPersistent = storage::kFileSystemTypePersistent;
     30 
     31 // We'll use these three distinct origins for testing, both as strings and as
     32 // GURLs in appropriate contexts.
     33 const char kTestOrigin1[] = "http://host1:1/";
     34 const char kTestOrigin2[] = "http://host2:2/";
     35 const char kTestOrigin3[] = "http://host3:3/";
     36 
     37 // Extensions and Devtools should be ignored.
     38 const char kTestOriginExt[] = "chrome-extension://abcdefghijklmnopqrstuvwxyz/";
     39 const char kTestOriginDevTools[] = "chrome-devtools://abcdefghijklmnopqrstuvw/";
     40 
     41 const GURL kOrigin1(kTestOrigin1);
     42 const GURL kOrigin2(kTestOrigin2);
     43 const GURL kOrigin3(kTestOrigin3);
     44 const GURL kOriginExt(kTestOriginExt);
     45 const GURL kOriginDevTools(kTestOriginDevTools);
     46 
     47 // TODO(mkwst): Update this size once the discussion in http://crbug.com/86114
     48 // is concluded.
     49 const int kEmptyFileSystemSize = 0;
     50 
     51 typedef std::list<BrowsingDataFileSystemHelper::FileSystemInfo>
     52     FileSystemInfoList;
     53 typedef scoped_ptr<FileSystemInfoList> ScopedFileSystemInfoList;
     54 
     55 // The FileSystem APIs are all asynchronous; this testing class wraps up the
     56 // boilerplate code necessary to deal with waiting for responses. In a nutshell,
     57 // any async call whose response we want to test ought to be followed by a call
     58 // to BlockUntilNotified(), which will (shockingly!) block until Notify() is
     59 // called. For this to work, you'll need to ensure that each async call is
     60 // implemented as a class method that that calls Notify() at an appropriate
     61 // point.
     62 class BrowsingDataFileSystemHelperTest : public testing::Test {
     63  public:
     64   BrowsingDataFileSystemHelperTest() {
     65     profile_.reset(new TestingProfile());
     66 
     67     helper_ = BrowsingDataFileSystemHelper::Create(
     68         BrowserContext::GetDefaultStoragePartition(profile_.get())->
     69             GetFileSystemContext());
     70     base::MessageLoop::current()->RunUntilIdle();
     71     canned_helper_ = new CannedBrowsingDataFileSystemHelper(profile_.get());
     72   }
     73   virtual ~BrowsingDataFileSystemHelperTest() {
     74     // Avoid memory leaks.
     75     profile_.reset();
     76     base::MessageLoop::current()->RunUntilIdle();
     77   }
     78 
     79   TestingProfile* GetProfile() {
     80     return profile_.get();
     81   }
     82 
     83   // Blocks on the current MessageLoop until Notify() is called.
     84   void BlockUntilNotified() {
     85     base::MessageLoop::current()->Run();
     86   }
     87 
     88   // Unblocks the current MessageLoop. Should be called in response to some sort
     89   // of async activity in a callback method.
     90   void Notify() {
     91     base::MessageLoop::current()->Quit();
     92   }
     93 
     94   // Callback that should be executed in response to
     95   // storage::FileSystemContext::OpenFileSystem.
     96   void OpenFileSystemCallback(const GURL& root,
     97                               const std::string& name,
     98                               base::File::Error error) {
     99     open_file_system_result_ = error;
    100     Notify();
    101   }
    102 
    103   bool OpenFileSystem(const GURL& origin,
    104                       storage::FileSystemType type,
    105                       storage::OpenFileSystemMode open_mode) {
    106     BrowserContext::GetDefaultStoragePartition(profile_.get())->
    107         GetFileSystemContext()->OpenFileSystem(
    108             origin, type, open_mode,
    109             base::Bind(
    110                 &BrowsingDataFileSystemHelperTest::OpenFileSystemCallback,
    111                 base::Unretained(this)));
    112     BlockUntilNotified();
    113     return open_file_system_result_ == base::File::FILE_OK;
    114   }
    115 
    116   // Calls storage::FileSystemContext::OpenFileSystem with
    117   // OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT flag
    118   // to verify the existence of a file system for a specified type and origin,
    119   // blocks until a response is available, then returns the result
    120   // synchronously to it's caller.
    121   bool FileSystemContainsOriginAndType(const GURL& origin,
    122                                        storage::FileSystemType type) {
    123     return OpenFileSystem(
    124         origin, type, storage::OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT);
    125   }
    126 
    127   // Callback that should be executed in response to StartFetching(), and stores
    128   // found file systems locally so that they are available via GetFileSystems().
    129   void CallbackStartFetching(
    130       const std::list<BrowsingDataFileSystemHelper::FileSystemInfo>&
    131           file_system_info_list) {
    132     file_system_info_list_.reset(
    133         new std::list<BrowsingDataFileSystemHelper::FileSystemInfo>(
    134             file_system_info_list));
    135     Notify();
    136   }
    137 
    138   // Calls StartFetching() on the test's BrowsingDataFileSystemHelper
    139   // object, then blocks until the callback is executed.
    140   void FetchFileSystems() {
    141     helper_->StartFetching(
    142         base::Bind(&BrowsingDataFileSystemHelperTest::CallbackStartFetching,
    143                    base::Unretained(this)));
    144     BlockUntilNotified();
    145   }
    146 
    147   // Calls StartFetching() on the test's CannedBrowsingDataFileSystemHelper
    148   // object, then blocks until the callback is executed.
    149   void FetchCannedFileSystems() {
    150     canned_helper_->StartFetching(
    151         base::Bind(&BrowsingDataFileSystemHelperTest::CallbackStartFetching,
    152                    base::Unretained(this)));
    153     BlockUntilNotified();
    154   }
    155 
    156   // Sets up kOrigin1 with a temporary file system, kOrigin2 with a persistent
    157   // file system, and kOrigin3 with both.
    158   virtual void PopulateTestFileSystemData() {
    159     CreateDirectoryForOriginAndType(kOrigin1, kTemporary);
    160     CreateDirectoryForOriginAndType(kOrigin2, kPersistent);
    161     CreateDirectoryForOriginAndType(kOrigin3, kTemporary);
    162     CreateDirectoryForOriginAndType(kOrigin3, kPersistent);
    163 
    164     EXPECT_FALSE(FileSystemContainsOriginAndType(kOrigin1, kPersistent));
    165     EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin1, kTemporary));
    166     EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin2, kPersistent));
    167     EXPECT_FALSE(FileSystemContainsOriginAndType(kOrigin2, kTemporary));
    168     EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin3, kPersistent));
    169     EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin3, kTemporary));
    170   }
    171 
    172   // Calls OpenFileSystem with OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
    173   // to create a filesystem of a given type for a specified origin.
    174   void CreateDirectoryForOriginAndType(const GURL& origin,
    175                                        storage::FileSystemType type) {
    176     OpenFileSystem(
    177         origin, type, storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
    178     EXPECT_EQ(base::File::FILE_OK, open_file_system_result_);
    179   }
    180 
    181   // Returns a list of the FileSystemInfo objects gathered in the most recent
    182   // call to StartFetching().
    183   FileSystemInfoList* GetFileSystems() {
    184     return file_system_info_list_.get();
    185   }
    186 
    187  protected:
    188   content::TestBrowserThreadBundle thread_bundle_;
    189   scoped_ptr<TestingProfile> profile_;
    190 
    191   // Temporary storage to pass information back from callbacks.
    192   base::File::Error open_file_system_result_;
    193   ScopedFileSystemInfoList file_system_info_list_;
    194 
    195   scoped_refptr<BrowsingDataFileSystemHelper> helper_;
    196   scoped_refptr<CannedBrowsingDataFileSystemHelper> canned_helper_;
    197 
    198  private:
    199   DISALLOW_COPY_AND_ASSIGN(BrowsingDataFileSystemHelperTest);
    200 };
    201 
    202 // Verifies that the BrowsingDataFileSystemHelper correctly finds the test file
    203 // system data, and that each file system returned contains the expected data.
    204 TEST_F(BrowsingDataFileSystemHelperTest, FetchData) {
    205   PopulateTestFileSystemData();
    206 
    207   FetchFileSystems();
    208 
    209   EXPECT_EQ(3UL, file_system_info_list_->size());
    210 
    211   // Order is arbitrary, verify all three origins.
    212   bool test_hosts_found[3] = {false, false, false};
    213   for (std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator info =
    214        file_system_info_list_->begin(); info != file_system_info_list_->end();
    215        ++info) {
    216     if (info->origin == kOrigin1) {
    217       EXPECT_FALSE(test_hosts_found[0]);
    218       test_hosts_found[0] = true;
    219       EXPECT_FALSE(ContainsKey(info->usage_map, kPersistent));
    220       EXPECT_TRUE(ContainsKey(info->usage_map, kTemporary));
    221       EXPECT_EQ(kEmptyFileSystemSize,
    222                 info->usage_map[storage::kFileSystemTypeTemporary]);
    223     } else if (info->origin == kOrigin2) {
    224       EXPECT_FALSE(test_hosts_found[1]);
    225       test_hosts_found[1] = true;
    226       EXPECT_TRUE(ContainsKey(info->usage_map, kPersistent));
    227       EXPECT_FALSE(ContainsKey(info->usage_map, kTemporary));
    228       EXPECT_EQ(kEmptyFileSystemSize, info->usage_map[kPersistent]);
    229     } else if (info->origin == kOrigin3) {
    230       EXPECT_FALSE(test_hosts_found[2]);
    231       test_hosts_found[2] = true;
    232       EXPECT_TRUE(ContainsKey(info->usage_map, kPersistent));
    233       EXPECT_TRUE(ContainsKey(info->usage_map, kTemporary));
    234       EXPECT_EQ(kEmptyFileSystemSize, info->usage_map[kPersistent]);
    235       EXPECT_EQ(kEmptyFileSystemSize, info->usage_map[kTemporary]);
    236     } else {
    237       ADD_FAILURE() << info->origin.spec() << " isn't an origin we added.";
    238     }
    239   }
    240   for (size_t i = 0; i < arraysize(test_hosts_found); i++) {
    241     EXPECT_TRUE(test_hosts_found[i]);
    242   }
    243 }
    244 
    245 // Verifies that the BrowsingDataFileSystemHelper correctly deletes file
    246 // systems via DeleteFileSystemOrigin().
    247 TEST_F(BrowsingDataFileSystemHelperTest, DeleteData) {
    248   PopulateTestFileSystemData();
    249 
    250   helper_->DeleteFileSystemOrigin(kOrigin1);
    251   helper_->DeleteFileSystemOrigin(kOrigin2);
    252 
    253   FetchFileSystems();
    254 
    255   EXPECT_EQ(1UL, file_system_info_list_->size());
    256   BrowsingDataFileSystemHelper::FileSystemInfo info =
    257       *(file_system_info_list_->begin());
    258   EXPECT_EQ(kOrigin3, info.origin);
    259   EXPECT_TRUE(ContainsKey(info.usage_map, kPersistent));
    260   EXPECT_TRUE(ContainsKey(info.usage_map, kTemporary));
    261   EXPECT_EQ(kEmptyFileSystemSize, info.usage_map[kPersistent]);
    262   EXPECT_EQ(kEmptyFileSystemSize, info.usage_map[kTemporary]);
    263 }
    264 
    265 // Verifies that the CannedBrowsingDataFileSystemHelper correctly reports
    266 // whether or not it currently contains file systems.
    267 TEST_F(BrowsingDataFileSystemHelperTest, Empty) {
    268   ASSERT_TRUE(canned_helper_->empty());
    269   canned_helper_->AddFileSystem(kOrigin1, kTemporary, 0);
    270   ASSERT_FALSE(canned_helper_->empty());
    271   canned_helper_->Reset();
    272   ASSERT_TRUE(canned_helper_->empty());
    273 }
    274 
    275 // Verifies that AddFileSystem correctly adds file systems, and that both
    276 // the type and usage metadata are reported as provided.
    277 TEST_F(BrowsingDataFileSystemHelperTest, CannedAddFileSystem) {
    278   canned_helper_->AddFileSystem(kOrigin1, kPersistent, 200);
    279   canned_helper_->AddFileSystem(kOrigin2, kTemporary, 100);
    280 
    281   FetchCannedFileSystems();
    282 
    283   EXPECT_EQ(2U, file_system_info_list_->size());
    284   std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator info =
    285       file_system_info_list_->begin();
    286   EXPECT_EQ(kOrigin1, info->origin);
    287   EXPECT_TRUE(ContainsKey(info->usage_map, kPersistent));
    288   EXPECT_FALSE(ContainsKey(info->usage_map, kTemporary));
    289   EXPECT_EQ(200, info->usage_map[kPersistent]);
    290 
    291   info++;
    292   EXPECT_EQ(kOrigin2, info->origin);
    293   EXPECT_FALSE(ContainsKey(info->usage_map, kPersistent));
    294   EXPECT_TRUE(ContainsKey(info->usage_map, kTemporary));
    295   EXPECT_EQ(100, info->usage_map[kTemporary]);
    296 }
    297 
    298 // Verifies that the CannedBrowsingDataFileSystemHelper correctly ignores
    299 // extension and devtools schemes.
    300 TEST_F(BrowsingDataFileSystemHelperTest, IgnoreExtensionsAndDevTools) {
    301   ASSERT_TRUE(canned_helper_->empty());
    302   canned_helper_->AddFileSystem(kOriginExt, kTemporary, 0);
    303   ASSERT_TRUE(canned_helper_->empty());
    304   canned_helper_->AddFileSystem(kOriginDevTools, kTemporary, 0);
    305   ASSERT_TRUE(canned_helper_->empty());
    306 }
    307 
    308 }  // namespace
    309