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