| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
| 12 #include "net/url_request/url_request.h" | 12 #include "net/url_request/url_request.h" |
| 13 #include "net/url_request/url_request_context.h" | 13 #include "net/url_request/url_request_context.h" |
| 14 #include "net/url_request/url_request_job.h" | 14 #include "net/url_request/url_request_job.h" |
| 15 #include "net/url_request/url_request_job_factory_impl.h" | 15 #include "net/url_request/url_request_job_factory_impl.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "url/gurl.h" | 17 #include "url/gurl.h" |
| 18 #include "webkit/browser/blob/blob_storage_controller.h" | 18 #include "webkit/browser/blob/blob_storage_context.h" |
| 19 #include "webkit/browser/blob/blob_url_request_job.h" | 19 #include "webkit/browser/blob/blob_url_request_job.h" |
| 20 #include "webkit/browser/blob/mock_blob_url_request_context.h" | 20 #include "webkit/browser/blob/mock_blob_url_request_context.h" |
| 21 #include "webkit/browser/fileapi/file_system_context.h" | 21 #include "webkit/browser/fileapi/file_system_context.h" |
| 22 #include "webkit/browser/fileapi/file_system_file_util.h" | 22 #include "webkit/browser/fileapi/file_system_file_util.h" |
| 23 #include "webkit/browser/fileapi/file_system_operation_context.h" | 23 #include "webkit/browser/fileapi/file_system_operation_context.h" |
| 24 #include "webkit/browser/fileapi/file_system_operation_runner.h" | 24 #include "webkit/browser/fileapi/file_system_operation_runner.h" |
| 25 #include "webkit/browser/fileapi/local_file_util.h" | 25 #include "webkit/browser/fileapi/local_file_util.h" |
| 26 #include "webkit/browser/fileapi/mock_file_change_observer.h" | 26 #include "webkit/browser/fileapi/mock_file_change_observer.h" |
| 27 #include "webkit/browser/fileapi/mock_file_system_context.h" | 27 #include "webkit/browser/fileapi/mock_file_system_context.h" |
| 28 #include "webkit/browser/fileapi/test_file_system_backend.h" | 28 #include "webkit/browser/fileapi/test_file_system_backend.h" |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 | 167 |
| 168 MockFileChangeObserver change_observer_; | 168 MockFileChangeObserver change_observer_; |
| 169 ChangeObserverList change_observers_; | 169 ChangeObserverList change_observers_; |
| 170 | 170 |
| 171 base::WeakPtrFactory<FileSystemOperationImplWriteTest> weak_factory_; | 171 base::WeakPtrFactory<FileSystemOperationImplWriteTest> weak_factory_; |
| 172 | 172 |
| 173 DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImplWriteTest); | 173 DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImplWriteTest); |
| 174 }; | 174 }; |
| 175 | 175 |
| 176 TEST_F(FileSystemOperationImplWriteTest, TestWriteSuccess) { | 176 TEST_F(FileSystemOperationImplWriteTest, TestWriteSuccess) { |
| 177 const GURL blob_url("blob:success"); | 177 ScopedTextBlob blob(url_request_context(), |
| 178 ScopedTextBlob blob(url_request_context(), blob_url, "Hello, world!\n"); | 178 "blob-id:success", |
| 179 | 179 "Hello, world!\n"); |
| 180 file_system_context_->operation_runner()->Write( | 180 file_system_context_->operation_runner()->Write( |
| 181 &url_request_context(), URLForPath(virtual_path_), blob_url, | 181 &url_request_context(), URLForPath(virtual_path_), |
| 182 blob.GetBlobDataHandle(), |
| 182 0, RecordWriteCallback()); | 183 0, RecordWriteCallback()); |
| 183 base::MessageLoop::current()->Run(); | 184 base::MessageLoop::current()->Run(); |
| 184 | 185 |
| 185 EXPECT_EQ(14, bytes_written()); | 186 EXPECT_EQ(14, bytes_written()); |
| 186 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | 187 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| 187 EXPECT_TRUE(complete()); | 188 EXPECT_TRUE(complete()); |
| 188 | 189 |
| 189 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | 190 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| 190 } | 191 } |
| 191 | 192 |
| 192 TEST_F(FileSystemOperationImplWriteTest, TestWriteZero) { | 193 TEST_F(FileSystemOperationImplWriteTest, TestWriteZero) { |
| 193 GURL blob_url("blob:zero"); | 194 ScopedTextBlob blob(url_request_context(), "blob_id:zero", ""); |
| 194 scoped_refptr<webkit_blob::BlobData> blob_data(new webkit_blob::BlobData()); | |
| 195 | |
| 196 url_request_context().blob_storage_controller() | |
| 197 ->AddFinishedBlob(blob_url, blob_data.get()); | |
| 198 | |
| 199 file_system_context_->operation_runner()->Write( | 195 file_system_context_->operation_runner()->Write( |
| 200 &url_request_context(), URLForPath(virtual_path_), | 196 &url_request_context(), URLForPath(virtual_path_), |
| 201 blob_url, 0, RecordWriteCallback()); | 197 blob.GetBlobDataHandle(), 0, RecordWriteCallback()); |
| 202 base::MessageLoop::current()->Run(); | 198 base::MessageLoop::current()->Run(); |
| 203 | 199 |
| 204 url_request_context().blob_storage_controller()->RemoveBlob(blob_url); | |
| 205 | |
| 206 EXPECT_EQ(0, bytes_written()); | 200 EXPECT_EQ(0, bytes_written()); |
| 207 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | 201 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| 208 EXPECT_TRUE(complete()); | 202 EXPECT_TRUE(complete()); |
| 209 | 203 |
| 210 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | 204 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| 211 } | 205 } |
| 212 | 206 |
| 207 |
| 213 TEST_F(FileSystemOperationImplWriteTest, TestWriteInvalidBlobUrl) { | 208 TEST_F(FileSystemOperationImplWriteTest, TestWriteInvalidBlobUrl) { |
| 209 scoped_ptr<webkit_blob::BlobDataHandle> null_handle; |
| 214 file_system_context_->operation_runner()->Write( | 210 file_system_context_->operation_runner()->Write( |
| 215 &url_request_context(), URLForPath(virtual_path_), | 211 &url_request_context(), URLForPath(virtual_path_), |
| 216 GURL("blob:invalid"), 0, RecordWriteCallback()); | 212 null_handle.Pass(), 0, RecordWriteCallback()); |
| 217 base::MessageLoop::current()->Run(); | 213 base::MessageLoop::current()->Run(); |
| 218 | 214 |
| 219 EXPECT_EQ(0, bytes_written()); | 215 EXPECT_EQ(0, bytes_written()); |
| 220 EXPECT_EQ(base::PLATFORM_FILE_ERROR_FAILED, status()); | 216 EXPECT_EQ(base::PLATFORM_FILE_ERROR_FAILED, status()); |
| 221 EXPECT_TRUE(complete()); | 217 EXPECT_TRUE(complete()); |
| 222 | 218 |
| 223 EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count()); | 219 EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count()); |
| 224 } | 220 } |
| 225 | 221 |
| 226 TEST_F(FileSystemOperationImplWriteTest, TestWriteInvalidFile) { | 222 TEST_F(FileSystemOperationImplWriteTest, TestWriteInvalidFile) { |
| 227 GURL blob_url("blob:writeinvalidfile"); | 223 ScopedTextBlob blob(url_request_context(), "blob_id:writeinvalidfile", |
| 228 ScopedTextBlob blob(url_request_context(), blob_url, | |
| 229 "It\'ll not be written."); | 224 "It\'ll not be written."); |
| 230 | |
| 231 file_system_context_->operation_runner()->Write( | 225 file_system_context_->operation_runner()->Write( |
| 232 &url_request_context(), | 226 &url_request_context(), |
| 233 URLForPath(base::FilePath(FILE_PATH_LITERAL("nonexist"))), | 227 URLForPath(base::FilePath(FILE_PATH_LITERAL("nonexist"))), |
| 234 blob_url, 0, RecordWriteCallback()); | 228 blob.GetBlobDataHandle(), 0, RecordWriteCallback()); |
| 235 base::MessageLoop::current()->Run(); | 229 base::MessageLoop::current()->Run(); |
| 236 | 230 |
| 237 EXPECT_EQ(0, bytes_written()); | 231 EXPECT_EQ(0, bytes_written()); |
| 238 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | 232 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| 239 EXPECT_TRUE(complete()); | 233 EXPECT_TRUE(complete()); |
| 240 | 234 |
| 241 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | 235 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| 242 } | 236 } |
| 243 | 237 |
| 244 TEST_F(FileSystemOperationImplWriteTest, TestWriteDir) { | 238 TEST_F(FileSystemOperationImplWriteTest, TestWriteDir) { |
| 245 base::FilePath virtual_dir_path(FILE_PATH_LITERAL("d")); | 239 base::FilePath virtual_dir_path(FILE_PATH_LITERAL("d")); |
| 246 file_system_context_->operation_runner()->CreateDirectory( | 240 file_system_context_->operation_runner()->CreateDirectory( |
| 247 URLForPath(virtual_dir_path), | 241 URLForPath(virtual_dir_path), |
| 248 true /* exclusive */, false /* recursive */, | 242 true /* exclusive */, false /* recursive */, |
| 249 base::Bind(&AssertStatusEq, base::PLATFORM_FILE_OK)); | 243 base::Bind(&AssertStatusEq, base::PLATFORM_FILE_OK)); |
| 250 | 244 |
| 251 GURL blob_url("blob:writedir"); | 245 ScopedTextBlob blob(url_request_context(), "blob:writedir", |
| 252 ScopedTextBlob blob(url_request_context(), blob_url, | |
| 253 "It\'ll not be written, too."); | 246 "It\'ll not be written, too."); |
| 254 | |
| 255 file_system_context_->operation_runner()->Write( | 247 file_system_context_->operation_runner()->Write( |
| 256 &url_request_context(), URLForPath(virtual_dir_path), | 248 &url_request_context(), URLForPath(virtual_dir_path), |
| 257 blob_url, 0, RecordWriteCallback()); | 249 blob.GetBlobDataHandle(), 0, RecordWriteCallback()); |
| 258 base::MessageLoop::current()->Run(); | 250 base::MessageLoop::current()->Run(); |
| 259 | 251 |
| 260 EXPECT_EQ(0, bytes_written()); | 252 EXPECT_EQ(0, bytes_written()); |
| 261 // TODO(kinuko): This error code is platform- or fileutil- dependent | 253 // TODO(kinuko): This error code is platform- or fileutil- dependent |
| 262 // right now. Make it return PLATFORM_FILE_ERROR_NOT_A_FILE in every case. | 254 // right now. Make it return PLATFORM_FILE_ERROR_NOT_A_FILE in every case. |
| 263 EXPECT_TRUE(status() == base::PLATFORM_FILE_ERROR_NOT_A_FILE || | 255 EXPECT_TRUE(status() == base::PLATFORM_FILE_ERROR_NOT_A_FILE || |
| 264 status() == base::PLATFORM_FILE_ERROR_ACCESS_DENIED || | 256 status() == base::PLATFORM_FILE_ERROR_ACCESS_DENIED || |
| 265 status() == base::PLATFORM_FILE_ERROR_FAILED); | 257 status() == base::PLATFORM_FILE_ERROR_FAILED); |
| 266 EXPECT_TRUE(complete()); | 258 EXPECT_TRUE(complete()); |
| 267 | 259 |
| 268 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | 260 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| 269 } | 261 } |
| 270 | 262 |
| 271 TEST_F(FileSystemOperationImplWriteTest, TestWriteFailureByQuota) { | 263 TEST_F(FileSystemOperationImplWriteTest, TestWriteFailureByQuota) { |
| 272 GURL blob_url("blob:success"); | 264 ScopedTextBlob blob(url_request_context(), "blob:success", |
| 273 ScopedTextBlob blob(url_request_context(), blob_url, "Hello, world!\n"); | 265 "Hello, world!\n"); |
| 274 | |
| 275 quota_manager_->SetQuota( | 266 quota_manager_->SetQuota( |
| 276 kOrigin, FileSystemTypeToQuotaStorageType(kFileSystemType), 10); | 267 kOrigin, FileSystemTypeToQuotaStorageType(kFileSystemType), 10); |
| 277 file_system_context_->operation_runner()->Write( | 268 file_system_context_->operation_runner()->Write( |
| 278 &url_request_context(), URLForPath(virtual_path_), blob_url, | 269 &url_request_context(), URLForPath(virtual_path_), |
| 279 0, RecordWriteCallback()); | 270 blob.GetBlobDataHandle(), 0, RecordWriteCallback()); |
| 280 base::MessageLoop::current()->Run(); | 271 base::MessageLoop::current()->Run(); |
| 281 | 272 |
| 282 EXPECT_EQ(10, bytes_written()); | 273 EXPECT_EQ(10, bytes_written()); |
| 283 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); | 274 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); |
| 284 EXPECT_TRUE(complete()); | 275 EXPECT_TRUE(complete()); |
| 285 | 276 |
| 286 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | 277 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| 287 } | 278 } |
| 288 | 279 |
| 289 TEST_F(FileSystemOperationImplWriteTest, TestImmediateCancelSuccessfulWrite) { | 280 TEST_F(FileSystemOperationImplWriteTest, TestImmediateCancelSuccessfulWrite) { |
| 290 GURL blob_url("blob:success"); | 281 ScopedTextBlob blob(url_request_context(), "blob:success", |
| 291 ScopedTextBlob blob(url_request_context(), blob_url, "Hello, world!\n"); | 282 "Hello, world!\n"); |
| 292 | |
| 293 FileSystemOperationRunner::OperationID id = | 283 FileSystemOperationRunner::OperationID id = |
| 294 file_system_context_->operation_runner()->Write( | 284 file_system_context_->operation_runner()->Write( |
| 295 &url_request_context(), URLForPath(virtual_path_), | 285 &url_request_context(), URLForPath(virtual_path_), |
| 296 blob_url, 0, RecordWriteCallback()); | 286 blob.GetBlobDataHandle(), 0, RecordWriteCallback()); |
| 297 file_system_context_->operation_runner()->Cancel(id, RecordCancelCallback()); | 287 file_system_context_->operation_runner()->Cancel(id, RecordCancelCallback()); |
| 298 // We use RunAllPendings() instead of Run() here, because we won't dispatch | 288 // We use RunAllPendings() instead of Run() here, because we won't dispatch |
| 299 // callbacks after Cancel() is issued (so no chance to Quit) nor do we need | 289 // callbacks after Cancel() is issued (so no chance to Quit) nor do we need |
| 300 // to run another write cycle. | 290 // to run another write cycle. |
| 301 base::MessageLoop::current()->RunUntilIdle(); | 291 base::MessageLoop::current()->RunUntilIdle(); |
| 302 | 292 |
| 303 // Issued Cancel() before receiving any response from Write(), | 293 // Issued Cancel() before receiving any response from Write(), |
| 304 // so nothing should have happen. | 294 // so nothing should have happen. |
| 305 EXPECT_EQ(0, bytes_written()); | 295 EXPECT_EQ(0, bytes_written()); |
| 306 EXPECT_EQ(base::PLATFORM_FILE_ERROR_ABORT, status()); | 296 EXPECT_EQ(base::PLATFORM_FILE_ERROR_ABORT, status()); |
| 307 EXPECT_EQ(base::PLATFORM_FILE_OK, cancel_status()); | 297 EXPECT_EQ(base::PLATFORM_FILE_OK, cancel_status()); |
| 308 EXPECT_TRUE(complete()); | 298 EXPECT_TRUE(complete()); |
| 309 | 299 |
| 310 EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count()); | 300 EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count()); |
| 311 } | 301 } |
| 312 | 302 |
| 313 TEST_F(FileSystemOperationImplWriteTest, TestImmediateCancelFailingWrite) { | 303 TEST_F(FileSystemOperationImplWriteTest, TestImmediateCancelFailingWrite) { |
| 314 GURL blob_url("blob:writeinvalidfile"); | 304 ScopedTextBlob blob(url_request_context(), "blob:writeinvalidfile", |
| 315 ScopedTextBlob blob(url_request_context(), blob_url, | |
| 316 "It\'ll not be written."); | 305 "It\'ll not be written."); |
| 317 | |
| 318 FileSystemOperationRunner::OperationID id = | 306 FileSystemOperationRunner::OperationID id = |
| 319 file_system_context_->operation_runner()->Write( | 307 file_system_context_->operation_runner()->Write( |
| 320 &url_request_context(), | 308 &url_request_context(), |
| 321 URLForPath(base::FilePath(FILE_PATH_LITERAL("nonexist"))), | 309 URLForPath(base::FilePath(FILE_PATH_LITERAL("nonexist"))), |
| 322 blob_url, 0, RecordWriteCallback()); | 310 blob.GetBlobDataHandle(), 0, RecordWriteCallback()); |
| 323 file_system_context_->operation_runner()->Cancel(id, RecordCancelCallback()); | 311 file_system_context_->operation_runner()->Cancel(id, RecordCancelCallback()); |
| 324 // We use RunAllPendings() instead of Run() here, because we won't dispatch | 312 // We use RunAllPendings() instead of Run() here, because we won't dispatch |
| 325 // callbacks after Cancel() is issued (so no chance to Quit) nor do we need | 313 // callbacks after Cancel() is issued (so no chance to Quit) nor do we need |
| 326 // to run another write cycle. | 314 // to run another write cycle. |
| 327 base::MessageLoop::current()->RunUntilIdle(); | 315 base::MessageLoop::current()->RunUntilIdle(); |
| 328 | 316 |
| 329 // Issued Cancel() before receiving any response from Write(), | 317 // Issued Cancel() before receiving any response from Write(), |
| 330 // so nothing should have happen. | 318 // so nothing should have happen. |
| 331 EXPECT_EQ(0, bytes_written()); | 319 EXPECT_EQ(0, bytes_written()); |
| 332 EXPECT_EQ(base::PLATFORM_FILE_ERROR_ABORT, status()); | 320 EXPECT_EQ(base::PLATFORM_FILE_ERROR_ABORT, status()); |
| 333 EXPECT_EQ(base::PLATFORM_FILE_OK, cancel_status()); | 321 EXPECT_EQ(base::PLATFORM_FILE_OK, cancel_status()); |
| 334 EXPECT_TRUE(complete()); | 322 EXPECT_TRUE(complete()); |
| 335 | 323 |
| 336 EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count()); | 324 EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count()); |
| 337 } | 325 } |
| 338 | 326 |
| 339 // TODO(ericu,dmikurube,kinuko): Add more tests for cancel cases. | 327 // TODO(ericu,dmikurube,kinuko): Add more tests for cancel cases. |
| 340 | 328 |
| 341 } // namespace fileapi | 329 } // namespace fileapi |
| OLD | NEW |