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 "sync/api/attachments/fake_attachment_store.h"
8 #include "base/memory/ref_counted_memory.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "sync/api/attachments/attachment.h"
13 #include "sync/protocol/sync.pb.h"
14 #include "testing/gtest/include/gtest/gtest.h"
18 const char kTestData1
[] = "test data 1";
19 const char kTestData2
[] = "test data 2";
21 class FakeAttachmentStoreTest
: public testing::Test
{
23 base::MessageLoop message_loop
;
24 FakeAttachmentStore store
;
25 AttachmentStore::Result result
;
26 scoped_ptr
<AttachmentMap
> attachments
;
27 scoped_ptr
<AttachmentIdList
> failed_attachment_ids
;
29 AttachmentStore::ReadCallback read_callback
;
30 AttachmentStore::WriteCallback write_callback
;
31 AttachmentStore::DropCallback drop_callback
;
33 scoped_refptr
<base::RefCountedString
> some_data1
;
34 scoped_refptr
<base::RefCountedString
> some_data2
;
36 FakeAttachmentStoreTest() : store(base::ThreadTaskRunnerHandle::Get()) {}
38 virtual void SetUp() {
40 read_callback
= base::Bind(&FakeAttachmentStoreTest::CopyResultAttachments
,
41 base::Unretained(this),
44 &failed_attachment_ids
);
45 write_callback
= base::Bind(
46 &FakeAttachmentStoreTest::CopyResult
, base::Unretained(this), &result
);
47 drop_callback
= write_callback
;
49 some_data1
= new base::RefCountedString
;
50 some_data1
->data() = kTestData1
;
52 some_data2
= new base::RefCountedString
;
53 some_data2
->data() = kTestData2
;
56 virtual void ClearAndPumpLoop() {
58 message_loop
.RunUntilIdle();
63 result
= AttachmentStore::UNSPECIFIED_ERROR
;
65 failed_attachment_ids
.reset();
68 void CopyResult(AttachmentStore::Result
* destination_result
,
69 const AttachmentStore::Result
& source_result
) {
70 *destination_result
= source_result
;
73 void CopyResultAttachments(
74 AttachmentStore::Result
* destination_result
,
75 scoped_ptr
<AttachmentMap
>* destination_attachments
,
76 scoped_ptr
<AttachmentIdList
>* destination_failed_attachment_ids
,
77 const AttachmentStore::Result
& source_result
,
78 scoped_ptr
<AttachmentMap
> source_attachments
,
79 scoped_ptr
<AttachmentIdList
> source_failed_attachment_ids
) {
80 CopyResult(destination_result
, source_result
);
81 *destination_attachments
= source_attachments
.Pass();
82 *destination_failed_attachment_ids
= source_failed_attachment_ids
.Pass();
86 // Verify that we do not overwrite existing attachments and that we do not treat
88 TEST_F(FakeAttachmentStoreTest
, Write_NoOverwriteNoError
) {
89 // Create two attachments with the same id but different data.
90 Attachment attachment1
= Attachment::Create(some_data1
);
91 Attachment attachment2
=
92 Attachment::CreateWithId(attachment1
.GetId(), some_data2
);
94 // Write the first one.
95 AttachmentList some_attachments
;
96 some_attachments
.push_back(attachment1
);
97 store
.Write(some_attachments
, write_callback
);
99 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
101 // Write the second one.
102 some_attachments
.clear();
103 some_attachments
.push_back(attachment2
);
104 store
.Write(some_attachments
, write_callback
);
106 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
108 // Read it back and see that it was not overwritten.
109 AttachmentIdList some_attachment_ids
;
110 some_attachment_ids
.push_back(attachment1
.GetId());
111 store
.Read(some_attachment_ids
, read_callback
);
113 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
114 EXPECT_EQ(attachments
->size(), 1U);
115 EXPECT_EQ(failed_attachment_ids
->size(), 0U);
116 AttachmentMap::const_iterator a1
= attachments
->find(attachment1
.GetId());
117 EXPECT_TRUE(a1
!= attachments
->end());
118 EXPECT_TRUE(attachment1
.GetData()->Equals(a1
->second
.GetData()));
121 // Verify that we can write some attachments and read them back.
122 TEST_F(FakeAttachmentStoreTest
, Write_RoundTrip
) {
123 Attachment attachment1
= Attachment::Create(some_data1
);
124 Attachment attachment2
= Attachment::Create(some_data2
);
125 AttachmentList some_attachments
;
126 some_attachments
.push_back(attachment1
);
127 some_attachments
.push_back(attachment2
);
129 store
.Write(some_attachments
, write_callback
);
131 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
133 AttachmentIdList some_attachment_ids
;
134 some_attachment_ids
.push_back(attachment1
.GetId());
135 some_attachment_ids
.push_back(attachment2
.GetId());
136 store
.Read(some_attachment_ids
, read_callback
);
138 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
139 EXPECT_EQ(attachments
->size(), 2U);
140 EXPECT_EQ(failed_attachment_ids
->size(), 0U);
142 AttachmentMap::const_iterator a1
= attachments
->find(attachment1
.GetId());
143 EXPECT_TRUE(a1
!= attachments
->end());
144 EXPECT_TRUE(attachment1
.GetData()->Equals(a1
->second
.GetData()));
146 AttachmentMap::const_iterator a2
= attachments
->find(attachment2
.GetId());
147 EXPECT_TRUE(a2
!= attachments
->end());
148 EXPECT_TRUE(attachment2
.GetData()->Equals(a2
->second
.GetData()));
151 // Try to read two attachments when only one exists.
152 TEST_F(FakeAttachmentStoreTest
, Read_OneNotFound
) {
153 Attachment attachment1
= Attachment::Create(some_data1
);
154 Attachment attachment2
= Attachment::Create(some_data2
);
156 AttachmentList some_attachments
;
157 // Write attachment1 only.
158 some_attachments
.push_back(attachment1
);
159 store
.Write(some_attachments
, write_callback
);
161 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
163 // Try to read both attachment1 and attachment2.
164 AttachmentIdList ids
;
165 ids
.push_back(attachment1
.GetId());
166 ids
.push_back(attachment2
.GetId());
167 store
.Read(ids
, read_callback
);
170 // See that only attachment1 was read.
171 EXPECT_EQ(result
, AttachmentStore::UNSPECIFIED_ERROR
);
172 EXPECT_EQ(attachments
->size(), 1U);
173 EXPECT_EQ(failed_attachment_ids
->size(), 1U);
176 // Try to drop two attachments when only one exists. Verify that no error occurs
177 // and that the existing attachment was dropped.
178 TEST_F(FakeAttachmentStoreTest
, Drop_DropTwoButOnlyOneExists
) {
179 // First, create two attachments.
180 Attachment attachment1
= Attachment::Create(some_data1
);
181 Attachment attachment2
= Attachment::Create(some_data2
);
182 AttachmentList some_attachments
;
183 some_attachments
.push_back(attachment1
);
184 some_attachments
.push_back(attachment2
);
185 store
.Write(some_attachments
, write_callback
);
187 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
189 // Drop attachment1 only.
190 AttachmentIdList ids
;
191 ids
.push_back(attachment1
.GetId());
192 store
.Drop(ids
, drop_callback
);
194 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
196 // See that attachment1 is gone.
197 store
.Read(ids
, read_callback
);
199 EXPECT_EQ(result
, AttachmentStore::UNSPECIFIED_ERROR
);
200 EXPECT_EQ(attachments
->size(), 0U);
201 EXPECT_EQ(failed_attachment_ids
->size(), 1U);
202 EXPECT_EQ((*failed_attachment_ids
)[0], attachment1
.GetId());
204 // Drop both attachment1 and attachment2.
206 ids
.push_back(attachment1
.GetId());
207 ids
.push_back(attachment2
.GetId());
208 store
.Drop(ids
, drop_callback
);
210 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
212 // See that attachment2 is now gone.
214 ids
.push_back(attachment2
.GetId());
215 store
.Read(ids
, read_callback
);
217 EXPECT_EQ(result
, AttachmentStore::UNSPECIFIED_ERROR
);
218 EXPECT_EQ(attachments
->size(), 0U);
219 EXPECT_EQ(failed_attachment_ids
->size(), 1U);
220 EXPECT_EQ((*failed_attachment_ids
)[0], attachment2
.GetId());
223 // Verify that attempting to drop an attachment that does not exist is not an
225 TEST_F(FakeAttachmentStoreTest
, Drop_DoesNotExist
) {
226 Attachment attachment1
= Attachment::Create(some_data1
);
227 AttachmentList some_attachments
;
228 some_attachments
.push_back(attachment1
);
229 store
.Write(some_attachments
, write_callback
);
231 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
233 // Drop the attachment.
234 AttachmentIdList ids
;
235 ids
.push_back(attachment1
.GetId());
236 store
.Drop(ids
, drop_callback
);
238 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
240 // See that it's gone.
241 store
.Read(ids
, read_callback
);
243 EXPECT_EQ(result
, AttachmentStore::UNSPECIFIED_ERROR
);
244 EXPECT_EQ(attachments
->size(), 0U);
245 EXPECT_EQ(failed_attachment_ids
->size(), 1U);
246 EXPECT_EQ((*failed_attachment_ids
)[0], attachment1
.GetId());
248 // Drop again, see that no error occurs.
250 ids
.push_back(attachment1
.GetId());
251 store
.Drop(ids
, drop_callback
);
253 EXPECT_EQ(result
, AttachmentStore::SUCCESS
);
256 } // namespace syncer