OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "sync/internal_api/public/processor_entity_tracker.h" | |
6 | |
7 #include <stdint.h> | |
8 | |
9 #include <memory> | |
10 #include <utility> | |
11 | |
12 #include "base/memory/ptr_util.h" | |
13 #include "base/time/time.h" | |
14 #include "sync/internal_api/public/base/model_type.h" | |
15 #include "sync/internal_api/public/non_blocking_sync_common.h" | |
16 #include "sync/protocol/sync.pb.h" | |
17 #include "sync/syncable/syncable_util.h" | |
18 #include "sync/util/time.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 namespace syncer_v2 { | |
22 | |
23 namespace { | |
24 | |
25 const std::string kTag = "tag"; | |
26 const std::string kId = "id"; | |
27 const std::string kValue1 = "value1"; | |
28 const std::string kValue2 = "value2"; | |
29 const std::string kValue3 = "value3"; | |
30 | |
31 std::string GenerateTagHash(const std::string& tag) { | |
32 return syncer::syncable::GenerateSyncableHash(syncer::PREFERENCES, tag); | |
33 } | |
34 | |
35 sync_pb::EntitySpecifics GenerateSpecifics(const std::string& tag, | |
36 const std::string& value) { | |
37 sync_pb::EntitySpecifics specifics; | |
38 specifics.mutable_preference()->set_name(tag); | |
39 specifics.mutable_preference()->set_value(value); | |
40 return specifics; | |
41 } | |
42 | |
43 std::unique_ptr<EntityData> GenerateEntityData(const std::string& tag, | |
44 const std::string& value) { | |
45 std::unique_ptr<EntityData> entity_data(new EntityData()); | |
46 entity_data->client_tag_hash = GenerateTagHash(tag); | |
47 entity_data->specifics = GenerateSpecifics(tag, value); | |
48 entity_data->non_unique_name = tag; | |
49 return entity_data; | |
50 } | |
51 | |
52 UpdateResponseData GenerateUpdate(const ProcessorEntityTracker& entity, | |
53 const std::string& id, | |
54 const std::string& value, | |
55 const base::Time& mtime, | |
56 int64_t version) { | |
57 std::unique_ptr<EntityData> data = | |
58 GenerateEntityData(entity.client_tag(), value); | |
59 data->id = id; | |
60 data->modification_time = mtime; | |
61 UpdateResponseData update; | |
62 update.entity = data->PassToPtr(); | |
63 update.response_version = version; | |
64 return update; | |
65 } | |
66 | |
67 UpdateResponseData GenerateTombstone(const ProcessorEntityTracker& entity, | |
68 const std::string& id, | |
69 const base::Time& mtime, | |
70 int64_t version) { | |
71 std::unique_ptr<EntityData> data = base::WrapUnique(new EntityData()); | |
72 data->client_tag_hash = GenerateTagHash(entity.client_tag()); | |
73 data->non_unique_name = entity.client_tag(); | |
74 data->id = id; | |
75 data->modification_time = mtime; | |
76 UpdateResponseData update; | |
77 update.entity = data->PassToPtr(); | |
78 update.response_version = version; | |
79 return update; | |
80 } | |
81 | |
82 CommitResponseData GenerateAckData(const CommitRequestData& request, | |
83 int64_t version) { | |
84 CommitResponseData response; | |
85 response.id = kId; | |
86 response.client_tag_hash = request.entity->client_tag_hash; | |
87 response.sequence_number = request.sequence_number; | |
88 response.response_version = version; | |
89 response.specifics_hash = request.specifics_hash; | |
90 return response; | |
91 } | |
92 | |
93 } // namespace | |
94 | |
95 // Some simple sanity tests for the ProcessorEntityTracker. | |
96 // | |
97 // A lot of the more complicated sync logic is implemented in the | |
98 // SharedModelTypeProcessor that owns the ProcessorEntityTracker. We can't unit | |
99 // test it here. | |
100 // | |
101 // Instead, we focus on simple tests to make sure that variables are getting | |
102 // properly intialized and flags properly set. Anything more complicated would | |
103 // be a redundant and incomplete version of the SharedModelTypeProcessor tests. | |
104 class ProcessorEntityTrackerTest : public ::testing::Test { | |
105 public: | |
106 ProcessorEntityTrackerTest() | |
107 : tag_hash_(GenerateTagHash(kTag)), | |
108 ctime_(base::Time::Now() - base::TimeDelta::FromSeconds(1)){}; | |
109 | |
110 std::unique_ptr<ProcessorEntityTracker> CreateNew() { | |
111 return ProcessorEntityTracker::CreateNew(kTag, tag_hash_, "", ctime_); | |
112 } | |
113 | |
114 std::unique_ptr<ProcessorEntityTracker> CreateSynced() { | |
115 std::unique_ptr<ProcessorEntityTracker> entity = CreateNew(); | |
116 entity->RecordAcceptedUpdate( | |
117 GenerateUpdate(*entity, kId, kValue1, ctime_, 1)); | |
118 DCHECK(!entity->IsUnsynced()); | |
119 return entity; | |
120 } | |
121 | |
122 const std::string tag_hash_; | |
123 const base::Time ctime_; | |
124 }; | |
125 | |
126 // Test the state of the default new tracker. | |
127 TEST_F(ProcessorEntityTrackerTest, DefaultTracker) { | |
128 std::unique_ptr<ProcessorEntityTracker> entity = CreateNew(); | |
129 | |
130 EXPECT_EQ(kTag, entity->client_tag()); | |
131 EXPECT_EQ(tag_hash_, entity->metadata().client_tag_hash()); | |
132 EXPECT_EQ("", entity->metadata().server_id()); | |
133 EXPECT_FALSE(entity->metadata().is_deleted()); | |
134 EXPECT_EQ(0, entity->metadata().sequence_number()); | |
135 EXPECT_EQ(0, entity->metadata().acked_sequence_number()); | |
136 EXPECT_EQ(kUncommittedVersion, entity->metadata().server_version()); | |
137 EXPECT_EQ(syncer::TimeToProtoTime(ctime_), | |
138 entity->metadata().creation_time()); | |
139 EXPECT_EQ(0, entity->metadata().modification_time()); | |
140 EXPECT_TRUE(entity->metadata().specifics_hash().empty()); | |
141 EXPECT_TRUE(entity->metadata().base_specifics_hash().empty()); | |
142 | |
143 EXPECT_FALSE(entity->IsUnsynced()); | |
144 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
145 EXPECT_FALSE(entity->RequiresCommitData()); | |
146 EXPECT_FALSE(entity->CanClearMetadata()); | |
147 EXPECT_FALSE(entity->UpdateIsReflection(1)); | |
148 EXPECT_FALSE(entity->HasCommitData()); | |
149 } | |
150 | |
151 // Test creating and commiting a new local item. | |
152 TEST_F(ProcessorEntityTrackerTest, NewLocalItem) { | |
153 std::unique_ptr<ProcessorEntityTracker> entity = CreateNew(); | |
154 entity->MakeLocalChange(GenerateEntityData(kTag, kValue1)); | |
155 | |
156 EXPECT_EQ("", entity->metadata().server_id()); | |
157 EXPECT_FALSE(entity->metadata().is_deleted()); | |
158 EXPECT_EQ(1, entity->metadata().sequence_number()); | |
159 EXPECT_EQ(0, entity->metadata().acked_sequence_number()); | |
160 EXPECT_EQ(kUncommittedVersion, entity->metadata().server_version()); | |
161 EXPECT_NE(0, entity->metadata().modification_time()); | |
162 EXPECT_FALSE(entity->metadata().specifics_hash().empty()); | |
163 EXPECT_TRUE(entity->metadata().base_specifics_hash().empty()); | |
164 | |
165 EXPECT_TRUE(entity->IsUnsynced()); | |
166 EXPECT_TRUE(entity->RequiresCommitRequest()); | |
167 EXPECT_FALSE(entity->RequiresCommitData()); | |
168 EXPECT_FALSE(entity->CanClearMetadata()); | |
169 EXPECT_FALSE(entity->UpdateIsReflection(1)); | |
170 EXPECT_TRUE(entity->HasCommitData()); | |
171 | |
172 EXPECT_EQ(kValue1, entity->commit_data()->specifics.preference().value()); | |
173 | |
174 // Generate a commit request. The metadata should not change. | |
175 const sync_pb::EntityMetadata metadata_v1 = entity->metadata(); | |
176 CommitRequestData request; | |
177 entity->InitializeCommitRequestData(&request); | |
178 EXPECT_EQ(metadata_v1.SerializeAsString(), | |
179 entity->metadata().SerializeAsString()); | |
180 | |
181 EXPECT_TRUE(entity->IsUnsynced()); | |
182 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
183 EXPECT_FALSE(entity->RequiresCommitData()); | |
184 EXPECT_FALSE(entity->CanClearMetadata()); | |
185 EXPECT_FALSE(entity->UpdateIsReflection(1)); | |
186 EXPECT_TRUE(entity->HasCommitData()); | |
187 | |
188 const EntityData& data = request.entity.value(); | |
189 EXPECT_EQ("", data.id); | |
190 EXPECT_EQ(tag_hash_, data.client_tag_hash); | |
191 EXPECT_EQ(kTag, data.non_unique_name); | |
192 EXPECT_EQ(kValue1, data.specifics.preference().value()); | |
193 EXPECT_EQ(syncer::TimeToProtoTime(ctime_), | |
194 syncer::TimeToProtoTime(data.creation_time)); | |
195 EXPECT_EQ(entity->metadata().modification_time(), | |
196 syncer::TimeToProtoTime(data.modification_time)); | |
197 EXPECT_FALSE(data.is_deleted()); | |
198 EXPECT_EQ(1, request.sequence_number); | |
199 EXPECT_EQ(kUncommittedVersion, request.base_version); | |
200 EXPECT_EQ(entity->metadata().specifics_hash(), request.specifics_hash); | |
201 | |
202 // Ack the commit. | |
203 entity->ReceiveCommitResponse(GenerateAckData(request, 1)); | |
204 | |
205 EXPECT_EQ(kId, entity->metadata().server_id()); | |
206 EXPECT_FALSE(entity->metadata().is_deleted()); | |
207 EXPECT_EQ(1, entity->metadata().sequence_number()); | |
208 EXPECT_EQ(1, entity->metadata().acked_sequence_number()); | |
209 EXPECT_EQ(1, entity->metadata().server_version()); | |
210 EXPECT_EQ(metadata_v1.creation_time(), entity->metadata().creation_time()); | |
211 EXPECT_EQ(metadata_v1.modification_time(), | |
212 entity->metadata().modification_time()); | |
213 EXPECT_FALSE(entity->metadata().specifics_hash().empty()); | |
214 EXPECT_TRUE(entity->metadata().base_specifics_hash().empty()); | |
215 | |
216 EXPECT_FALSE(entity->IsUnsynced()); | |
217 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
218 EXPECT_FALSE(entity->RequiresCommitData()); | |
219 EXPECT_FALSE(entity->CanClearMetadata()); | |
220 EXPECT_TRUE(entity->UpdateIsReflection(1)); | |
221 EXPECT_FALSE(entity->HasCommitData()); | |
222 } | |
223 | |
224 // Test state for a newly synced server item. | |
225 TEST_F(ProcessorEntityTrackerTest, NewServerItem) { | |
226 std::unique_ptr<ProcessorEntityTracker> entity = CreateNew(); | |
227 | |
228 const base::Time mtime = base::Time::Now(); | |
229 entity->RecordAcceptedUpdate( | |
230 GenerateUpdate(*entity, kId, kValue1, mtime, 10)); | |
231 | |
232 EXPECT_EQ(kId, entity->metadata().server_id()); | |
233 EXPECT_FALSE(entity->metadata().is_deleted()); | |
234 EXPECT_EQ(0, entity->metadata().sequence_number()); | |
235 EXPECT_EQ(0, entity->metadata().acked_sequence_number()); | |
236 EXPECT_EQ(10, entity->metadata().server_version()); | |
237 EXPECT_EQ(syncer::TimeToProtoTime(mtime), | |
238 entity->metadata().modification_time()); | |
239 EXPECT_FALSE(entity->metadata().specifics_hash().empty()); | |
240 EXPECT_TRUE(entity->metadata().base_specifics_hash().empty()); | |
241 | |
242 EXPECT_FALSE(entity->IsUnsynced()); | |
243 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
244 EXPECT_FALSE(entity->RequiresCommitData()); | |
245 EXPECT_FALSE(entity->CanClearMetadata()); | |
246 EXPECT_TRUE(entity->UpdateIsReflection(9)); | |
247 EXPECT_TRUE(entity->UpdateIsReflection(10)); | |
248 EXPECT_FALSE(entity->UpdateIsReflection(11)); | |
249 EXPECT_FALSE(entity->HasCommitData()); | |
250 } | |
251 | |
252 // Test state for a tombstone received for a previously unknown item. | |
253 TEST_F(ProcessorEntityTrackerTest, NewServerTombstone) { | |
254 std::unique_ptr<ProcessorEntityTracker> entity = CreateNew(); | |
255 | |
256 const base::Time mtime = base::Time::Now(); | |
257 entity->RecordAcceptedUpdate(GenerateTombstone(*entity, kId, mtime, 1)); | |
258 | |
259 EXPECT_EQ(kId, entity->metadata().server_id()); | |
260 EXPECT_TRUE(entity->metadata().is_deleted()); | |
261 EXPECT_EQ(0, entity->metadata().sequence_number()); | |
262 EXPECT_EQ(0, entity->metadata().acked_sequence_number()); | |
263 EXPECT_EQ(1, entity->metadata().server_version()); | |
264 EXPECT_EQ(syncer::TimeToProtoTime(mtime), | |
265 entity->metadata().modification_time()); | |
266 EXPECT_TRUE(entity->metadata().specifics_hash().empty()); | |
267 EXPECT_TRUE(entity->metadata().base_specifics_hash().empty()); | |
268 | |
269 EXPECT_FALSE(entity->IsUnsynced()); | |
270 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
271 EXPECT_FALSE(entity->RequiresCommitData()); | |
272 EXPECT_TRUE(entity->CanClearMetadata()); | |
273 EXPECT_TRUE(entity->UpdateIsReflection(1)); | |
274 EXPECT_FALSE(entity->UpdateIsReflection(2)); | |
275 EXPECT_FALSE(entity->HasCommitData()); | |
276 } | |
277 | |
278 // Apply a deletion update to a synced item. | |
279 TEST_F(ProcessorEntityTrackerTest, ServerTombstone) { | |
280 // Start with a non-deleted state with version 1. | |
281 std::unique_ptr<ProcessorEntityTracker> entity = CreateSynced(); | |
282 // A deletion update one version later. | |
283 const base::Time mtime = base::Time::Now(); | |
284 entity->RecordAcceptedUpdate(GenerateTombstone(*entity, kId, mtime, 2)); | |
285 | |
286 EXPECT_TRUE(entity->metadata().is_deleted()); | |
287 EXPECT_EQ(0, entity->metadata().sequence_number()); | |
288 EXPECT_EQ(0, entity->metadata().acked_sequence_number()); | |
289 EXPECT_EQ(2, entity->metadata().server_version()); | |
290 EXPECT_EQ(syncer::TimeToProtoTime(mtime), | |
291 entity->metadata().modification_time()); | |
292 EXPECT_TRUE(entity->metadata().specifics_hash().empty()); | |
293 EXPECT_TRUE(entity->metadata().base_specifics_hash().empty()); | |
294 | |
295 EXPECT_FALSE(entity->IsUnsynced()); | |
296 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
297 EXPECT_FALSE(entity->RequiresCommitData()); | |
298 EXPECT_TRUE(entity->CanClearMetadata()); | |
299 EXPECT_TRUE(entity->UpdateIsReflection(2)); | |
300 EXPECT_FALSE(entity->UpdateIsReflection(3)); | |
301 EXPECT_FALSE(entity->HasCommitData()); | |
302 } | |
303 | |
304 // Test a local change of a synced item. | |
305 TEST_F(ProcessorEntityTrackerTest, LocalChange) { | |
306 std::unique_ptr<ProcessorEntityTracker> entity = CreateSynced(); | |
307 const int64_t mtime_v0 = entity->metadata().modification_time(); | |
308 const std::string specifics_hash_v0 = entity->metadata().specifics_hash(); | |
309 | |
310 // Make a local change with different specifics. | |
311 entity->MakeLocalChange(GenerateEntityData(kTag, kValue2)); | |
312 | |
313 const int64_t mtime_v1 = entity->metadata().modification_time(); | |
314 const std::string specifics_hash_v1 = entity->metadata().specifics_hash(); | |
315 | |
316 EXPECT_FALSE(entity->metadata().is_deleted()); | |
317 EXPECT_EQ(1, entity->metadata().sequence_number()); | |
318 EXPECT_EQ(0, entity->metadata().acked_sequence_number()); | |
319 EXPECT_EQ(1, entity->metadata().server_version()); | |
320 EXPECT_LT(mtime_v0, mtime_v1); | |
321 EXPECT_NE(specifics_hash_v0, specifics_hash_v1); | |
322 EXPECT_EQ(specifics_hash_v0, entity->metadata().base_specifics_hash()); | |
323 | |
324 EXPECT_TRUE(entity->IsUnsynced()); | |
325 EXPECT_TRUE(entity->RequiresCommitRequest()); | |
326 EXPECT_FALSE(entity->RequiresCommitData()); | |
327 EXPECT_FALSE(entity->CanClearMetadata()); | |
328 EXPECT_TRUE(entity->HasCommitData()); | |
329 | |
330 // Make a commit. | |
331 CommitRequestData request; | |
332 entity->InitializeCommitRequestData(&request); | |
333 | |
334 EXPECT_EQ(kId, request.entity->id); | |
335 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
336 | |
337 // Ack the commit. | |
338 entity->ReceiveCommitResponse(GenerateAckData(request, 2)); | |
339 | |
340 EXPECT_EQ(1, entity->metadata().sequence_number()); | |
341 EXPECT_EQ(1, entity->metadata().acked_sequence_number()); | |
342 EXPECT_EQ(2, entity->metadata().server_version()); | |
343 EXPECT_EQ(mtime_v1, entity->metadata().modification_time()); | |
344 EXPECT_EQ(specifics_hash_v1, entity->metadata().specifics_hash()); | |
345 EXPECT_EQ("", entity->metadata().base_specifics_hash()); | |
346 | |
347 EXPECT_FALSE(entity->IsUnsynced()); | |
348 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
349 EXPECT_FALSE(entity->RequiresCommitData()); | |
350 EXPECT_FALSE(entity->CanClearMetadata()); | |
351 EXPECT_FALSE(entity->HasCommitData()); | |
352 } | |
353 | |
354 // Test a local deletion of a synced item. | |
355 TEST_F(ProcessorEntityTrackerTest, LocalDeletion) { | |
356 std::unique_ptr<ProcessorEntityTracker> entity = CreateSynced(); | |
357 const int64_t mtime = entity->metadata().modification_time(); | |
358 const std::string specifics_hash = entity->metadata().specifics_hash(); | |
359 | |
360 // Make a local delete. | |
361 entity->Delete(); | |
362 | |
363 EXPECT_TRUE(entity->metadata().is_deleted()); | |
364 EXPECT_EQ(1, entity->metadata().sequence_number()); | |
365 EXPECT_EQ(0, entity->metadata().acked_sequence_number()); | |
366 EXPECT_EQ(1, entity->metadata().server_version()); | |
367 EXPECT_LT(mtime, entity->metadata().modification_time()); | |
368 EXPECT_TRUE(entity->metadata().specifics_hash().empty()); | |
369 EXPECT_EQ(specifics_hash, entity->metadata().base_specifics_hash()); | |
370 | |
371 EXPECT_TRUE(entity->IsUnsynced()); | |
372 EXPECT_TRUE(entity->RequiresCommitRequest()); | |
373 EXPECT_FALSE(entity->RequiresCommitData()); | |
374 EXPECT_FALSE(entity->CanClearMetadata()); | |
375 EXPECT_FALSE(entity->HasCommitData()); | |
376 | |
377 // Generate a commit request. The metadata should not change. | |
378 const sync_pb::EntityMetadata metadata_v1 = entity->metadata(); | |
379 CommitRequestData request; | |
380 entity->InitializeCommitRequestData(&request); | |
381 EXPECT_EQ(metadata_v1.SerializeAsString(), | |
382 entity->metadata().SerializeAsString()); | |
383 | |
384 EXPECT_TRUE(entity->IsUnsynced()); | |
385 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
386 EXPECT_FALSE(entity->RequiresCommitData()); | |
387 EXPECT_FALSE(entity->CanClearMetadata()); | |
388 EXPECT_FALSE(entity->HasCommitData()); | |
389 | |
390 const EntityData& data = request.entity.value(); | |
391 EXPECT_EQ(kId, data.id); | |
392 EXPECT_EQ(tag_hash_, data.client_tag_hash); | |
393 EXPECT_EQ("", data.non_unique_name); | |
394 EXPECT_EQ(syncer::TimeToProtoTime(ctime_), | |
395 syncer::TimeToProtoTime(data.creation_time)); | |
396 EXPECT_EQ(entity->metadata().modification_time(), | |
397 syncer::TimeToProtoTime(data.modification_time)); | |
398 EXPECT_TRUE(data.is_deleted()); | |
399 EXPECT_EQ(1, request.sequence_number); | |
400 EXPECT_EQ(1, request.base_version); | |
401 EXPECT_EQ(entity->metadata().specifics_hash(), request.specifics_hash); | |
402 | |
403 // Ack the deletion. | |
404 entity->ReceiveCommitResponse(GenerateAckData(request, 2)); | |
405 | |
406 EXPECT_TRUE(entity->metadata().is_deleted()); | |
407 EXPECT_EQ(1, entity->metadata().sequence_number()); | |
408 EXPECT_EQ(1, entity->metadata().acked_sequence_number()); | |
409 EXPECT_EQ(2, entity->metadata().server_version()); | |
410 EXPECT_EQ(metadata_v1.modification_time(), | |
411 entity->metadata().modification_time()); | |
412 EXPECT_TRUE(entity->metadata().specifics_hash().empty()); | |
413 EXPECT_TRUE(entity->metadata().base_specifics_hash().empty()); | |
414 | |
415 EXPECT_FALSE(entity->IsUnsynced()); | |
416 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
417 EXPECT_FALSE(entity->RequiresCommitData()); | |
418 EXPECT_TRUE(entity->CanClearMetadata()); | |
419 EXPECT_FALSE(entity->HasCommitData()); | |
420 } | |
421 | |
422 // Test that hashes and sequence numbers are handled correctly for the "commit | |
423 // commit, ack ack" case. | |
424 TEST_F(ProcessorEntityTrackerTest, LocalChangesInterleaved) { | |
425 std::unique_ptr<ProcessorEntityTracker> entity = CreateSynced(); | |
426 const std::string specifics_hash_v0 = entity->metadata().specifics_hash(); | |
427 | |
428 // Make the first change. | |
429 entity->MakeLocalChange(GenerateEntityData(kTag, kValue2)); | |
430 const std::string specifics_hash_v1 = entity->metadata().specifics_hash(); | |
431 | |
432 EXPECT_EQ(1, entity->metadata().sequence_number()); | |
433 EXPECT_EQ(0, entity->metadata().acked_sequence_number()); | |
434 EXPECT_NE(specifics_hash_v0, specifics_hash_v1); | |
435 EXPECT_EQ(specifics_hash_v0, entity->metadata().base_specifics_hash()); | |
436 | |
437 // Request the first commit. | |
438 CommitRequestData request_v1; | |
439 entity->InitializeCommitRequestData(&request_v1); | |
440 | |
441 // Make the second change. | |
442 entity->MakeLocalChange(GenerateEntityData(kTag, kValue3)); | |
443 const std::string specifics_hash_v2 = entity->metadata().specifics_hash(); | |
444 | |
445 EXPECT_EQ(2, entity->metadata().sequence_number()); | |
446 EXPECT_EQ(0, entity->metadata().acked_sequence_number()); | |
447 EXPECT_NE(specifics_hash_v1, specifics_hash_v2); | |
448 EXPECT_EQ(specifics_hash_v0, entity->metadata().base_specifics_hash()); | |
449 | |
450 // Request the second commit. | |
451 CommitRequestData request_v2; | |
452 entity->InitializeCommitRequestData(&request_v2); | |
453 | |
454 EXPECT_TRUE(entity->IsUnsynced()); | |
455 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
456 EXPECT_FALSE(entity->RequiresCommitData()); | |
457 EXPECT_FALSE(entity->CanClearMetadata()); | |
458 EXPECT_TRUE(entity->HasCommitData()); | |
459 | |
460 // Ack the first commit. | |
461 entity->ReceiveCommitResponse(GenerateAckData(request_v1, 2)); | |
462 | |
463 EXPECT_EQ(2, entity->metadata().sequence_number()); | |
464 EXPECT_EQ(1, entity->metadata().acked_sequence_number()); | |
465 EXPECT_EQ(2, entity->metadata().server_version()); | |
466 EXPECT_EQ(specifics_hash_v2, entity->metadata().specifics_hash()); | |
467 EXPECT_EQ(specifics_hash_v1, entity->metadata().base_specifics_hash()); | |
468 | |
469 // Ack the second commit. | |
470 entity->ReceiveCommitResponse(GenerateAckData(request_v2, 3)); | |
471 | |
472 EXPECT_EQ(2, entity->metadata().sequence_number()); | |
473 EXPECT_EQ(2, entity->metadata().acked_sequence_number()); | |
474 EXPECT_EQ(3, entity->metadata().server_version()); | |
475 EXPECT_EQ(specifics_hash_v2, entity->metadata().specifics_hash()); | |
476 EXPECT_EQ("", entity->metadata().base_specifics_hash()); | |
477 | |
478 EXPECT_FALSE(entity->IsUnsynced()); | |
479 EXPECT_FALSE(entity->RequiresCommitRequest()); | |
480 EXPECT_FALSE(entity->RequiresCommitData()); | |
481 EXPECT_FALSE(entity->CanClearMetadata()); | |
482 EXPECT_FALSE(entity->HasCommitData()); | |
483 } | |
484 | |
485 } // namespace syncer_v2 | |
OLD | NEW |