This source file includes following definitions.
- has_inflight_prepare_for_sync_
- SetUp
- TearDown
- StartPrepareForSync
- PrepareForSync
- GetPrepareForSyncClosure
- DidPrepareForSync
- ApplyRemoteChange
- DidApplyRemoteChange
- StartModifyFileOnIOThread
- WaitUntilModifyFileIsDone
- DidModifyFile
- SimulateFinishSync
- PrepareForSync_Basic
- PrepareForSync_WriteDuringSync
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "chrome/browser/sync_file_system/local/local_file_sync_context.h"
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/message_loop/message_loop.h"
#include "base/platform_file.h"
#include "base/stl_util.h"
#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
#include "chrome/browser/sync_file_system/sync_file_metadata.h"
#include "chrome/browser/sync_file_system/sync_status_code.h"
#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/mock_blob_url_request_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
#include "third_party/leveldatabase/src/include/leveldb/env.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_operation_runner.h"
#include "webkit/browser/fileapi/isolated_context.h"
#include "webkit/common/blob/scoped_file.h"
#define FPL FILE_PATH_LITERAL
using content::BrowserThread;
using fileapi::FileSystemContext;
using fileapi::FileSystemURL;
using fileapi::FileSystemURLSet;
namespace sync_file_system {
namespace {
const char kOrigin1[] = "http://example.com";
const char kOrigin2[] = "http://chromium.org";
}
class LocalFileSyncContextTest : public testing::Test {
protected:
LocalFileSyncContextTest()
: thread_bundle_(
content::TestBrowserThreadBundle::REAL_FILE_THREAD |
content::TestBrowserThreadBundle::REAL_IO_THREAD),
status_(SYNC_FILE_ERROR_FAILED),
file_error_(base::File::FILE_ERROR_FAILED),
async_modify_finished_(false),
has_inflight_prepare_for_sync_(false) {}
virtual void SetUp() OVERRIDE {
RegisterSyncableFileSystem();
ASSERT_TRUE(dir_.CreateUniqueTempDir());
in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
ui_task_runner_ = base::MessageLoop::current()->message_loop_proxy();
io_task_runner_ = BrowserThread::GetMessageLoopProxyForThread(
BrowserThread::IO);
file_task_runner_ = BrowserThread::GetMessageLoopProxyForThread(
BrowserThread::IO);
}
virtual void TearDown() OVERRIDE {
RevokeSyncableFileSystem();
}
void StartPrepareForSync(FileSystemContext* file_system_context,
const FileSystemURL& url,
LocalFileSyncContext::SyncMode sync_mode,
SyncFileMetadata* metadata,
FileChangeList* changes,
webkit_blob::ScopedFile* snapshot) {
ASSERT_TRUE(changes != NULL);
ASSERT_FALSE(has_inflight_prepare_for_sync_);
status_ = SYNC_STATUS_UNKNOWN;
has_inflight_prepare_for_sync_ = true;
sync_context_->PrepareForSync(
file_system_context,
url,
sync_mode,
base::Bind(&LocalFileSyncContextTest::DidPrepareForSync,
base::Unretained(this), metadata, changes, snapshot));
}
SyncStatusCode PrepareForSync(FileSystemContext* file_system_context,
const FileSystemURL& url,
LocalFileSyncContext::SyncMode sync_mode,
SyncFileMetadata* metadata,
FileChangeList* changes,
webkit_blob::ScopedFile* snapshot) {
StartPrepareForSync(file_system_context, url, sync_mode,
metadata, changes, snapshot);
base::MessageLoop::current()->Run();
return status_;
}
base::Closure GetPrepareForSyncClosure(
FileSystemContext* file_system_context,
const FileSystemURL& url,
LocalFileSyncContext::SyncMode sync_mode,
SyncFileMetadata* metadata,
FileChangeList* changes,
webkit_blob::ScopedFile* snapshot) {
return base::Bind(&LocalFileSyncContextTest::StartPrepareForSync,
base::Unretained(this),
base::Unretained(file_system_context),
url, sync_mode, metadata, changes, snapshot);
}
void DidPrepareForSync(SyncFileMetadata* metadata_out,
FileChangeList* changes_out,
webkit_blob::ScopedFile* snapshot_out,
SyncStatusCode status,
const LocalFileSyncInfo& sync_file_info,
webkit_blob::ScopedFile snapshot) {
ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
has_inflight_prepare_for_sync_ = false;
status_ = status;
*metadata_out = sync_file_info.metadata;
*changes_out = sync_file_info.changes;
if (snapshot_out)
*snapshot_out = snapshot.Pass();
base::MessageLoop::current()->Quit();
}
SyncStatusCode ApplyRemoteChange(FileSystemContext* file_system_context,
const FileChange& change,
const base::FilePath& local_path,
const FileSystemURL& url,
SyncFileType expected_file_type) {
SCOPED_TRACE(testing::Message() << "ApplyChange for " <<
url.DebugString());
SyncFileMetadata metadata;
FileChangeList changes;
EXPECT_EQ(SYNC_STATUS_OK,
PrepareForSync(file_system_context, url,
LocalFileSyncContext::SYNC_EXCLUSIVE,
&metadata, &changes, NULL));
EXPECT_EQ(expected_file_type, metadata.file_type);
status_ = SYNC_STATUS_UNKNOWN;
sync_context_->ApplyRemoteChange(
file_system_context, change, local_path, url,
base::Bind(&LocalFileSyncContextTest::DidApplyRemoteChange,
base::Unretained(this),
make_scoped_refptr(file_system_context), url));
base::MessageLoop::current()->Run();
return status_;
}
void DidApplyRemoteChange(FileSystemContext* file_system_context,
const FileSystemURL& url,
SyncStatusCode status) {
status_ = status;
sync_context_->FinalizeExclusiveSync(
file_system_context, url,
status == SYNC_STATUS_OK ,
base::MessageLoop::QuitClosure());
}
void StartModifyFileOnIOThread(CannedSyncableFileSystem* file_system,
const FileSystemURL& url) {
ASSERT_TRUE(file_system != NULL);
if (!io_task_runner_->RunsTasksOnCurrentThread()) {
async_modify_finished_ = false;
ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
io_task_runner_->PostTask(
FROM_HERE,
base::Bind(&LocalFileSyncContextTest::StartModifyFileOnIOThread,
base::Unretained(this), file_system, url));
return;
}
ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
file_error_ = base::File::FILE_ERROR_FAILED;
file_system->operation_runner()->Truncate(
url, 1, base::Bind(&LocalFileSyncContextTest::DidModifyFile,
base::Unretained(this)));
}
base::File::Error WaitUntilModifyFileIsDone() {
while (!async_modify_finished_)
base::MessageLoop::current()->RunUntilIdle();
return file_error_;
}
void DidModifyFile(base::File::Error error) {
if (!ui_task_runner_->RunsTasksOnCurrentThread()) {
ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
ui_task_runner_->PostTask(
FROM_HERE,
base::Bind(&LocalFileSyncContextTest::DidModifyFile,
base::Unretained(this), error));
return;
}
ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
file_error_ = error;
async_modify_finished_ = true;
}
void SimulateFinishSync(FileSystemContext* file_system_context,
const FileSystemURL& url,
SyncStatusCode status,
LocalFileSyncContext::SyncMode sync_mode) {
if (sync_mode == LocalFileSyncContext::SYNC_SNAPSHOT) {
sync_context_->FinalizeSnapshotSync(
file_system_context, url, status,
base::Bind(&base::DoNothing));
} else {
sync_context_->FinalizeExclusiveSync(
file_system_context, url,
status == SYNC_STATUS_OK ,
base::Bind(&base::DoNothing));
}
}
void PrepareForSync_Basic(LocalFileSyncContext::SyncMode sync_mode,
SyncStatusCode simulate_sync_finish_status) {
CannedSyncableFileSystem file_system(GURL(kOrigin1),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
sync_context_ = new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
ASSERT_EQ(SYNC_STATUS_OK,
file_system.MaybeInitializeFileSystemContext(
sync_context_.get()));
ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
const FileSystemURL kFile(file_system.URL("file"));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile));
SyncFileMetadata metadata;
FileChangeList changes;
EXPECT_EQ(SYNC_STATUS_OK,
PrepareForSync(file_system.file_system_context(), kFile,
sync_mode, &metadata, &changes, NULL));
EXPECT_EQ(1U, changes.size());
EXPECT_TRUE(changes.list().back().IsFile());
EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
file_system.GetChangesForURLInTracker(kFile, &changes);
EXPECT_EQ(1U, changes.size());
EXPECT_TRUE(changes.list().back().IsFile());
EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
SimulateFinishSync(file_system.file_system_context(), kFile,
simulate_sync_finish_status, sync_mode);
file_system.GetChangesForURLInTracker(kFile, &changes);
if (simulate_sync_finish_status == SYNC_STATUS_OK) {
EXPECT_TRUE(changes.empty());
} else {
EXPECT_EQ(1U, changes.size());
EXPECT_TRUE(changes.list().back().IsFile());
EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
}
sync_context_->ShutdownOnUIThread();
sync_context_ = NULL;
file_system.TearDown();
}
void PrepareForSync_WriteDuringSync(
LocalFileSyncContext::SyncMode sync_mode) {
CannedSyncableFileSystem file_system(GURL(kOrigin1),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
sync_context_ = new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
ASSERT_EQ(SYNC_STATUS_OK,
file_system.MaybeInitializeFileSystemContext(
sync_context_.get()));
ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
const FileSystemURL kFile(file_system.URL("file"));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile));
SyncFileMetadata metadata;
FileChangeList changes;
webkit_blob::ScopedFile snapshot;
EXPECT_EQ(SYNC_STATUS_OK,
PrepareForSync(file_system.file_system_context(), kFile,
sync_mode, &metadata, &changes, &snapshot));
EXPECT_EQ(1U, changes.size());
EXPECT_TRUE(changes.list().back().IsFile());
EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
EXPECT_EQ(sync_mode == LocalFileSyncContext::SYNC_SNAPSHOT,
!snapshot.path().empty());
file_system.GetChangesForURLInTracker(kFile, &changes);
EXPECT_EQ(1U, changes.size());
EXPECT_TRUE(changes.list().back().IsFile());
EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
StartModifyFileOnIOThread(&file_system, kFile);
if (sync_mode == LocalFileSyncContext::SYNC_SNAPSHOT) {
EXPECT_EQ(base::File::FILE_OK, WaitUntilModifyFileIsDone());
} else {
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(async_modify_finished_);
}
SimulateFinishSync(file_system.file_system_context(), kFile,
SYNC_STATUS_OK, sync_mode);
EXPECT_EQ(base::File::FILE_OK, WaitUntilModifyFileIsDone());
file_system.GetChangesForURLInTracker(kFile, &changes);
EXPECT_EQ(1U, changes.size());
EXPECT_TRUE(changes.list().back().IsFile());
EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
sync_context_->ShutdownOnUIThread();
sync_context_ = NULL;
file_system.TearDown();
}
ScopedEnableSyncFSDirectoryOperation enable_directory_operation_;
base::ScopedTempDir dir_;
scoped_ptr<leveldb::Env> in_memory_env_;
content::TestBrowserThreadBundle thread_bundle_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
scoped_refptr<LocalFileSyncContext> sync_context_;
SyncStatusCode status_;
base::File::Error file_error_;
bool async_modify_finished_;
bool has_inflight_prepare_for_sync_;
};
TEST_F(LocalFileSyncContextTest, ConstructAndDestruct) {
sync_context_ =
new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
sync_context_->ShutdownOnUIThread();
}
TEST_F(LocalFileSyncContextTest, InitializeFileSystemContext) {
CannedSyncableFileSystem file_system(GURL(kOrigin1),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
sync_context_ = new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
EXPECT_EQ(SYNC_STATUS_OK,
file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
EXPECT_TRUE(file_system.backend()->sync_context() != NULL);
EXPECT_TRUE(file_system.backend()->change_tracker() != NULL);
EXPECT_EQ(sync_context_.get(), file_system.backend()->sync_context());
EXPECT_EQ(SYNC_STATUS_OK,
file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
EXPECT_EQ(sync_context_.get(), file_system.backend()->sync_context());
EXPECT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
const FileSystemURL kURL(file_system.URL("foo"));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kURL));
FileSystemURLSet urls;
file_system.GetChangedURLsInTracker(&urls);
ASSERT_EQ(1U, urls.size());
EXPECT_TRUE(ContainsKey(urls, kURL));
sync_context_->ShutdownOnUIThread();
file_system.TearDown();
}
TEST_F(LocalFileSyncContextTest, MultipleFileSystemContexts) {
CannedSyncableFileSystem file_system1(GURL(kOrigin1),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
CannedSyncableFileSystem file_system2(GURL(kOrigin2),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
file_system1.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
file_system2.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
sync_context_ = new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
EXPECT_EQ(SYNC_STATUS_OK,
file_system1.MaybeInitializeFileSystemContext(sync_context_.get()));
EXPECT_EQ(SYNC_STATUS_OK,
file_system2.MaybeInitializeFileSystemContext(sync_context_.get()));
EXPECT_EQ(base::File::FILE_OK, file_system1.OpenFileSystem());
EXPECT_EQ(base::File::FILE_OK, file_system2.OpenFileSystem());
const FileSystemURL kURL1(file_system1.URL("foo"));
const FileSystemURL kURL2(file_system2.URL("bar"));
EXPECT_EQ(base::File::FILE_OK, file_system1.CreateFile(kURL1));
FileSystemURLSet urls;
file_system1.GetChangedURLsInTracker(&urls);
ASSERT_EQ(1U, urls.size());
EXPECT_TRUE(ContainsKey(urls, kURL1));
urls.clear();
file_system2.GetChangedURLsInTracker(&urls);
ASSERT_TRUE(urls.empty());
EXPECT_EQ(base::File::FILE_OK, file_system2.CreateDirectory(kURL2));
urls.clear();
file_system1.GetChangedURLsInTracker(&urls);
ASSERT_EQ(1U, urls.size());
EXPECT_TRUE(ContainsKey(urls, kURL1));
urls.clear();
file_system2.GetChangedURLsInTracker(&urls);
ASSERT_EQ(1U, urls.size());
EXPECT_TRUE(ContainsKey(urls, kURL2));
SyncFileMetadata metadata;
FileChangeList changes;
EXPECT_EQ(SYNC_STATUS_OK,
PrepareForSync(file_system1.file_system_context(), kURL1,
LocalFileSyncContext::SYNC_EXCLUSIVE,
&metadata, &changes, NULL));
EXPECT_EQ(1U, changes.size());
EXPECT_TRUE(changes.list().back().IsFile());
EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
EXPECT_EQ(0, metadata.size);
changes.clear();
EXPECT_EQ(SYNC_STATUS_OK,
PrepareForSync(file_system2.file_system_context(), kURL2,
LocalFileSyncContext::SYNC_EXCLUSIVE,
&metadata, &changes, NULL));
EXPECT_EQ(1U, changes.size());
EXPECT_FALSE(changes.list().back().IsFile());
EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
EXPECT_EQ(SYNC_FILE_TYPE_DIRECTORY, metadata.file_type);
EXPECT_EQ(0, metadata.size);
sync_context_->ShutdownOnUIThread();
sync_context_ = NULL;
file_system1.TearDown();
file_system2.TearDown();
}
TEST_F(LocalFileSyncContextTest, PrepareSync_SyncSuccess_Exclusive) {
PrepareForSync_Basic(LocalFileSyncContext::SYNC_EXCLUSIVE,
SYNC_STATUS_OK);
}
TEST_F(LocalFileSyncContextTest, PrepareSync_SyncSuccess_Snapshot) {
PrepareForSync_Basic(LocalFileSyncContext::SYNC_SNAPSHOT,
SYNC_STATUS_OK);
}
TEST_F(LocalFileSyncContextTest, PrepareSync_SyncFailure_Exclusive) {
PrepareForSync_Basic(LocalFileSyncContext::SYNC_EXCLUSIVE,
SYNC_STATUS_FAILED);
}
TEST_F(LocalFileSyncContextTest, PrepareSync_SyncFailure_Snapshot) {
PrepareForSync_Basic(LocalFileSyncContext::SYNC_SNAPSHOT,
SYNC_STATUS_FAILED);
}
TEST_F(LocalFileSyncContextTest, PrepareSync_WriteDuringSync_Exclusive) {
PrepareForSync_WriteDuringSync(LocalFileSyncContext::SYNC_EXCLUSIVE);
}
TEST_F(LocalFileSyncContextTest, PrepareSync_WriteDuringSync_Snapshot) {
PrepareForSync_WriteDuringSync(LocalFileSyncContext::SYNC_SNAPSHOT);
}
TEST_F(LocalFileSyncContextTest, DISABLED_PrepareSyncWhileWriting) {
CannedSyncableFileSystem file_system(GURL(kOrigin1),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
sync_context_ = new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
EXPECT_EQ(SYNC_STATUS_OK,
file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
EXPECT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
const FileSystemURL kURL1(file_system.URL("foo"));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kURL1));
StartModifyFileOnIOThread(&file_system, kURL1);
SyncFileMetadata metadata;
metadata.file_type = SYNC_FILE_TYPE_UNKNOWN;
FileChangeList changes;
EXPECT_EQ(SYNC_STATUS_FILE_BUSY,
PrepareForSync(file_system.file_system_context(), kURL1,
LocalFileSyncContext::SYNC_EXCLUSIVE,
&metadata, &changes, NULL));
EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
metadata.file_type = SYNC_FILE_TYPE_UNKNOWN;
changes.clear();
sync_context_->RegisterURLForWaitingSync(
kURL1, GetPrepareForSyncClosure(file_system.file_system_context(), kURL1,
LocalFileSyncContext::SYNC_EXCLUSIVE,
&metadata, &changes, NULL));
EXPECT_EQ(base::File::FILE_OK, WaitUntilModifyFileIsDone());
base::MessageLoop::current()->Run();
ASSERT_FALSE(has_inflight_prepare_for_sync_);
EXPECT_EQ(SYNC_STATUS_OK, status_);
EXPECT_EQ(1U, changes.size());
EXPECT_TRUE(changes.list().back().IsFile());
EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
EXPECT_EQ(1, metadata.size);
sync_context_->ShutdownOnUIThread();
sync_context_ = NULL;
file_system.TearDown();
}
TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForDeletion) {
CannedSyncableFileSystem file_system(GURL(kOrigin1),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
sync_context_ = new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
ASSERT_EQ(SYNC_STATUS_OK,
file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
int64 initial_usage = -1;
int64 quota = -1;
EXPECT_EQ(quota::kQuotaStatusOk,
file_system.GetUsageAndQuota(&initial_usage, "a));
const FileSystemURL kFile(file_system.URL("file"));
const FileSystemURL kDir(file_system.URL("dir"));
const FileSystemURL kChild(file_system.URL("dir/child"));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateDirectory(kDir));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kChild));
FileSystemURLSet urls;
file_system.GetChangedURLsInTracker(&urls);
ASSERT_EQ(3U, urls.size());
ASSERT_TRUE(ContainsKey(urls, kFile));
ASSERT_TRUE(ContainsKey(urls, kDir));
ASSERT_TRUE(ContainsKey(urls, kChild));
for (FileSystemURLSet::iterator iter = urls.begin();
iter != urls.end(); ++iter) {
file_system.ClearChangeForURLInTracker(*iter);
}
int64 new_usage = -1;
EXPECT_EQ(quota::kQuotaStatusOk,
file_system.GetUsageAndQuota(&new_usage, "a));
EXPECT_GT(new_usage, initial_usage);
FileChange change(FileChange::FILE_CHANGE_DELETE,
SYNC_FILE_TYPE_FILE);
EXPECT_EQ(SYNC_STATUS_OK,
ApplyRemoteChange(file_system.file_system_context(),
change, base::FilePath(), kFile,
SYNC_FILE_TYPE_FILE));
change = FileChange(FileChange::FILE_CHANGE_DELETE,
SYNC_FILE_TYPE_UNKNOWN);
EXPECT_EQ(SYNC_STATUS_OK,
ApplyRemoteChange(file_system.file_system_context(),
change, base::FilePath(), kDir,
SYNC_FILE_TYPE_DIRECTORY));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
file_system.FileExists(kFile));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
file_system.DirectoryExists(kDir));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
file_system.FileExists(kChild));
urls.clear();
file_system.GetChangedURLsInTracker(&urls);
EXPECT_TRUE(urls.empty());
EXPECT_EQ(quota::kQuotaStatusOk,
file_system.GetUsageAndQuota(&new_usage, "a));
EXPECT_EQ(new_usage, initial_usage);
sync_context_->ShutdownOnUIThread();
sync_context_ = NULL;
file_system.TearDown();
}
TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForDeletion_ForRoot) {
CannedSyncableFileSystem file_system(GURL(kOrigin1),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
sync_context_ = new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
ASSERT_EQ(SYNC_STATUS_OK,
file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
int64 initial_usage = -1;
int64 quota = -1;
EXPECT_EQ(quota::kQuotaStatusOk,
file_system.GetUsageAndQuota(&initial_usage, "a));
const FileSystemURL kFile(file_system.URL("file"));
const FileSystemURL kDir(file_system.URL("dir"));
const FileSystemURL kChild(file_system.URL("dir/child"));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateDirectory(kDir));
EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kChild));
int64 new_usage = -1;
EXPECT_EQ(quota::kQuotaStatusOk,
file_system.GetUsageAndQuota(&new_usage, "a));
EXPECT_GT(new_usage, initial_usage);
const FileSystemURL kRoot(file_system.URL(""));
FileChange change(FileChange::FILE_CHANGE_DELETE, SYNC_FILE_TYPE_DIRECTORY);
EXPECT_EQ(SYNC_STATUS_OK,
ApplyRemoteChange(file_system.file_system_context(),
change, base::FilePath(), kRoot,
SYNC_FILE_TYPE_DIRECTORY));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
file_system.FileExists(kFile));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
file_system.DirectoryExists(kDir));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
file_system.FileExists(kChild));
FileSystemURLSet urls;
file_system.GetChangedURLsInTracker(&urls);
EXPECT_TRUE(urls.empty());
EXPECT_EQ(quota::kQuotaStatusOk,
file_system.GetUsageAndQuota(&new_usage, "a));
EXPECT_EQ(new_usage, initial_usage);
sync_context_->ShutdownOnUIThread();
sync_context_ = NULL;
file_system.TearDown();
}
TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForAddOrUpdate) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
CannedSyncableFileSystem file_system(GURL(kOrigin1),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
sync_context_ = new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
ASSERT_EQ(SYNC_STATUS_OK,
file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
const FileSystemURL kFile1(file_system.URL("file1"));
const FileSystemURL kFile2(file_system.URL("file2"));
const FileSystemURL kDir(file_system.URL("dir"));
const char kTestFileData0[] = "0123456789";
const char kTestFileData1[] = "Lorem ipsum!";
const char kTestFileData2[] = "This is sample test data.";
EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile1));
EXPECT_EQ(static_cast<int64>(arraysize(kTestFileData0) - 1),
file_system.WriteString(kFile1, kTestFileData0));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
file_system.FileExists(kFile2));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
file_system.DirectoryExists(kDir));
FileSystemURLSet urls;
file_system.GetChangedURLsInTracker(&urls);
ASSERT_EQ(1U, urls.size());
EXPECT_TRUE(ContainsKey(urls, kFile1));
file_system.ClearChangeForURLInTracker(*urls.begin());
const base::FilePath kFilePath1(temp_dir.path().Append(FPL("file1")));
const base::FilePath kFilePath2(temp_dir.path().Append(FPL("file2")));
ASSERT_EQ(static_cast<int>(arraysize(kTestFileData1) - 1),
base::WriteFile(kFilePath1, kTestFileData1,
arraysize(kTestFileData1) - 1));
ASSERT_EQ(static_cast<int>(arraysize(kTestFileData2) - 1),
base::WriteFile(kFilePath2, kTestFileData2,
arraysize(kTestFileData2) - 1));
int64 usage = -1, new_usage = -1;
int64 quota = -1;
EXPECT_EQ(quota::kQuotaStatusOk,
file_system.GetUsageAndQuota(&usage, "a));
FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
SYNC_FILE_TYPE_FILE);
EXPECT_EQ(SYNC_STATUS_OK,
ApplyRemoteChange(file_system.file_system_context(),
change, kFilePath1, kFile1,
SYNC_FILE_TYPE_FILE));
const int updated_size =
arraysize(kTestFileData1) - arraysize(kTestFileData0);
EXPECT_EQ(quota::kQuotaStatusOk,
file_system.GetUsageAndQuota(&new_usage, "a));
EXPECT_EQ(updated_size, new_usage - usage);
change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
SYNC_FILE_TYPE_FILE);
EXPECT_EQ(SYNC_STATUS_OK,
ApplyRemoteChange(file_system.file_system_context(),
change, kFilePath2, kFile2,
SYNC_FILE_TYPE_UNKNOWN));
change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
SYNC_FILE_TYPE_DIRECTORY);
EXPECT_EQ(SYNC_STATUS_OK,
ApplyRemoteChange(file_system.file_system_context(),
change, base::FilePath(), kDir,
SYNC_FILE_TYPE_UNKNOWN));
change =
FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE);
EXPECT_EQ(SYNC_STATUS_OK,
ApplyRemoteChange(file_system.file_system_context(),
change,
kFilePath1,
kDir,
SYNC_FILE_TYPE_DIRECTORY));
EXPECT_EQ(base::File::FILE_OK, file_system.FileExists(kDir));
change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
SYNC_FILE_TYPE_DIRECTORY);
EXPECT_EQ(SYNC_STATUS_OK,
ApplyRemoteChange(file_system.file_system_context(),
change,
kFilePath1,
kDir,
SYNC_FILE_TYPE_FILE));
new_usage = usage;
EXPECT_EQ(quota::kQuotaStatusOk,
file_system.GetUsageAndQuota(&new_usage, "a));
EXPECT_GT(new_usage,
static_cast<int64>(usage + arraysize(kTestFileData2) - 1));
urls.clear();
file_system.GetChangedURLsInTracker(&urls);
EXPECT_TRUE(urls.empty());
EXPECT_EQ(base::File::FILE_OK, file_system.FileExists(kFile1));
EXPECT_EQ(base::File::FILE_OK, file_system.FileExists(kFile2));
EXPECT_EQ(base::File::FILE_OK, file_system.DirectoryExists(kDir));
sync_context_->ShutdownOnUIThread();
file_system.TearDown();
}
TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForAddOrUpdate_NoParent) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
CannedSyncableFileSystem file_system(GURL(kOrigin1),
in_memory_env_.get(),
io_task_runner_.get(),
file_task_runner_.get());
file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
sync_context_ = new LocalFileSyncContext(
dir_.path(), in_memory_env_.get(),
ui_task_runner_.get(), io_task_runner_.get());
ASSERT_EQ(SYNC_STATUS_OK,
file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
const char kTestFileData[] = "Lorem ipsum!";
const FileSystemURL kDir(file_system.URL("dir"));
const FileSystemURL kFile(file_system.URL("dir/file"));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, file_system.FileExists(kDir));
EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, file_system.FileExists(kFile));
const base::FilePath kFilePath(temp_dir.path().Append(FPL("file")));
ASSERT_EQ(static_cast<int>(arraysize(kTestFileData) - 1),
base::WriteFile(kFilePath, kTestFileData,
arraysize(kTestFileData) - 1));
FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
SYNC_FILE_TYPE_FILE);
EXPECT_EQ(SYNC_STATUS_OK,
ApplyRemoteChange(file_system.file_system_context(),
change, kFilePath, kFile,
SYNC_FILE_TYPE_UNKNOWN));
FileSystemURLSet urls;
urls.clear();
file_system.GetChangedURLsInTracker(&urls);
EXPECT_TRUE(urls.empty());
EXPECT_EQ(base::File::FILE_OK, file_system.FileExists(kFile));
EXPECT_EQ(base::File::FILE_OK, file_system.DirectoryExists(kDir));
sync_context_->ShutdownOnUIThread();
file_system.TearDown();
}
}