1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/sync_driver/shared_change_processor.h"
10 #include "base/bind_helpers.h"
11 #include "base/compiler_specific.h"
12 #include "base/location.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/threading/thread.h"
16 #include "components/sync_driver/data_type_error_handler_mock.h"
17 #include "components/sync_driver/generic_change_processor.h"
18 #include "components/sync_driver/generic_change_processor_factory.h"
19 #include "components/sync_driver/sync_api_component_factory.h"
20 #include "sync/api/attachments/attachment_id.h"
21 #include "sync/api/attachments/attachment_store.h"
22 #include "sync/api/fake_syncable_service.h"
23 #include "sync/internal_api/public/attachments/attachment_service_impl.h"
24 #include "sync/internal_api/public/base/model_type.h"
25 #include "sync/internal_api/public/test/test_user_share.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 namespace sync_driver
{
33 using ::testing::NiceMock
;
34 using ::testing::StrictMock
;
36 class SyncSharedChangeProcessorTest
:
38 public SyncApiComponentFactory
{
40 SyncSharedChangeProcessorTest()
41 : backend_thread_("dbthread"),
43 has_attachment_service_(false) {}
45 ~SyncSharedChangeProcessorTest() override
{
46 EXPECT_FALSE(db_syncable_service_
.get());
49 base::WeakPtr
<syncer::SyncableService
> GetSyncableServiceForType(
50 syncer::ModelType type
) override
{
51 return db_syncable_service_
->AsWeakPtr();
54 scoped_ptr
<syncer::AttachmentService
> CreateAttachmentService(
55 scoped_ptr
<syncer::AttachmentStoreForSync
> attachment_store
,
56 const syncer::UserShare
& user_share
,
57 const std::string
& store_birthday
,
58 syncer::ModelType model_type
,
59 syncer::AttachmentService::Delegate
* delegate
) override
{
60 return syncer::AttachmentServiceImpl::CreateForTest();
64 void SetUp() override
{
65 test_user_share_
.SetUp();
66 shared_change_processor_
= new SharedChangeProcessor();
67 ASSERT_TRUE(backend_thread_
.Start());
68 ASSERT_TRUE(backend_thread_
.task_runner()->PostTask(
70 base::Bind(&SyncSharedChangeProcessorTest::SetUpDBSyncableService
,
71 base::Unretained(this))));
74 void TearDown() override
{
75 EXPECT_TRUE(backend_thread_
.task_runner()->PostTask(
77 base::Bind(&SyncSharedChangeProcessorTest::TearDownDBSyncableService
,
78 base::Unretained(this))));
79 // This must happen before the DB thread is stopped since
80 // |shared_change_processor_| may post tasks to delete its members
81 // on the correct thread.
83 // TODO(akalin): Write deterministic tests for the destruction of
84 // |shared_change_processor_| on the UI and DB threads.
85 shared_change_processor_
= NULL
;
86 backend_thread_
.Stop();
88 // Note: Stop() joins the threads, and that barrier prevents this read
89 // from being moved (e.g by compiler optimization) in such a way that it
90 // would race with the write in ConnectOnDBThread (because by this time,
91 // everything that could have run on |backend_thread_| has done so).
92 ASSERT_TRUE(did_connect_
);
93 test_user_share_
.TearDown();
96 // Connect |shared_change_processor_| on the DB thread.
98 EXPECT_TRUE(backend_thread_
.task_runner()->PostTask(
100 base::Bind(&SyncSharedChangeProcessorTest::ConnectOnDBThread
,
101 base::Unretained(this), shared_change_processor_
)));
104 void SetAttachmentStore() {
105 EXPECT_TRUE(backend_thread_
.task_runner()->PostTask(
107 base::Bind(&SyncSharedChangeProcessorTest::SetAttachmentStoreOnDBThread
,
108 base::Unretained(this))));
111 bool HasAttachmentService() {
112 base::WaitableEvent
event(false, false);
113 EXPECT_TRUE(backend_thread_
.task_runner()->PostTask(
116 &SyncSharedChangeProcessorTest::CheckAttachmentServiceOnDBThread
,
117 base::Unretained(this), base::Unretained(&event
))));
119 return has_attachment_service_
;
124 void SetUpDBSyncableService() {
125 DCHECK(backend_thread_
.task_runner()->BelongsToCurrentThread());
126 DCHECK(!db_syncable_service_
.get());
127 db_syncable_service_
.reset(new syncer::FakeSyncableService());
130 // Used by TearDown().
131 void TearDownDBSyncableService() {
132 DCHECK(backend_thread_
.task_runner()->BelongsToCurrentThread());
133 DCHECK(db_syncable_service_
.get());
134 db_syncable_service_
.reset();
137 void SetAttachmentStoreOnDBThread() {
138 DCHECK(backend_thread_
.task_runner()->BelongsToCurrentThread());
139 DCHECK(db_syncable_service_
.get());
140 db_syncable_service_
->set_attachment_store(
141 syncer::AttachmentStore::CreateInMemoryStore());
144 // Used by Connect(). The SharedChangeProcessor is passed in
145 // because we modify |shared_change_processor_| on the main thread
147 void ConnectOnDBThread(
148 const scoped_refptr
<SharedChangeProcessor
>& shared_change_processor
) {
149 DCHECK(backend_thread_
.task_runner()->BelongsToCurrentThread());
150 EXPECT_TRUE(shared_change_processor
->Connect(
151 this, &processor_factory_
, test_user_share_
.user_share(),
152 &error_handler_
, syncer::AUTOFILL
,
153 base::WeakPtr
<syncer::SyncMergeResult
>()));
157 void CheckAttachmentServiceOnDBThread(base::WaitableEvent
* event
) {
158 DCHECK(backend_thread_
.task_runner()->BelongsToCurrentThread());
159 DCHECK(db_syncable_service_
.get());
160 has_attachment_service_
= !!db_syncable_service_
->attachment_service();
164 base::MessageLoop frontend_loop_
;
165 base::Thread backend_thread_
;
166 syncer::TestUserShare test_user_share_
;
168 scoped_refptr
<SharedChangeProcessor
> shared_change_processor_
;
169 StrictMock
<DataTypeErrorHandlerMock
> error_handler_
;
171 GenericChangeProcessorFactory processor_factory_
;
173 bool has_attachment_service_
;
175 // Used only on DB thread.
176 scoped_ptr
<syncer::FakeSyncableService
> db_syncable_service_
;
179 // Simply connect the shared change processor. It should succeed, and
180 // nothing further should happen.
181 TEST_F(SyncSharedChangeProcessorTest
, Basic
) {
185 // Connect the shared change processor to a syncable service with
186 // AttachmentStore. Verify that shared change processor implementation
187 // creates AttachmentService and passes it back to the syncable service.
188 TEST_F(SyncSharedChangeProcessorTest
, ConnectWithAttachmentStore
) {
189 SetAttachmentStore();
191 EXPECT_TRUE(HasAttachmentService());
196 } // namespace sync_driver