diff options
author | maniscalco@chromium.org <maniscalco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-10 02:02:05 +0000 |
---|---|---|
committer | maniscalco@chromium.org <maniscalco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-10 02:02:05 +0000 |
commit | 62bf48aeb139e753945e55f3c15d96ee45265fa8 (patch) | |
tree | 25e8ecdd7788c3f53d8f1128cc86af25d4b3731a /sync/internal_api | |
parent | 48fed1cf88260ead7236c047a75ec84c66f79578 (diff) | |
download | chromium_src-62bf48aeb139e753945e55f3c15d96ee45265fa8.zip chromium_src-62bf48aeb139e753945e55f3c15d96ee45265fa8.tar.gz chromium_src-62bf48aeb139e753945e55f3c15d96ee45265fa8.tar.bz2 |
Move code from sync/api/attachments to sync/internal_api/attachments.
The goal is to reorganize the sync attachment code so that in the future
attachment code can include stuff it needs (like src/net/) without
loosening the DEPS rules for the rest of sync.
Replace internal_api's coarse grained dep on net/ with finer grained
deps.
sync/api/attachments - Home to attachment code that's needed by both
sync itself and users of sync.
sync/internal_api/public/attachments - Home to attachment headers needed
by sync/api/attachments.
sync/internal_api/attachments - Home to attachment code that's private
to sync.
TBR=mef,erikwright,phajdan.jr
BUG=
Review URL: https://codereview.chromium.org/270633005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269481 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync/internal_api')
-rw-r--r-- | sync/internal_api/DEPS | 6 | ||||
-rw-r--r-- | sync/internal_api/attachments/DEPS | 3 | ||||
-rw-r--r-- | sync/internal_api/attachments/fake_attachment_store.cc | 121 | ||||
-rw-r--r-- | sync/internal_api/attachments/fake_attachment_store_unittest.cc | 239 | ||||
-rw-r--r-- | sync/internal_api/attachments/fake_attachment_uploader.cc | 32 | ||||
-rw-r--r-- | sync/internal_api/attachments/fake_attachment_uploader_unittest.cc | 60 | ||||
-rw-r--r-- | sync/internal_api/http_bridge.cc | 2 | ||||
-rw-r--r-- | sync/internal_api/public/attachments/fake_attachment_store.h | 60 | ||||
-rw-r--r-- | sync/internal_api/public/attachments/fake_attachment_uploader.h | 30 |
9 files changed, 550 insertions, 3 deletions
diff --git a/sync/internal_api/DEPS b/sync/internal_api/DEPS index a6e2e4e..dec66bc 100644 --- a/sync/internal_api/DEPS +++ b/sync/internal_api/DEPS @@ -1,5 +1,9 @@ include_rules = [ - "+net", + "+net/base", + "+net/cookies", + "+net/http", + "+net/test", + "+net/url_request", "+sync/base", "+sync/engine", "+sync/js", diff --git a/sync/internal_api/attachments/DEPS b/sync/internal_api/attachments/DEPS new file mode 100644 index 0000000..50828ba --- /dev/null +++ b/sync/internal_api/attachments/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+sync/api/attachments", +] diff --git a/sync/internal_api/attachments/fake_attachment_store.cc b/sync/internal_api/attachments/fake_attachment_store.cc new file mode 100644 index 0000000..40224bd --- /dev/null +++ b/sync/internal_api/attachments/fake_attachment_store.cc @@ -0,0 +1,121 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sync/internal_api/public/attachments/fake_attachment_store.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/memory/ref_counted_memory.h" +#include "base/message_loop/message_loop_proxy.h" +#include "base/sequenced_task_runner.h" +#include "base/single_thread_task_runner.h" +#include "sync/api/attachments/attachment.h" + +namespace syncer { + +// Backend is where all the work happens. +class FakeAttachmentStore::Backend + : public base::RefCountedThreadSafe<FakeAttachmentStore::Backend> { + public: + // Construct a Backend that posts its results to |frontend_task_runner|. + Backend( + const scoped_refptr<base::SingleThreadTaskRunner>& frontend_task_runner); + + void Read(const AttachmentIdList& ids, const ReadCallback& callback); + void Write(const AttachmentList& attachments, const WriteCallback& callback); + void Drop(const AttachmentIdList& ids, const DropCallback& callback); + + private: + friend class base::RefCountedThreadSafe<Backend>; + + ~Backend(); + + scoped_refptr<base::SingleThreadTaskRunner> frontend_task_runner_; + AttachmentMap attachments_; +}; + +FakeAttachmentStore::Backend::Backend( + const scoped_refptr<base::SingleThreadTaskRunner>& frontend_task_runner) + : frontend_task_runner_(frontend_task_runner) {} + +FakeAttachmentStore::Backend::~Backend() {} + +void FakeAttachmentStore::Backend::Read(const AttachmentIdList& ids, + const ReadCallback& callback) { + Result result_code = SUCCESS; + AttachmentIdList::const_iterator id_iter = ids.begin(); + AttachmentIdList::const_iterator id_end = ids.end(); + scoped_ptr<AttachmentMap> result_map(new AttachmentMap); + for (; id_iter != id_end; ++id_iter) { + const AttachmentId& id = *id_iter; + syncer::AttachmentMap::iterator attachment_iter = + attachments_.find(*id_iter); + if (attachment_iter != attachments_.end()) { + const Attachment& attachment = attachment_iter->second; + result_map->insert(std::make_pair(id, attachment)); + } else { + result_code = UNSPECIFIED_ERROR; + break; + } + } + frontend_task_runner_->PostTask( + FROM_HERE, base::Bind(callback, result_code, base::Passed(&result_map))); +} + +void FakeAttachmentStore::Backend::Write(const AttachmentList& attachments, + const WriteCallback& callback) { + AttachmentList::const_iterator iter = attachments.begin(); + AttachmentList::const_iterator end = attachments.end(); + for (; iter != end; ++iter) { + attachments_.insert(std::make_pair(iter->GetId(), *iter)); + } + frontend_task_runner_->PostTask(FROM_HERE, base::Bind(callback, SUCCESS)); +} + +void FakeAttachmentStore::Backend::Drop(const AttachmentIdList& ids, + const DropCallback& callback) { + Result result = SUCCESS; + AttachmentIdList::const_iterator ids_iter = ids.begin(); + AttachmentIdList::const_iterator ids_end = ids.end(); + for (; ids_iter != ids_end; ++ids_iter) { + AttachmentMap::iterator attachments_iter = attachments_.find(*ids_iter); + if (attachments_iter != attachments_.end()) { + attachments_.erase(attachments_iter); + } + } + frontend_task_runner_->PostTask(FROM_HERE, base::Bind(callback, result)); +} + +FakeAttachmentStore::FakeAttachmentStore( + const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner) + : backend_(new Backend(base::MessageLoopProxy::current())), + backend_task_runner_(backend_task_runner) {} + +FakeAttachmentStore::~FakeAttachmentStore() {} + +void FakeAttachmentStore::Read(const AttachmentIdList& ids, + const ReadCallback& callback) { + backend_task_runner_->PostTask( + FROM_HERE, + base::Bind(&FakeAttachmentStore::Backend::Read, backend_, ids, callback)); +} + +void FakeAttachmentStore::Write(const AttachmentList& attachments, + const WriteCallback& callback) { + backend_task_runner_->PostTask( + FROM_HERE, + base::Bind(&FakeAttachmentStore::Backend::Write, + backend_, + attachments, + callback)); +} + +void FakeAttachmentStore::Drop(const AttachmentIdList& ids, + const DropCallback& callback) { + backend_task_runner_->PostTask( + FROM_HERE, + base::Bind(&FakeAttachmentStore::Backend::Drop, backend_, ids, callback)); +} + +} // namespace syncer diff --git a/sync/internal_api/attachments/fake_attachment_store_unittest.cc b/sync/internal_api/attachments/fake_attachment_store_unittest.cc new file mode 100644 index 0000000..dffe3cf --- /dev/null +++ b/sync/internal_api/attachments/fake_attachment_store_unittest.cc @@ -0,0 +1,239 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sync/internal_api/public/attachments/fake_attachment_store.h" + +#include "base/bind.h" +#include "base/memory/ref_counted_memory.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" +#include "sync/api/attachments/attachment.h" +#include "sync/protocol/sync.pb.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace syncer { + +const char kTestData1[] = "test data 1"; +const char kTestData2[] = "test data 2"; + +class FakeAttachmentStoreTest : public testing::Test { + protected: + base::MessageLoop message_loop; + FakeAttachmentStore store; + AttachmentStore::Result result; + scoped_ptr<AttachmentMap> attachments; + + AttachmentStore::ReadCallback read_callback; + AttachmentStore::WriteCallback write_callback; + AttachmentStore::DropCallback drop_callback; + + scoped_refptr<base::RefCountedString> some_data1; + scoped_refptr<base::RefCountedString> some_data2; + + FakeAttachmentStoreTest() : store(base::MessageLoopProxy::current()) {} + + virtual void SetUp() { + Clear(); + read_callback = base::Bind(&FakeAttachmentStoreTest::CopyResultAttachments, + base::Unretained(this), + &result, + &attachments); + write_callback = base::Bind( + &FakeAttachmentStoreTest::CopyResult, base::Unretained(this), &result); + drop_callback = write_callback; + + some_data1 = new base::RefCountedString; + some_data1->data() = kTestData1; + + some_data2 = new base::RefCountedString; + some_data2->data() = kTestData2; + } + + virtual void ClearAndPumpLoop() { + Clear(); + message_loop.RunUntilIdle(); + } + + private: + void Clear() { + result = AttachmentStore::UNSPECIFIED_ERROR; + attachments.reset(); + } + + void CopyResult(AttachmentStore::Result* destination_result, + const AttachmentStore::Result& source_result) { + *destination_result = source_result; + } + + void CopyResultAttachments(AttachmentStore::Result* destination_result, + scoped_ptr<AttachmentMap>* destination_attachments, + const AttachmentStore::Result& source_result, + scoped_ptr<AttachmentMap> source_attachments) { + CopyResult(destination_result, source_result); + *destination_attachments = source_attachments.Pass(); + } +}; + +// Verify that we do not overwrite existing attachments and that we do not treat +// it as an error. +TEST_F(FakeAttachmentStoreTest, Write_NoOverwriteNoError) { + // Create two attachments with the same id but different data. + Attachment attachment1 = Attachment::Create(some_data1); + Attachment attachment2 = + Attachment::CreateWithId(attachment1.GetId(), some_data2); + + // Write the first one. + AttachmentList some_attachments; + some_attachments.push_back(attachment1); + store.Write(some_attachments, write_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + + // Write the second one. + some_attachments.clear(); + some_attachments.push_back(attachment2); + store.Write(some_attachments, write_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + + // Read it back and see that it was not overwritten. + AttachmentIdList some_attachment_ids; + some_attachment_ids.push_back(attachment1.GetId()); + store.Read(some_attachment_ids, read_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + EXPECT_EQ(attachments->size(), 1U); + AttachmentMap::const_iterator a1 = attachments->find(attachment1.GetId()); + EXPECT_TRUE(a1 != attachments->end()); + EXPECT_TRUE(attachment1.GetData()->Equals(a1->second.GetData())); +} + +// Verify that we can write some attachments and read them back. +TEST_F(FakeAttachmentStoreTest, Write_RoundTrip) { + Attachment attachment1 = Attachment::Create(some_data1); + Attachment attachment2 = Attachment::Create(some_data2); + AttachmentList some_attachments; + some_attachments.push_back(attachment1); + some_attachments.push_back(attachment2); + + store.Write(some_attachments, write_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + + AttachmentIdList some_attachment_ids; + some_attachment_ids.push_back(attachment1.GetId()); + some_attachment_ids.push_back(attachment2.GetId()); + store.Read(some_attachment_ids, read_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + EXPECT_EQ(attachments->size(), 2U); + + AttachmentMap::const_iterator a1 = attachments->find(attachment1.GetId()); + EXPECT_TRUE(a1 != attachments->end()); + EXPECT_TRUE(attachment1.GetData()->Equals(a1->second.GetData())); + + AttachmentMap::const_iterator a2 = attachments->find(attachment2.GetId()); + EXPECT_TRUE(a2 != attachments->end()); + EXPECT_TRUE(attachment2.GetData()->Equals(a2->second.GetData())); +} + +// Try to read two attachments when only one exists. +TEST_F(FakeAttachmentStoreTest, Read_OneNotFound) { + Attachment attachment1 = Attachment::Create(some_data1); + Attachment attachment2 = Attachment::Create(some_data2); + + AttachmentList some_attachments; + // Write attachment1 only. + some_attachments.push_back(attachment1); + store.Write(some_attachments, write_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + + // Try to read both attachment1 and attachment2. + AttachmentIdList ids; + ids.push_back(attachment1.GetId()); + ids.push_back(attachment2.GetId()); + store.Read(ids, read_callback); + ClearAndPumpLoop(); + + // See that only attachment1 was read. + EXPECT_EQ(result, AttachmentStore::UNSPECIFIED_ERROR); + EXPECT_EQ(attachments->size(), 1U); +} + +// Try to drop two attachments when only one exists. Verify that no error occurs +// and that the existing attachment was dropped. +TEST_F(FakeAttachmentStoreTest, Drop_DropTwoButOnlyOneExists) { + // First, create two attachments. + Attachment attachment1 = Attachment::Create(some_data1); + Attachment attachment2 = Attachment::Create(some_data2); + AttachmentList some_attachments; + some_attachments.push_back(attachment1); + some_attachments.push_back(attachment2); + store.Write(some_attachments, write_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + + // Drop attachment1 only. + AttachmentIdList ids; + ids.push_back(attachment1.GetId()); + store.Drop(ids, drop_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + + // See that attachment1 is gone. + store.Read(ids, read_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::UNSPECIFIED_ERROR); + EXPECT_EQ(attachments->size(), 0U); + + // Drop both attachment1 and attachment2. + ids.clear(); + ids.push_back(attachment1.GetId()); + ids.push_back(attachment2.GetId()); + store.Drop(ids, drop_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + + // See that attachment2 is now gone. + ids.clear(); + ids.push_back(attachment2.GetId()); + store.Read(ids, read_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::UNSPECIFIED_ERROR); + EXPECT_EQ(attachments->size(), 0U); +} + +// Verify that attempting to drop an attachment that does not exist is not an +// error. +TEST_F(FakeAttachmentStoreTest, Drop_DoesNotExist) { + Attachment attachment1 = Attachment::Create(some_data1); + AttachmentList some_attachments; + some_attachments.push_back(attachment1); + store.Write(some_attachments, write_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + + // Drop the attachment. + AttachmentIdList ids; + ids.push_back(attachment1.GetId()); + store.Drop(ids, drop_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); + + // See that it's gone. + store.Read(ids, read_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::UNSPECIFIED_ERROR); + EXPECT_EQ(attachments->size(), 0U); + + // Drop again, see that no error occurs. + ids.clear(); + ids.push_back(attachment1.GetId()); + store.Drop(ids, drop_callback); + ClearAndPumpLoop(); + EXPECT_EQ(result, AttachmentStore::SUCCESS); +} + +} // namespace syncer diff --git a/sync/internal_api/attachments/fake_attachment_uploader.cc b/sync/internal_api/attachments/fake_attachment_uploader.cc new file mode 100644 index 0000000..e73ea6b --- /dev/null +++ b/sync/internal_api/attachments/fake_attachment_uploader.cc @@ -0,0 +1,32 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sync/internal_api/public/attachments/fake_attachment_uploader.h" + +#include "base/bind.h" +#include "base/message_loop/message_loop.h" +#include "sync/api/attachments/attachment.h" + +namespace syncer { + +FakeAttachmentUploader::FakeAttachmentUploader() { + DCHECK(CalledOnValidThread()); +} + +FakeAttachmentUploader::~FakeAttachmentUploader() { + DCHECK(CalledOnValidThread()); +} + +void FakeAttachmentUploader::UploadAttachment(const Attachment& attachment, + const UploadCallback& callback) { + DCHECK(CalledOnValidThread()); + UploadResult result = UPLOAD_SUCCESS; + AttachmentId updated_id = attachment.GetId(); + // TODO(maniscalco): Update the attachment id with server address information + // before passing it to the callback. + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(callback, result, updated_id)); +} + +} // namespace syncer diff --git a/sync/internal_api/attachments/fake_attachment_uploader_unittest.cc b/sync/internal_api/attachments/fake_attachment_uploader_unittest.cc new file mode 100644 index 0000000..2cfd75e --- /dev/null +++ b/sync/internal_api/attachments/fake_attachment_uploader_unittest.cc @@ -0,0 +1,60 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sync/internal_api/public/attachments/fake_attachment_uploader.h" + +#include "base/bind.h" +#include "base/memory/ref_counted.h" +#include "base/memory/ref_counted_memory.h" +#include "base/message_loop/message_loop.h" +#include "sync/api/attachments/attachment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace syncer { + +namespace { + +const char kAttachmentData[] = "some data"; + +} // namespace + +class FakeAttachmentUploaderTest : public testing::Test { + protected: + virtual void SetUp() { + upload_callback_count = 0; + upload_callback = base::Bind(&FakeAttachmentUploaderTest::Increment, + base::Unretained(this), + &upload_callback_count); + } + base::MessageLoop message_loop; + FakeAttachmentUploader uploader; + int upload_callback_count; + AttachmentUploader::UploadCallback upload_callback; + + private: + void Increment(int* success_count, + const AttachmentUploader::UploadResult& result, + const AttachmentId& ignored) { + if (result == AttachmentUploader::UPLOAD_SUCCESS) { + ++(*success_count); + } + } +}; + +// Call upload attachment several times, see that the supplied callback is +// invoked the same number of times with a result of SUCCESS. +TEST_F(FakeAttachmentUploaderTest, UploadAttachment) { + scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString); + some_data->data() = kAttachmentData; + Attachment attachment1 = Attachment::Create(some_data); + Attachment attachment2 = Attachment::Create(some_data); + Attachment attachment3 = Attachment::Create(some_data); + uploader.UploadAttachment(attachment1, upload_callback); + uploader.UploadAttachment(attachment2, upload_callback); + uploader.UploadAttachment(attachment3, upload_callback); + message_loop.RunUntilIdle(); + EXPECT_EQ(upload_callback_count, 3); +} + +} // namespace syncer diff --git a/sync/internal_api/http_bridge.cc b/sync/internal_api/http_bridge.cc index fe700f8..ffcaf9a 100644 --- a/sync/internal_api/http_bridge.cc +++ b/sync/internal_api/http_bridge.cc @@ -10,11 +10,9 @@ #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/cookies/cookie_monster.h" -#include "net/dns/host_resolver.h" #include "net/http/http_cache.h" #include "net/http/http_network_layer.h" #include "net/http/http_response_headers.h" -#include "net/proxy/proxy_service.h" #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context.h" diff --git a/sync/internal_api/public/attachments/fake_attachment_store.h b/sync/internal_api/public/attachments/fake_attachment_store.h new file mode 100644 index 0000000..5bd59b63 --- /dev/null +++ b/sync/internal_api/public/attachments/fake_attachment_store.h @@ -0,0 +1,60 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SYNC_INTERNAL_API_PUBLIC_ATTACHMENTS_FAKE_ATTACHMENT_STORE_H_ +#define SYNC_INTERNAL_API_PUBLIC_ATTACHMENTS_FAKE_ATTACHMENT_STORE_H_ + +#include <map> + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/stl_util.h" +#include "sync/api/attachments/attachment_store.h" +#include "sync/base/sync_export.h" + +namespace base { +class SequencedTaskRunner; +class SingleThreadTaskRunner; +} // namespace base + +namespace sync_pb { +class AttachmentId; +} // namespace sync_pb + +namespace syncer { + +class Attachment; + +// A in-memory only implementation of AttachmentStore used for testing. +// +// Requires that the current thread has a MessageLoop. +class SYNC_EXPORT FakeAttachmentStore : public AttachmentStore { + public: + // Construct a FakeAttachmentStore whose "IO" will be performed in + // |backend_task_runner|. + explicit FakeAttachmentStore( + const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner); + + virtual ~FakeAttachmentStore(); + + // AttachmentStore implementation. + virtual void Read(const AttachmentIdList& id, + const ReadCallback& callback) OVERRIDE; + virtual void Write(const AttachmentList& attachments, + const WriteCallback& callback) OVERRIDE; + virtual void Drop(const AttachmentIdList& id, + const DropCallback& callback) OVERRIDE; + + private: + class Backend; + + scoped_refptr<Backend> backend_; + scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; + + DISALLOW_COPY_AND_ASSIGN(FakeAttachmentStore); +}; + +} // namespace syncer + +#endif // SYNC_INTERNAL_API_PUBLIC_ATTACHMENTS_FAKE_ATTACHMENT_STORE_H_ diff --git a/sync/internal_api/public/attachments/fake_attachment_uploader.h b/sync/internal_api/public/attachments/fake_attachment_uploader.h new file mode 100644 index 0000000..91a35dc --- /dev/null +++ b/sync/internal_api/public/attachments/fake_attachment_uploader.h @@ -0,0 +1,30 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SYNC_INTERNAL_API_PUBLIC_ATTACHMENTS_FAKE_ATTACHMENT_UPLOADER_H_ +#define SYNC_INTERNAL_API_PUBLIC_ATTACHMENTS_FAKE_ATTACHMENT_UPLOADER_H_ + +#include "base/threading/non_thread_safe.h" +#include "sync/api/attachments/attachment_uploader.h" + +namespace syncer { + +// A fake implementation of AttachmentUploader. +class SYNC_EXPORT FakeAttachmentUploader : public AttachmentUploader, + public base::NonThreadSafe { + public: + FakeAttachmentUploader(); + virtual ~FakeAttachmentUploader(); + + // AttachmentUploader implementation. + virtual void UploadAttachment(const Attachment& attachment, + const UploadCallback& callback) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(FakeAttachmentUploader); +}; + +} // namespace syncer + +#endif // SYNC_INTERNAL_API_PUBLIC_ATTACHMENTS_FAKE_ATTACHMENT_UPLOADER_H_ |