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/open_file_operation.h" 6 7 #include <map> 8 9 #include "base/file_util.h" 10 #include "base/files/file_path.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/task_runner_util.h" 13 #include "chrome/browser/chromeos/drive/drive.pb.h" 14 #include "chrome/browser/chromeos/drive/file_cache.h" 15 #include "chrome/browser/chromeos/drive/file_errors.h" 16 #include "chrome/browser/chromeos/drive/file_system/operation_test_base.h" 17 #include "google_apis/drive/test_util.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 namespace drive { 21 namespace file_system { 22 23 class OpenFileOperationTest : public OperationTestBase { 24 protected: 25 virtual void SetUp() OVERRIDE { 26 OperationTestBase::SetUp(); 27 28 operation_.reset(new OpenFileOperation( 29 blocking_task_runner(), observer(), scheduler(), metadata(), cache(), 30 temp_dir())); 31 } 32 33 scoped_ptr<OpenFileOperation> operation_; 34 }; 35 36 TEST_F(OpenFileOperationTest, OpenExistingFile) { 37 const base::FilePath file_in_root( 38 FILE_PATH_LITERAL("drive/root/File 1.txt")); 39 ResourceEntry src_entry; 40 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 41 const int64 file_size = src_entry.file_info().size(); 42 43 FileError error = FILE_ERROR_FAILED; 44 base::FilePath file_path; 45 base::Closure close_callback; 46 operation_->OpenFile( 47 file_in_root, 48 OPEN_FILE, 49 std::string(), // mime_type 50 google_apis::test_util::CreateCopyResultCallback( 51 &error, &file_path, &close_callback)); 52 test_util::RunBlockingPoolTask(); 53 54 EXPECT_EQ(FILE_ERROR_OK, error); 55 ASSERT_TRUE(base::PathExists(file_path)); 56 int64 local_file_size; 57 ASSERT_TRUE(base::GetFileSize(file_path, &local_file_size)); 58 EXPECT_EQ(file_size, local_file_size); 59 60 ASSERT_FALSE(close_callback.is_null()); 61 close_callback.Run(); 62 EXPECT_EQ(1U, observer()->updated_local_ids().count(src_entry.local_id())); 63 } 64 65 TEST_F(OpenFileOperationTest, OpenNonExistingFile) { 66 const base::FilePath file_in_root( 67 FILE_PATH_LITERAL("drive/root/not-exist.txt")); 68 69 FileError error = FILE_ERROR_FAILED; 70 base::FilePath file_path; 71 base::Closure close_callback; 72 operation_->OpenFile( 73 file_in_root, 74 OPEN_FILE, 75 std::string(), // mime_type 76 google_apis::test_util::CreateCopyResultCallback( 77 &error, &file_path, &close_callback)); 78 test_util::RunBlockingPoolTask(); 79 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error); 80 EXPECT_TRUE(close_callback.is_null()); 81 } 82 83 TEST_F(OpenFileOperationTest, CreateExistingFile) { 84 const base::FilePath file_in_root( 85 FILE_PATH_LITERAL("drive/root/File 1.txt")); 86 ResourceEntry src_entry; 87 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 88 89 FileError error = FILE_ERROR_FAILED; 90 base::FilePath file_path; 91 base::Closure close_callback; 92 operation_->OpenFile( 93 file_in_root, 94 CREATE_FILE, 95 std::string(), // mime_type 96 google_apis::test_util::CreateCopyResultCallback( 97 &error, &file_path, &close_callback)); 98 test_util::RunBlockingPoolTask(); 99 100 EXPECT_EQ(FILE_ERROR_EXISTS, error); 101 EXPECT_TRUE(close_callback.is_null()); 102 } 103 104 TEST_F(OpenFileOperationTest, CreateNonExistingFile) { 105 const base::FilePath file_in_root( 106 FILE_PATH_LITERAL("drive/root/not-exist.txt")); 107 108 FileError error = FILE_ERROR_FAILED; 109 base::FilePath file_path; 110 base::Closure close_callback; 111 operation_->OpenFile( 112 file_in_root, 113 CREATE_FILE, 114 std::string(), // mime_type 115 google_apis::test_util::CreateCopyResultCallback( 116 &error, &file_path, &close_callback)); 117 test_util::RunBlockingPoolTask(); 118 119 EXPECT_EQ(1U, observer()->get_changed_paths().size()); 120 EXPECT_TRUE(observer()->get_changed_paths().count(file_in_root.DirName())); 121 122 EXPECT_EQ(FILE_ERROR_OK, error); 123 ASSERT_TRUE(base::PathExists(file_path)); 124 int64 local_file_size; 125 ASSERT_TRUE(base::GetFileSize(file_path, &local_file_size)); 126 EXPECT_EQ(0, local_file_size); // Should be an empty file. 127 128 ASSERT_FALSE(close_callback.is_null()); 129 close_callback.Run(); 130 EXPECT_EQ(1U, 131 observer()->updated_local_ids().count(GetLocalId(file_in_root))); 132 } 133 134 TEST_F(OpenFileOperationTest, OpenOrCreateExistingFile) { 135 const base::FilePath file_in_root( 136 FILE_PATH_LITERAL("drive/root/File 1.txt")); 137 ResourceEntry src_entry; 138 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 139 const int64 file_size = src_entry.file_info().size(); 140 141 FileError error = FILE_ERROR_FAILED; 142 base::FilePath file_path; 143 base::Closure close_callback; 144 operation_->OpenFile( 145 file_in_root, 146 OPEN_OR_CREATE_FILE, 147 std::string(), // mime_type 148 google_apis::test_util::CreateCopyResultCallback( 149 &error, &file_path, &close_callback)); 150 test_util::RunBlockingPoolTask(); 151 152 // Notified because 'available offline' status of the existing file changes. 153 EXPECT_EQ(1U, observer()->get_changed_paths().size()); 154 EXPECT_TRUE(observer()->get_changed_paths().count(file_in_root.DirName())); 155 156 EXPECT_EQ(FILE_ERROR_OK, error); 157 ASSERT_TRUE(base::PathExists(file_path)); 158 int64 local_file_size; 159 ASSERT_TRUE(base::GetFileSize(file_path, &local_file_size)); 160 EXPECT_EQ(file_size, local_file_size); 161 162 ASSERT_FALSE(close_callback.is_null()); 163 close_callback.Run(); 164 EXPECT_EQ(1U, observer()->updated_local_ids().count(src_entry.local_id())); 165 166 ResourceEntry result_entry; 167 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &result_entry)); 168 EXPECT_TRUE(result_entry.file_specific_info().cache_state().is_present()); 169 EXPECT_TRUE(result_entry.file_specific_info().cache_state().is_dirty()); 170 } 171 172 TEST_F(OpenFileOperationTest, OpenOrCreateNonExistingFile) { 173 const base::FilePath file_in_root( 174 FILE_PATH_LITERAL("drive/root/not-exist.txt")); 175 176 FileError error = FILE_ERROR_FAILED; 177 base::FilePath file_path; 178 base::Closure close_callback; 179 operation_->OpenFile( 180 file_in_root, 181 OPEN_OR_CREATE_FILE, 182 std::string(), // mime_type 183 google_apis::test_util::CreateCopyResultCallback( 184 &error, &file_path, &close_callback)); 185 test_util::RunBlockingPoolTask(); 186 187 EXPECT_EQ(FILE_ERROR_OK, error); 188 ASSERT_TRUE(base::PathExists(file_path)); 189 int64 local_file_size; 190 ASSERT_TRUE(base::GetFileSize(file_path, &local_file_size)); 191 EXPECT_EQ(0, local_file_size); // Should be an empty file. 192 193 ASSERT_FALSE(close_callback.is_null()); 194 close_callback.Run(); 195 EXPECT_EQ(1U, 196 observer()->updated_local_ids().count(GetLocalId(file_in_root))); 197 } 198 199 TEST_F(OpenFileOperationTest, OpenFileTwice) { 200 const base::FilePath file_in_root( 201 FILE_PATH_LITERAL("drive/root/File 1.txt")); 202 ResourceEntry src_entry; 203 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 204 const int64 file_size = src_entry.file_info().size(); 205 206 FileError error = FILE_ERROR_FAILED; 207 base::FilePath file_path; 208 base::Closure close_callback; 209 operation_->OpenFile( 210 file_in_root, 211 OPEN_FILE, 212 std::string(), // mime_type 213 google_apis::test_util::CreateCopyResultCallback( 214 &error, &file_path, &close_callback)); 215 test_util::RunBlockingPoolTask(); 216 217 EXPECT_EQ(FILE_ERROR_OK, error); 218 ASSERT_TRUE(base::PathExists(file_path)); 219 int64 local_file_size; 220 ASSERT_TRUE(base::GetFileSize(file_path, &local_file_size)); 221 EXPECT_EQ(file_size, local_file_size); 222 223 // Open again. 224 error = FILE_ERROR_FAILED; 225 base::Closure close_callback2; 226 operation_->OpenFile( 227 file_in_root, 228 OPEN_FILE, 229 std::string(), // mime_type 230 google_apis::test_util::CreateCopyResultCallback( 231 &error, &file_path, &close_callback2)); 232 test_util::RunBlockingPoolTask(); 233 234 EXPECT_EQ(FILE_ERROR_OK, error); 235 ASSERT_TRUE(base::PathExists(file_path)); 236 ASSERT_TRUE(base::GetFileSize(file_path, &local_file_size)); 237 EXPECT_EQ(file_size, local_file_size); 238 239 ASSERT_FALSE(close_callback.is_null()); 240 ASSERT_FALSE(close_callback2.is_null()); 241 242 close_callback.Run(); 243 244 // There still remains a client opening the file, so it shouldn't be 245 // uploaded yet. 246 EXPECT_TRUE(observer()->updated_local_ids().empty()); 247 248 close_callback2.Run(); 249 250 // Here, all the clients close the file, so it should be uploaded then. 251 EXPECT_EQ(1U, observer()->updated_local_ids().count(src_entry.local_id())); 252 } 253 254 } // namespace file_system 255 } // namespace drive 256