Home | History | Annotate | Download | only in file_system
      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 "chrome/browser/chromeos/drive/file_system/truncate_operation.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "base/files/file_util.h"
      9 #include "base/task_runner_util.h"
     10 #include "chrome/browser/chromeos/drive/drive.pb.h"
     11 #include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h"
     12 #include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
     13 #include "content/public/test/test_utils.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 namespace drive {
     17 namespace file_system {
     18 
     19 class TruncateOperationTest : public OperationTestBase {
     20  protected:
     21   virtual void SetUp() OVERRIDE {
     22     OperationTestBase::SetUp();
     23 
     24     operation_.reset(new TruncateOperation(
     25         blocking_task_runner(), delegate(), scheduler(),
     26         metadata(), cache(), temp_dir()));
     27   }
     28 
     29   scoped_ptr<TruncateOperation> operation_;
     30 };
     31 
     32 TEST_F(TruncateOperationTest, Truncate) {
     33   base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
     34   ResourceEntry src_entry;
     35   ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
     36   const int64 file_size = src_entry.file_info().size();
     37 
     38   // Make sure the file has at least 2 bytes.
     39   ASSERT_GE(file_size, 2);
     40 
     41   FileError error = FILE_ERROR_FAILED;
     42   operation_->Truncate(
     43       file_in_root,
     44       1,  // Truncate to 1 byte.
     45       google_apis::test_util::CreateCopyResultCallback(&error));
     46   content::RunAllBlockingPoolTasksUntilIdle();
     47   EXPECT_EQ(FILE_ERROR_OK, error);
     48 
     49   base::FilePath local_path;
     50   error = FILE_ERROR_FAILED;
     51   base::PostTaskAndReplyWithResult(
     52       blocking_task_runner(),
     53       FROM_HERE,
     54       base::Bind(&internal::FileCache::GetFile,
     55                  base::Unretained(cache()),
     56                  GetLocalId(file_in_root), &local_path),
     57       google_apis::test_util::CreateCopyResultCallback(&error));
     58   content::RunAllBlockingPoolTasksUntilIdle();
     59   ASSERT_EQ(FILE_ERROR_OK, error);
     60 
     61   // The local file should be truncated.
     62   int64 local_file_size = 0;
     63   base::GetFileSize(local_path, &local_file_size);
     64   EXPECT_EQ(1, local_file_size);
     65 }
     66 
     67 TEST_F(TruncateOperationTest, NegativeSize) {
     68   base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
     69   ResourceEntry src_entry;
     70   ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
     71   const int64 file_size = src_entry.file_info().size();
     72 
     73   // Make sure the file has at least 2 bytes.
     74   ASSERT_GE(file_size, 2);
     75 
     76   FileError error = FILE_ERROR_FAILED;
     77   operation_->Truncate(
     78       file_in_root,
     79       -1,  // Truncate to "-1" byte.
     80       google_apis::test_util::CreateCopyResultCallback(&error));
     81   content::RunAllBlockingPoolTasksUntilIdle();
     82   EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, error);
     83 }
     84 
     85 TEST_F(TruncateOperationTest, HostedDocument) {
     86   base::FilePath file_in_root(FILE_PATH_LITERAL(
     87       "drive/root/Document 1 excludeDir-test.gdoc"));
     88 
     89   FileError error = FILE_ERROR_FAILED;
     90   operation_->Truncate(
     91       file_in_root,
     92       1,  // Truncate to 1 byte.
     93       google_apis::test_util::CreateCopyResultCallback(&error));
     94   content::RunAllBlockingPoolTasksUntilIdle();
     95   EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, error);
     96 }
     97 
     98 TEST_F(TruncateOperationTest, Extend) {
     99   base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
    100   ResourceEntry src_entry;
    101   ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
    102   const int64 file_size = src_entry.file_info().size();
    103 
    104   FileError error = FILE_ERROR_FAILED;
    105   operation_->Truncate(
    106       file_in_root,
    107       file_size + 10,  // Extend to 10 bytes.
    108       google_apis::test_util::CreateCopyResultCallback(&error));
    109   content::RunAllBlockingPoolTasksUntilIdle();
    110   EXPECT_EQ(FILE_ERROR_OK, error);
    111 
    112   base::FilePath local_path;
    113   error = FILE_ERROR_FAILED;
    114   base::PostTaskAndReplyWithResult(
    115       blocking_task_runner(),
    116       FROM_HERE,
    117       base::Bind(&internal::FileCache::GetFile,
    118                  base::Unretained(cache()),
    119                  GetLocalId(file_in_root), &local_path),
    120       google_apis::test_util::CreateCopyResultCallback(&error));
    121   content::RunAllBlockingPoolTasksUntilIdle();
    122   ASSERT_EQ(FILE_ERROR_OK, error);
    123 
    124   // The local file should be truncated.
    125   std::string content;
    126   ASSERT_TRUE(base::ReadFileToString(local_path, &content));
    127 
    128   EXPECT_EQ(file_size + 10, static_cast<int64>(content.size()));
    129   // All trailing 10 bytes should be '\0'.
    130   EXPECT_EQ(std::string(10, '\0'), content.substr(file_size));
    131 }
    132 
    133 }  // namespace file_system
    134 }  // namespace drive
    135