190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/files/file.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/thread_task_runner_handle.h" 142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h" 152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" 162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_context.h" 172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_status.h" 182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" 192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/syncable_file_operation_runner.h" 202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/syncable_file_system_operation.h" 212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/mock_blob_url_request_context.h" 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h" 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/helpers/memenv/memenv.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperation; 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL; 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::MockBlobURLRequestContext; 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::ScopedTextBlob; 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::File; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string kParent = "foo"; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string kFile = "foo/file"; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string kDir = "foo/dir"; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string kChild = "foo/dir/bar"; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string kOther = "bar"; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncableFileOperationRunnerTest : public testing::Test { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef FileSystemOperation::StatusCallback StatusCallback; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the current thread as IO thread so that we can directly call 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // operations in the tests. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncableFileOperationRunnerTest() 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) in_memory_env_(leveldb::NewMemEnv(leveldb::Env::Default())), 557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) file_system_(GURL("http://example.com"), 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) in_memory_env_.get(), 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::ThreadTaskRunnerHandle::Get().get(), 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::ThreadTaskRunnerHandle::Get().get()), 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback_count_(0), 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) write_status_(File::FILE_ERROR_FAILED), 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) write_bytes_(0), 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) write_complete_(false), 637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) url_request_context_(file_system_.file_system_context()), 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_factory_(this) {} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(dir_.CreateUniqueTempDir()); 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_system_.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED); 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sync_context_ = new LocalFileSyncContext( 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dir_.path(), 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) in_memory_env_.get(), 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::ThreadTaskRunnerHandle::Get().get(), 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::ThreadTaskRunnerHandle::Get().get()); 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_EQ( 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SYNC_STATUS_OK, 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.MaybeInitializeFileSystemContext(sync_context_.get())); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(File::FILE_OK, file_system_.OpenFileSystem()); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(File::FILE_OK, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_.CreateDirectory(URL(kParent))); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE { 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (sync_context_.get()) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_context_->ShutdownOnUIThread(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_context_ = NULL; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_.TearDown(); 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RevokeSyncableFileSystem(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemURL URL(const std::string& path) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file_system_.URL(path); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LocalFileSyncStatus* sync_status() { 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return file_system_.backend()->sync_context()->sync_status(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetCallbackStatus() { 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) write_status_ = File::FILE_ERROR_FAILED; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_bytes_ = 0; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_complete_ = false; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_count_ = 0; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatusCallback ExpectStatus(const tracked_objects::Location& location, 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) File::Error expect) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Bind(&SyncableFileOperationRunnerTest::DidFinish, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), location, expect); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemOperation::WriteCallback GetWriteCallback( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& location) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Bind(&SyncableFileOperationRunnerTest::DidWrite, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), location); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DidWrite(const tracked_objects::Location& location, 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) File::Error status, int64 bytes, bool complete) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(testing::Message() << location.ToString()); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_status_ = status; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_bytes_ += bytes; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_complete_ = complete; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++callback_count_; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DidFinish(const tracked_objects::Location& location, 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) File::Error expect, File::Error status) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(testing::Message() << location.ToString()); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expect, status); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++callback_count_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool CreateTempFile(base::FilePath* path) { 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return base::CreateTemporaryFileInDir(dir_.path(), path); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::TestBrowserThreadBundle thread_bundle_; 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ScopedTempDir dir_; 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<leveldb::Env> in_memory_env_; 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CannedSyncableFileSystem file_system_; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<LocalFileSyncContext> sync_context_; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int callback_count_; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) File::Error write_status_; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t write_bytes_; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool write_complete_; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockBlobURLRequestContext url_request_context_; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private: 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<SyncableFileOperationRunnerTest> weak_factory_; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SyncableFileOperationRunnerTest); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncableFileOperationRunnerTest, SimpleQueue) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->StartSyncing(URL(kFile)); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(sync_status()->IsWritable(URL(kFile))); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The URL is in syncing so the write operations won't run. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->CreateFile( 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URL(kFile), false /* exclusive */, 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Truncate( 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URL(kFile), 1, 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, callback_count_); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read operations are not blocked (and are executed before queued ones). 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->FileExists( 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) URL(kFile), ExpectStatus(FROM_HERE, File::FILE_ERROR_NOT_FOUND)); 179b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, callback_count_); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // End syncing (to enable write). 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->EndSyncing(URL(kFile)); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(sync_status()->IsWritable(URL(kFile))); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2, callback_count_); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now the file must have been created and updated. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->FileExists( 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) URL(kFile), ExpectStatus(FROM_HERE, File::FILE_OK)); 194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, callback_count_); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncableFileOperationRunnerTest, WriteToParentAndChild) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First create the kDir directory and kChild in the dir. 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_OK, file_system_.CreateDirectory(URL(kDir))); 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_OK, file_system_.CreateFile(URL(kChild))); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start syncing the kDir directory. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->StartSyncing(URL(kDir)); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(sync_status()->IsWritable(URL(kDir))); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Writes to kParent and kChild should be all queued up. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Truncate( 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) URL(kChild), 1, ExpectStatus(FROM_HERE, File::FILE_OK)); 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Remove( 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URL(kParent), true /* recursive */, 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, callback_count_); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read operations are not blocked (and are executed before queued ones). 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->DirectoryExists( 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) URL(kDir), ExpectStatus(FROM_HERE, File::FILE_OK)); 220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, callback_count_); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Writes to unrelated files must succeed as well. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->CreateDirectory( 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URL(kOther), false /* exclusive */, false /* recursive */, 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 228b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, callback_count_); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // End syncing (to enable write). 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->EndSyncing(URL(kDir)); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(sync_status()->IsWritable(URL(kDir))); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 236b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2, callback_count_); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncableFileOperationRunnerTest, CopyAndMove) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First create the kDir directory and kChild in the dir. 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_OK, file_system_.CreateDirectory(URL(kDir))); 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_OK, file_system_.CreateFile(URL(kChild))); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start syncing the kParent directory. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->StartSyncing(URL(kParent)); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copying kDir to other directory should succeed, while moving would fail 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (since the source directory is in syncing). 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Copy( 25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) URL(kDir), 25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) URL("dest-copy"), 25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemOperation::OPTION_NONE, 25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemOperationRunner::CopyProgressCallback(), 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Move( 25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) URL(kDir), 25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) URL("dest-move"), 26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemOperation::OPTION_NONE, 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 262b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, callback_count_); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only "dest-copy1" should exist. 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_OK, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_.DirectoryExists(URL("dest-copy"))); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_ERROR_NOT_FOUND, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_.DirectoryExists(URL("dest-move"))); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start syncing the "dest-copy2" directory. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->StartSyncing(URL("dest-copy2")); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now the destination is also locked copying kDir should be queued. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Copy( 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) URL(kDir), 27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) URL("dest-copy2"), 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemOperation::OPTION_NONE, 28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemOperationRunner::CopyProgressCallback(), 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 282b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, callback_count_); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finish syncing the "dest-copy2" directory to unlock Copy. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->EndSyncing(URL("dest-copy2")); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 288b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, callback_count_); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now we should have "dest-copy2". 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_OK, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_.DirectoryExists(URL("dest-copy2"))); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finish syncing the kParent to unlock Move. 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->EndSyncing(URL(kParent)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, callback_count_); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now we should have "dest-move". 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_OK, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_.DirectoryExists(URL("dest-move"))); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncableFileOperationRunnerTest, Write) { 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_OK, file_system_.CreateFile(URL(kFile))); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kData("Lorem ipsum."); 30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScopedTextBlob blob(url_request_context_, "blob:foo", kData); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->StartSyncing(URL(kFile)); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Write( 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &url_request_context_, 31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) URL(kFile), blob.GetBlobDataHandle(), 0, GetWriteCallback(FROM_HERE)); 317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, callback_count_); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->EndSyncing(URL(kFile)); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!write_complete_) 324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(File::FILE_OK, write_status_); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kData.size(), write_bytes_); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(write_complete_); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncableFileOperationRunnerTest, QueueAndCancel) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->StartSyncing(URL(kFile)); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(sync_status()->IsWritable(URL(kFile))); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->CreateFile( 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URL(kFile), false /* exclusive */, 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_ERROR_ABORT)); 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Truncate( 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URL(kFile), 1, 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_ERROR_ABORT)); 342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, callback_count_); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetCallbackStatus(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This shouldn't crash nor leak memory. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_context_->ShutdownOnUIThread(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_context_ = NULL; 350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2, callback_count_); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Test if CopyInForeignFile runs cooperatively with other Sync operations. 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(SyncableFileOperationRunnerTest, CopyInForeignFile) { 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string kTestData("test data"); 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath temp_path; 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(CreateTempFile(&temp_path)); 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(static_cast<int>(kTestData.size()), 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WriteFile( 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) temp_path, kTestData.data(), kTestData.size())); 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sync_status()->StartSyncing(URL(kFile)); 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_FALSE(sync_status()->IsWritable(URL(kFile))); 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The URL is in syncing so CopyIn (which is a write operation) won't run. 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResetCallbackStatus(); 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->CopyInForeignFile( 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) temp_path, URL(kFile), 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 372b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(0, callback_count_); 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // End syncing (to enable write). 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sync_status()->EndSyncing(URL(kFile)); 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(sync_status()->IsWritable(URL(kFile))); 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResetCallbackStatus(); 380b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(1, callback_count_); 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Now the file must have been created and have the same content as temp_path. 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ResetCallbackStatus(); 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_system_.DoVerifyFile( 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) URL(kFile), kTestData, 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 388b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(1, callback_count_); 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(SyncableFileOperationRunnerTest, Cancel) { 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Prepare a file. 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->CreateFile( 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) URL(kFile), false /* exclusive */, 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExpectStatus(FROM_HERE, File::FILE_OK)); 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(1, callback_count_); 399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Run Truncate and immediately cancel. This shouldn't crash. 401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ResetCallbackStatus(); 40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemOperationRunner::OperationID id = 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Truncate( 40403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) URL(kFile), 10, ExpectStatus(FROM_HERE, File::FILE_OK)); 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_.operation_runner()->Cancel( 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) id, ExpectStatus(FROM_HERE, File::FILE_ERROR_INVALID_OPERATION)); 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(2, callback_count_); 409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace sync_file_system 412