summaryrefslogtreecommitdiffstats
path: root/sync/internal_api/attachments
diff options
context:
space:
mode:
authorpavely <pavely@chromium.org>2014-11-26 14:07:05 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-26 22:08:17 +0000
commit39dc7bac58f08244ecd344565c98f8d1b01fa3c5 (patch)
tree2d3eaf101ffeafbd6d4e19ad53f8943a9492a685 /sync/internal_api/attachments
parent0cd50ebcbdc0835c250ec44efc67891feb55c876 (diff)
downloadchromium_src-39dc7bac58f08244ecd344565c98f8d1b01fa3c5.zip
chromium_src-39dc7bac58f08244ecd344565c98f8d1b01fa3c5.tar.gz
chromium_src-39dc7bac58f08244ecd344565c98f8d1b01fa3c5.tar.bz2
Synchronous creation of OnDiskAttachmentStore
AttachmentStore::CreateOnDiskStore synchronously returns reference to attachment store. Internally it triggers asynchronous initialization on background thread. If initialization fails then consecutive operations with AttachmentStore fail with STORE_NOT_INITIALIZED. BUG=436285 R=maniscalco@chromium.org Review URL: https://codereview.chromium.org/757703004 Cr-Commit-Position: refs/heads/master@{#305891}
Diffstat (limited to 'sync/internal_api/attachments')
-rw-r--r--sync/internal_api/attachments/attachment_service_impl.cc4
-rw-r--r--sync/internal_api/attachments/attachment_service_impl_unittest.cc3
-rw-r--r--sync/internal_api/attachments/attachment_store_handle.cc7
-rw-r--r--sync/internal_api/attachments/attachment_store_handle_unittest.cc25
-rw-r--r--sync/internal_api/attachments/in_memory_attachment_store.cc5
-rw-r--r--sync/internal_api/attachments/on_disk_attachment_store.cc93
-rw-r--r--sync/internal_api/attachments/on_disk_attachment_store_unittest.cc193
7 files changed, 214 insertions, 116 deletions
diff --git a/sync/internal_api/attachments/attachment_service_impl.cc b/sync/internal_api/attachments/attachment_service_impl.cc
index 10f4790..dab7aa7 100644
--- a/sync/internal_api/attachments/attachment_service_impl.cc
+++ b/sync/internal_api/attachments/attachment_service_impl.cc
@@ -200,7 +200,8 @@ void AttachmentServiceImpl::ReadDone(
AttachmentIdList::const_iterator iter = unavailable_attachment_ids->begin();
AttachmentIdList::const_iterator end = unavailable_attachment_ids->end();
- if (attachment_downloader_.get()) {
+ if (result != AttachmentStore::STORE_INITIALIZATION_FAILED &&
+ attachment_downloader_.get()) {
// Try to download locally unavailable attachments.
for (; iter != end; ++iter) {
attachment_downloader_->DownloadAttachment(
@@ -227,6 +228,7 @@ void AttachmentServiceImpl::WriteDone(
state->AddAttachment(attachment);
break;
case AttachmentStore::UNSPECIFIED_ERROR:
+ case AttachmentStore::STORE_INITIALIZATION_FAILED:
state->AddUnavailableAttachmentId(attachment.GetId());
break;
}
diff --git a/sync/internal_api/attachments/attachment_service_impl_unittest.cc b/sync/internal_api/attachments/attachment_service_impl_unittest.cc
index b83af16..713d155 100644
--- a/sync/internal_api/attachments/attachment_service_impl_unittest.cc
+++ b/sync/internal_api/attachments/attachment_service_impl_unittest.cc
@@ -24,6 +24,9 @@ class MockAttachmentStore : public AttachmentStore,
public:
MockAttachmentStore() {}
+ void Init(const InitCallback& callback) override {
+ }
+
void Read(const AttachmentIdList& ids,
const ReadCallback& callback) override {
read_ids.push_back(ids);
diff --git a/sync/internal_api/attachments/attachment_store_handle.cc b/sync/internal_api/attachments/attachment_store_handle.cc
index d770b6a..2807350 100644
--- a/sync/internal_api/attachments/attachment_store_handle.cc
+++ b/sync/internal_api/attachments/attachment_store_handle.cc
@@ -37,6 +37,13 @@ AttachmentStoreHandle::~AttachmentStoreHandle() {
FROM_HERE, base::Bind(&NoOp, base::Passed(&backend_)));
}
+void AttachmentStoreHandle::Init(const InitCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ backend_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&AttachmentStoreBase::Init,
+ base::Unretained(backend_.get()), callback));
+}
+
void AttachmentStoreHandle::Read(const AttachmentIdList& ids,
const ReadCallback& callback) {
DCHECK(CalledOnValidThread());
diff --git a/sync/internal_api/attachments/attachment_store_handle_unittest.cc b/sync/internal_api/attachments/attachment_store_handle_unittest.cc
index 0764ee0..9f82a78 100644
--- a/sync/internal_api/attachments/attachment_store_handle_unittest.cc
+++ b/sync/internal_api/attachments/attachment_store_handle_unittest.cc
@@ -21,13 +21,15 @@ namespace {
class MockAttachmentStore : public AttachmentStoreBase {
public:
- MockAttachmentStore(const base::Closure& read_called,
+ MockAttachmentStore(const base::Closure& init_called,
+ const base::Closure& read_called,
const base::Closure& write_called,
const base::Closure& drop_called,
const base::Closure& read_metadata_called,
const base::Closure& read_all_metadata_called,
const base::Closure& dtor_called)
- : read_called_(read_called),
+ : init_called_(init_called),
+ read_called_(read_called),
write_called_(write_called),
drop_called_(drop_called),
read_metadata_called_(read_metadata_called),
@@ -36,6 +38,10 @@ class MockAttachmentStore : public AttachmentStoreBase {
~MockAttachmentStore() override { dtor_called_.Run(); }
+ void Init(const InitCallback& callback) override {
+ init_called_.Run();
+ }
+
void Read(const AttachmentIdList& ids,
const ReadCallback& callback) override {
read_called_.Run();
@@ -60,6 +66,7 @@ class MockAttachmentStore : public AttachmentStoreBase {
read_all_metadata_called_.Run();
}
+ base::Closure init_called_;
base::Closure read_called_;
base::Closure write_called_;
base::Closure drop_called_;
@@ -73,7 +80,8 @@ class MockAttachmentStore : public AttachmentStoreBase {
class AttachmentStoreHandleTest : public testing::Test {
protected:
AttachmentStoreHandleTest()
- : read_call_count_(0),
+ : init_call_count_(0),
+ read_call_count_(0),
write_call_count_(0),
drop_call_count_(0),
read_metadata_call_count_(0),
@@ -82,6 +90,8 @@ class AttachmentStoreHandleTest : public testing::Test {
virtual void SetUp() {
scoped_ptr<AttachmentStoreBase> backend(new MockAttachmentStore(
+ base::Bind(&AttachmentStoreHandleTest::InitCalled,
+ base::Unretained(this)),
base::Bind(&AttachmentStoreHandleTest::ReadCalled,
base::Unretained(this)),
base::Bind(&AttachmentStoreHandleTest::WriteCalled,
@@ -113,6 +123,8 @@ class AttachmentStoreHandleTest : public testing::Test {
NOTREACHED();
}
+ void InitCalled() { ++init_call_count_; }
+
void ReadCalled() { ++read_call_count_; }
void WriteCalled() { ++write_call_count_; }
@@ -132,6 +144,7 @@ class AttachmentStoreHandleTest : public testing::Test {
base::MessageLoop message_loop_;
scoped_refptr<AttachmentStoreHandle> attachment_store_handle_;
+ int init_call_count_;
int read_call_count_;
int write_call_count_;
int drop_call_count_;
@@ -145,6 +158,12 @@ TEST_F(AttachmentStoreHandleTest, MethodsCalled) {
AttachmentIdList ids;
AttachmentList attachments;
+ attachment_store_handle_->Init(
+ base::Bind(&AttachmentStoreHandleTest::DoneWithResult));
+ EXPECT_EQ(init_call_count_, 0);
+ RunMessageLoop();
+ EXPECT_EQ(init_call_count_, 1);
+
attachment_store_handle_->Read(
ids, base::Bind(&AttachmentStoreHandleTest::ReadDone));
EXPECT_EQ(read_call_count_, 0);
diff --git a/sync/internal_api/attachments/in_memory_attachment_store.cc b/sync/internal_api/attachments/in_memory_attachment_store.cc
index 6dbc4fa..f5000c7 100644
--- a/sync/internal_api/attachments/in_memory_attachment_store.cc
+++ b/sync/internal_api/attachments/in_memory_attachment_store.cc
@@ -21,6 +21,11 @@ InMemoryAttachmentStore::InMemoryAttachmentStore(
InMemoryAttachmentStore::~InMemoryAttachmentStore() {
}
+void InMemoryAttachmentStore::Init(const InitCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ callback_task_runner_->PostTask(FROM_HERE, base::Bind(callback, SUCCESS));
+}
+
void InMemoryAttachmentStore::Read(const AttachmentIdList& ids,
const ReadCallback& callback) {
DCHECK(CalledOnValidThread());
diff --git a/sync/internal_api/attachments/on_disk_attachment_store.cc b/sync/internal_api/attachments/on_disk_attachment_store.cc
index 76f96bc..16fa0c0 100644
--- a/sync/internal_api/attachments/on_disk_attachment_store.cc
+++ b/sync/internal_api/attachments/on_disk_attachment_store.cc
@@ -83,33 +83,47 @@ leveldb::Status WriteStoreMetadata(
} // namespace
OnDiskAttachmentStore::OnDiskAttachmentStore(
- const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner)
- : callback_task_runner_(callback_task_runner) {
+ const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner,
+ const base::FilePath& path)
+ : callback_task_runner_(callback_task_runner), path_(path) {
}
OnDiskAttachmentStore::~OnDiskAttachmentStore() {
}
+void OnDiskAttachmentStore::Init(const InitCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ Result result_code = OpenOrCreate(path_);
+ callback_task_runner_->PostTask(FROM_HERE, base::Bind(callback, result_code));
+}
+
void OnDiskAttachmentStore::Read(const AttachmentIdList& ids,
const ReadCallback& callback) {
DCHECK(CalledOnValidThread());
- DCHECK(db_);
scoped_ptr<AttachmentMap> result_map(new AttachmentMap());
scoped_ptr<AttachmentIdList> unavailable_attachments(new AttachmentIdList());
- AttachmentIdList::const_iterator iter = ids.begin();
- const AttachmentIdList::const_iterator end = ids.end();
- for (; iter != end; ++iter) {
- scoped_ptr<Attachment> attachment = ReadSingleAttachment(*iter);
- if (attachment) {
- result_map->insert(std::make_pair(*iter, *attachment));
- } else {
- unavailable_attachments->push_back(*iter);
+ Result result_code = STORE_INITIALIZATION_FAILED;
+
+ if (db_) {
+ result_code = SUCCESS;
+ AttachmentIdList::const_iterator iter = ids.begin();
+ const AttachmentIdList::const_iterator end = ids.end();
+ for (; iter != end; ++iter) {
+ scoped_ptr<Attachment> attachment;
+ attachment = ReadSingleAttachment(*iter);
+ if (attachment) {
+ result_map->insert(std::make_pair(*iter, *attachment));
+ } else {
+ unavailable_attachments->push_back(*iter);
+ }
}
+ result_code =
+ unavailable_attachments->empty() ? SUCCESS : UNSPECIFIED_ERROR;
+ } else {
+ *unavailable_attachments = ids;
}
- Result result_code =
- unavailable_attachments->empty() ? SUCCESS : UNSPECIFIED_ERROR;
callback_task_runner_->PostTask(
FROM_HERE,
base::Bind(callback,
@@ -121,14 +135,16 @@ void OnDiskAttachmentStore::Read(const AttachmentIdList& ids,
void OnDiskAttachmentStore::Write(const AttachmentList& attachments,
const WriteCallback& callback) {
DCHECK(CalledOnValidThread());
- DCHECK(db_);
- Result result_code = SUCCESS;
-
- AttachmentList::const_iterator iter = attachments.begin();
- const AttachmentList::const_iterator end = attachments.end();
- for (; iter != end; ++iter) {
- if (!WriteSingleAttachment(*iter))
- result_code = UNSPECIFIED_ERROR;
+ Result result_code = STORE_INITIALIZATION_FAILED;
+
+ if (db_) {
+ result_code = SUCCESS;
+ AttachmentList::const_iterator iter = attachments.begin();
+ const AttachmentList::const_iterator end = attachments.end();
+ for (; iter != end; ++iter) {
+ if (!WriteSingleAttachment(*iter))
+ result_code = UNSPECIFIED_ERROR;
+ }
}
callback_task_runner_->PostTask(FROM_HERE, base::Bind(callback, result_code));
}
@@ -136,22 +152,24 @@ void OnDiskAttachmentStore::Write(const AttachmentList& attachments,
void OnDiskAttachmentStore::Drop(const AttachmentIdList& ids,
const DropCallback& callback) {
DCHECK(CalledOnValidThread());
- DCHECK(db_);
- Result result_code = SUCCESS;
- leveldb::WriteOptions write_options = MakeWriteOptions();
- AttachmentIdList::const_iterator iter = ids.begin();
- const AttachmentIdList::const_iterator end = ids.end();
- for (; iter != end; ++iter) {
- leveldb::WriteBatch write_batch;
- write_batch.Delete(MakeDataKeyFromAttachmentId(*iter));
- write_batch.Delete(MakeMetadataKeyFromAttachmentId(*iter));
-
- leveldb::Status status = db_->Write(write_options, &write_batch);
- if (!status.ok()) {
- // DB::Delete doesn't check if record exists, it returns ok just like
- // AttachmentStore::Drop should.
- DVLOG(1) << "DB::Write failed: status=" << status.ToString();
- result_code = UNSPECIFIED_ERROR;
+ Result result_code = STORE_INITIALIZATION_FAILED;
+ if (db_) {
+ result_code = SUCCESS;
+ leveldb::WriteOptions write_options = MakeWriteOptions();
+ AttachmentIdList::const_iterator iter = ids.begin();
+ const AttachmentIdList::const_iterator end = ids.end();
+ for (; iter != end; ++iter) {
+ leveldb::WriteBatch write_batch;
+ write_batch.Delete(MakeDataKeyFromAttachmentId(*iter));
+ write_batch.Delete(MakeMetadataKeyFromAttachmentId(*iter));
+
+ leveldb::Status status = db_->Write(write_options, &write_batch);
+ if (!status.ok()) {
+ // DB::Delete doesn't check if record exists, it returns ok just like
+ // AttachmentStore::Drop should.
+ DVLOG(1) << "DB::Write failed: status=" << status.ToString();
+ result_code = UNSPECIFIED_ERROR;
+ }
}
}
callback_task_runner_->PostTask(FROM_HERE, base::Bind(callback, result_code));
@@ -171,7 +189,6 @@ void OnDiskAttachmentStore::ReadAllMetadata(
AttachmentStore::Result OnDiskAttachmentStore::OpenOrCreate(
const base::FilePath& path) {
- DCHECK(CalledOnValidThread());
DCHECK(!db_);
base::FilePath leveldb_path = path.Append(kLeveldbDirectory);
diff --git a/sync/internal_api/attachments/on_disk_attachment_store_unittest.cc b/sync/internal_api/attachments/on_disk_attachment_store_unittest.cc
index b33a983..620ff74 100644
--- a/sync/internal_api/attachments/on_disk_attachment_store_unittest.cc
+++ b/sync/internal_api/attachments/on_disk_attachment_store_unittest.cc
@@ -13,6 +13,7 @@
#include "base/time/time.h"
#include "sync/internal_api/attachments/attachment_store_test_template.h"
#include "sync/internal_api/attachments/proto/attachment_store.pb.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/options.h"
@@ -23,12 +24,9 @@ namespace syncer {
namespace {
-void AttachmentStoreCreated(scoped_refptr<AttachmentStore>* store_dest,
- AttachmentStore::Result* result_dest,
- const AttachmentStore::Result& result,
- const scoped_refptr<AttachmentStore>& store) {
+void AttachmentStoreCreated(AttachmentStore::Result* result_dest,
+ const AttachmentStore::Result& result) {
*result_dest = result;
- *store_dest = store;
}
} // namespace
@@ -43,13 +41,12 @@ class OnDiskAttachmentStoreFactory {
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
scoped_refptr<AttachmentStore> store;
AttachmentStore::Result result = AttachmentStore::UNSPECIFIED_ERROR;
- AttachmentStore::CreateOnDiskStore(
- temp_dir_.path(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&AttachmentStoreCreated, &store, &result));
+ store = AttachmentStore::CreateOnDiskStore(
+ temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AttachmentStoreCreated, &result));
base::RunLoop run_loop;
run_loop.RunUntilIdle();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ EXPECT_EQ(AttachmentStore::SUCCESS, result);
return store;
}
@@ -77,10 +74,12 @@ class OnDiskAttachmentStoreSpecificTest : public testing::Test {
void CopyResultAttachments(
AttachmentStore::Result* destination_result,
+ AttachmentIdList* destination_failed_attachment_ids,
const AttachmentStore::Result& source_result,
scoped_ptr<AttachmentMap> source_attachments,
scoped_ptr<AttachmentIdList> source_failed_attachment_ids) {
CopyResult(destination_result, source_result);
+ *destination_failed_attachment_ids = *source_failed_attachment_ids;
}
scoped_ptr<leveldb::DB> OpenLevelDB(const base::FilePath& path) {
@@ -144,12 +143,11 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, CloseAndReopen) {
AttachmentStore::Result result;
result = AttachmentStore::UNSPECIFIED_ERROR;
- AttachmentStore::CreateOnDiskStore(
- temp_dir_.path(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&AttachmentStoreCreated, &store_, &result));
+ store_ = AttachmentStore::CreateOnDiskStore(
+ temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AttachmentStoreCreated, &result));
RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ EXPECT_EQ(AttachmentStore::SUCCESS, result);
result = AttachmentStore::UNSPECIFIED_ERROR;
std::string some_data = "data";
@@ -162,28 +160,28 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, CloseAndReopen) {
base::Unretained(this),
&result));
RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ EXPECT_EQ(AttachmentStore::SUCCESS, result);
- // Close attachment store.
+ // Close and reopen attachment store.
store_ = nullptr;
result = AttachmentStore::UNSPECIFIED_ERROR;
- AttachmentStore::CreateOnDiskStore(
- temp_dir_.path(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&AttachmentStoreCreated, &store_, &result));
+ store_ = AttachmentStore::CreateOnDiskStore(
+ temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AttachmentStoreCreated, &result));
RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ EXPECT_EQ(AttachmentStore::SUCCESS, result);
result = AttachmentStore::UNSPECIFIED_ERROR;
AttachmentIdList attachment_ids;
attachment_ids.push_back(attachment.GetId());
+ AttachmentIdList failed_attachment_ids;
store_->Read(
attachment_ids,
base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultAttachments,
- base::Unretained(this),
- &result));
+ base::Unretained(this), &result, &failed_attachment_ids));
RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ EXPECT_EQ(AttachmentStore::SUCCESS, result);
+ EXPECT_TRUE(failed_attachment_ids.empty());
}
// Ensure loading corrupt attachment store fails.
@@ -200,13 +198,11 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, FailToOpen) {
current_file_content.size());
AttachmentStore::Result result = AttachmentStore::SUCCESS;
- AttachmentStore::CreateOnDiskStore(
- temp_dir_.path(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&AttachmentStoreCreated, &store_, &result));
+ store_ = AttachmentStore::CreateOnDiskStore(
+ temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AttachmentStoreCreated, &result));
RunLoop();
- EXPECT_EQ(result, AttachmentStore::UNSPECIFIED_ERROR);
- EXPECT_EQ(store_.get(), nullptr);
+ EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, result);
}
// Ensure that attachment store works correctly when store metadata is missing,
@@ -221,12 +217,11 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, StoreMetadata) {
OpenLevelDB(db_path);
// Open database with AttachmentStore.
AttachmentStore::Result result = AttachmentStore::UNSPECIFIED_ERROR;
- AttachmentStore::CreateOnDiskStore(
- temp_dir_.path(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&AttachmentStoreCreated, &store_, &result));
+ store_ = AttachmentStore::CreateOnDiskStore(
+ temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AttachmentStoreCreated, &result));
RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ EXPECT_EQ(AttachmentStore::SUCCESS, result);
// Close AttachmentStore so that test can check content.
store_ = nullptr;
RunLoop();
@@ -235,7 +230,7 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, StoreMetadata) {
std::string data = ReadStoreMetadataRecord(db_path);
attachment_store_pb::StoreMetadata metadata;
EXPECT_TRUE(metadata.ParseFromString(data));
- EXPECT_EQ(metadata.schema_version(), 1);
+ EXPECT_EQ(1, metadata.schema_version());
// Set unknown future schema version.
metadata.set_schema_version(2);
@@ -244,26 +239,22 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, StoreMetadata) {
// AttachmentStore should fail to load.
result = AttachmentStore::SUCCESS;
- AttachmentStore::CreateOnDiskStore(
- temp_dir_.path(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&AttachmentStoreCreated, &store_, &result));
+ store_ = AttachmentStore::CreateOnDiskStore(
+ temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AttachmentStoreCreated, &result));
RunLoop();
- EXPECT_EQ(result, AttachmentStore::UNSPECIFIED_ERROR);
- EXPECT_EQ(store_.get(), nullptr);
+ EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, result);
// Write garbage into metadata record.
UpdateStoreMetadataRecord(db_path, "abra.cadabra");
// AttachmentStore should fail to load.
result = AttachmentStore::SUCCESS;
- AttachmentStore::CreateOnDiskStore(
- temp_dir_.path(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&AttachmentStoreCreated, &store_, &result));
+ store_ = AttachmentStore::CreateOnDiskStore(
+ temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AttachmentStoreCreated, &result));
RunLoop();
- EXPECT_EQ(result, AttachmentStore::UNSPECIFIED_ERROR);
- EXPECT_EQ(store_.get(), nullptr);
+ EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, result);
}
// Ensure that attachment store correctly maintains metadata records for
@@ -274,15 +265,13 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, RecordMetadata) {
temp_dir_.path().Append(FILE_PATH_LITERAL("leveldb"));
// Create attachment store.
- AttachmentStore::Result result = AttachmentStore::UNSPECIFIED_ERROR;
- AttachmentStore::CreateOnDiskStore(
- temp_dir_.path(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&AttachmentStoreCreated, &store_, &result));
- RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ AttachmentStore::Result create_result = AttachmentStore::UNSPECIFIED_ERROR;
+ store_ = AttachmentStore::CreateOnDiskStore(
+ temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AttachmentStoreCreated, &create_result));
// Write two attachments.
+ AttachmentStore::Result write_result = AttachmentStore::UNSPECIFIED_ERROR;
std::string some_data;
AttachmentList attachments;
some_data = "data1";
@@ -293,22 +282,20 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, RecordMetadata) {
Attachment::Create(base::RefCountedString::TakeString(&some_data)));
store_->Write(attachments,
base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
- base::Unretained(this),
- &result));
- RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ base::Unretained(this), &write_result));
// Delete one of written attachments.
+ AttachmentStore::Result drop_result = AttachmentStore::UNSPECIFIED_ERROR;
AttachmentIdList attachment_ids;
attachment_ids.push_back(attachments[0].GetId());
store_->Drop(attachment_ids,
base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
- base::Unretained(this),
- &result));
- RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ base::Unretained(this), &drop_result));
store_ = nullptr;
RunLoop();
+ EXPECT_EQ(AttachmentStore::SUCCESS, create_result);
+ EXPECT_EQ(AttachmentStore::SUCCESS, write_result);
+ EXPECT_EQ(AttachmentStore::SUCCESS, drop_result);
// Verify that attachment store contains only records for second attachment.
VerifyAttachmentRecordsPresent(db_path, attachments[0].GetId(), false);
@@ -320,14 +307,13 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, MismatchedCrc) {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
// Create attachment store.
- AttachmentStore::Result result = AttachmentStore::UNSPECIFIED_ERROR;
- AttachmentStore::CreateOnDiskStore(
+ AttachmentStore::Result create_result = AttachmentStore::UNSPECIFIED_ERROR;
+ store_ = AttachmentStore::CreateOnDiskStore(
temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
- base::Bind(&AttachmentStoreCreated, &store_, &result));
- RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ base::Bind(&AttachmentStoreCreated, &create_result));
// Write attachment with incorrect crc32c.
+ AttachmentStore::Result write_result = AttachmentStore::UNSPECIFIED_ERROR;
const uint32_t intentionally_wrong_crc32c = 0;
std::string some_data("data1");
Attachment attachment = Attachment::CreateFromParts(
@@ -337,19 +323,78 @@ TEST_F(OnDiskAttachmentStoreSpecificTest, MismatchedCrc) {
attachments.push_back(attachment);
store_->Write(attachments,
base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
- base::Unretained(this), &result));
- RunLoop();
- EXPECT_EQ(result, AttachmentStore::SUCCESS);
+ base::Unretained(this), &write_result));
// Read attachment.
+ AttachmentStore::Result read_result = AttachmentStore::UNSPECIFIED_ERROR;
AttachmentIdList attachment_ids;
attachment_ids.push_back(attachment.GetId());
+ AttachmentIdList failed_attachment_ids;
+ store_->Read(
+ attachment_ids,
+ base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultAttachments,
+ base::Unretained(this), &read_result, &failed_attachment_ids));
+ RunLoop();
+ EXPECT_EQ(AttachmentStore::SUCCESS, create_result);
+ EXPECT_EQ(AttachmentStore::SUCCESS, write_result);
+ EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, read_result);
+ EXPECT_THAT(failed_attachment_ids, testing::ElementsAre(attachment.GetId()));
+}
+
+// Ensure that after store initialization failure ReadWrite/Drop operations fail
+// with correct error.
+TEST_F(OnDiskAttachmentStoreSpecificTest, OpsAfterInitializationFailed) {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ base::FilePath db_path =
+ temp_dir_.path().Append(FILE_PATH_LITERAL("leveldb"));
+ base::CreateDirectory(db_path);
+
+ // To simulate corrupt database write empty CURRENT file.
+ std::string current_file_content = "";
+ base::WriteFile(db_path.Append(FILE_PATH_LITERAL("CURRENT")),
+ current_file_content.c_str(), current_file_content.size());
+
+ AttachmentStore::Result create_result = AttachmentStore::SUCCESS;
+ store_ = AttachmentStore::CreateOnDiskStore(
+ temp_dir_.path(), base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&AttachmentStoreCreated, &create_result));
+
+ // Reading from uninitialized store should result in
+ // STORE_INITIALIZATION_FAILED.
+ AttachmentStore::Result read_result = AttachmentStore::SUCCESS;
+ AttachmentIdList attachment_ids;
+ attachment_ids.push_back(AttachmentId::Create());
+ AttachmentIdList failed_attachment_ids;
store_->Read(
attachment_ids,
base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultAttachments,
- base::Unretained(this), &result));
+ base::Unretained(this), &read_result, &failed_attachment_ids));
+
+ // Dropping from uninitialized store should result in
+ // STORE_INITIALIZATION_FAILED.
+ AttachmentStore::Result drop_result = AttachmentStore::SUCCESS;
+ store_->Drop(attachment_ids,
+ base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
+ base::Unretained(this), &drop_result));
+
+ // Writing to uninitialized store should result in
+ // STORE_INITIALIZATION_FAILED.
+ AttachmentStore::Result write_result = AttachmentStore::SUCCESS;
+ std::string some_data;
+ AttachmentList attachments;
+ some_data = "data1";
+ attachments.push_back(
+ Attachment::Create(base::RefCountedString::TakeString(&some_data)));
+ store_->Write(attachments,
+ base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
+ base::Unretained(this), &write_result));
+
RunLoop();
- EXPECT_EQ(result, AttachmentStore::UNSPECIFIED_ERROR);
+ EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, create_result);
+ EXPECT_EQ(AttachmentStore::STORE_INITIALIZATION_FAILED, read_result);
+ EXPECT_THAT(failed_attachment_ids, testing::ElementsAre(attachment_ids[0]));
+ EXPECT_EQ(AttachmentStore::STORE_INITIALIZATION_FAILED, drop_result);
+ EXPECT_EQ(AttachmentStore::STORE_INITIALIZATION_FAILED, write_result);
}
} // namespace syncer