1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/file_system/truncate_operation.h"
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/file_util.h"
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/files/file_path.h"
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/task_runner_util.h"
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/drive.pb.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/test_util.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive {
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace file_system {
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass TruncateOperationTest : public OperationTestBase {
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protected:
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    OperationTestBase::SetUp();
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    operation_.reset(new TruncateOperation(
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        blocking_task_runner(), observer(), scheduler(),
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        metadata(), cache(), temp_dir()));
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<TruncateOperation> operation_;
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(TruncateOperationTest, Truncate) {
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ResourceEntry src_entry;
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const int64 file_size = src_entry.file_info().size();
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Make sure the file has at least 2 bytes.
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_GE(file_size, 2);
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FileError error = FILE_ERROR_FAILED;
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  operation_->Truncate(
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      file_in_root,
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      1,  // Truncate to 1 byte.
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      google_apis::test_util::CreateCopyResultCallback(&error));
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  test_util::RunBlockingPoolTask();
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(FILE_ERROR_OK, error);
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::FilePath local_path;
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  error = FILE_ERROR_FAILED;
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      blocking_task_runner(),
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      FROM_HERE,
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&internal::FileCache::GetFile,
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 base::Unretained(cache()),
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 GetLocalId(file_in_root), &local_path),
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      google_apis::test_util::CreateCopyResultCallback(&error));
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  test_util::RunBlockingPoolTask();
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(FILE_ERROR_OK, error);
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The local file should be truncated.
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int64 local_file_size = 0;
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::GetFileSize(local_path, &local_file_size);
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(1, local_file_size);
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(TruncateOperationTest, NegativeSize) {
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ResourceEntry src_entry;
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const int64 file_size = src_entry.file_info().size();
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Make sure the file has at least 2 bytes.
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_GE(file_size, 2);
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FileError error = FILE_ERROR_FAILED;
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  operation_->Truncate(
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      file_in_root,
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      -1,  // Truncate to "-1" byte.
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      google_apis::test_util::CreateCopyResultCallback(&error));
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  test_util::RunBlockingPoolTask();
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, error);
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(TruncateOperationTest, HostedDocument) {
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::FilePath file_in_root(FILE_PATH_LITERAL(
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      "drive/root/Document 1 excludeDir-test.gdoc"));
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FileError error = FILE_ERROR_FAILED;
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  operation_->Truncate(
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      file_in_root,
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      1,  // Truncate to 1 byte.
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      google_apis::test_util::CreateCopyResultCallback(&error));
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  test_util::RunBlockingPoolTask();
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, error);
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(TruncateOperationTest, Extend) {
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ResourceEntry src_entry;
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const int64 file_size = src_entry.file_info().size();
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FileError error = FILE_ERROR_FAILED;
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  operation_->Truncate(
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      file_in_root,
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      file_size + 10,  // Extend to 10 bytes.
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      google_apis::test_util::CreateCopyResultCallback(&error));
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  test_util::RunBlockingPoolTask();
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(FILE_ERROR_OK, error);
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::FilePath local_path;
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  error = FILE_ERROR_FAILED;
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      blocking_task_runner(),
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      FROM_HERE,
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&internal::FileCache::GetFile,
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 base::Unretained(cache()),
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 GetLocalId(file_in_root), &local_path),
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      google_apis::test_util::CreateCopyResultCallback(&error));
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  test_util::RunBlockingPoolTask();
122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(FILE_ERROR_OK, error);
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The local file should be truncated.
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string content;
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(base::ReadFileToString(local_path, &content));
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(file_size + 10, static_cast<int64>(content.size()));
129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // All trailing 10 bytes should be '\0'.
130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(std::string(10, '\0'), content.substr(file_size));
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace file_system
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive
135