Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: net/tools/testserver/chromiumsync.py

Issue 3051019: Update python sync server to support recursive deletion. (Closed)
Patch Set: Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/test/live_sync/two_client_live_bookmarks_sync_test.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python2.4 1 #!/usr/bin/python2.4
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """An implementation of the server side of the Chromium sync protocol. 6 """An implementation of the server side of the Chromium sync protocol.
7 7
8 The details of the protocol are described mostly by comments in the protocol 8 The details of the protocol are described mostly by comments in the protocol
9 buffer definition at chrome/browser/sync/protocol/sync.proto. 9 buffer definition at chrome/browser/sync/protocol/sync.proto.
10 """ 10 """
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 # TODO(nick): Implement cycle detection and resolution. 502 # TODO(nick): Implement cycle detection and resolution.
503 if not self._CheckParentIdForCommit(entry): 503 if not self._CheckParentIdForCommit(entry):
504 return None 504 return None
505 505
506 # At this point, the commit is definitely going to happen. 506 # At this point, the commit is definitely going to happen.
507 507
508 # Deletion works by storing a limited record for an entry, called a 508 # Deletion works by storing a limited record for an entry, called a
509 # tombstone. A sync server must track deleted IDs forever, since it does 509 # tombstone. A sync server must track deleted IDs forever, since it does
510 # not keep track of client knowledge (there's no deletion ACK event). 510 # not keep track of client knowledge (there's no deletion ACK event).
511 if entry.deleted: 511 if entry.deleted:
512 # Only the ID, version and deletion state are preserved on a tombstone. 512 def MakeTombstone(id_string):
513 # TODO(nick): Does the production server not preserve the type? Not 513 """Make a tombstone entry that will replace the entry being deleted.
514 # doing so means that tombstones cannot be filtered based on 514
515 # requested_types at GetUpdates time. 515 Args:
516 tombstone = sync_pb2.SyncEntity() 516 id_string: Index of the SyncEntity to be deleted.
517 tombstone.id_string = entry.id_string 517 Returns:
518 tombstone.deleted = True 518 A new SyncEntity reflecting the fact that the entry is deleted.
519 tombstone.name = '' 519 """
520 entry = tombstone 520 # Only the ID, version and deletion state are preserved on a tombstone.
521 # TODO(nick): Does the production server not preserve the type? Not
522 # doing so means that tombstones cannot be filtered based on
523 # requested_types at GetUpdates time.
524 tombstone = sync_pb2.SyncEntity()
525 tombstone.id_string = id_string
526 tombstone.deleted = True
527 tombstone.name = ''
528 return tombstone
529
530 def IsChild(child_id):
531 """Check if a SyncEntity is a child of entry, or any of its children.
532
533 Args:
534 child_id: Index of the SyncEntity that is a possible child of entry.
535 Returns:
536 True if it is a child; false otherwise.
537 """
538 if child_id not in self._entries:
539 return False
540 if self._entries[child_id].parent_id_string == entry.id_string:
541 return True
542 return IsChild(self._entries[child_id].parent_id_string)
543
544 # Identify any children entry might have.
545 child_ids = []
546 for possible_child in self._entries.itervalues():
547 if IsChild(possible_child.id_string):
548 child_ids.append(possible_child.id_string)
549
550 # Mark all children that were identified as deleted.
551 for child_id in child_ids:
552 self._SaveEntry(MakeTombstone(child_id))
553
554 # Delete entry itself.
555 entry = MakeTombstone(entry.id_string)
521 else: 556 else:
522 # Comments in sync.proto detail how the representation of positional 557 # Comments in sync.proto detail how the representation of positional
523 # ordering works: the 'insert_after_item_id' field specifies a 558 # ordering works: the 'insert_after_item_id' field specifies a
524 # predecessor during Commit operations, but the 'position_in_parent' 559 # predecessor during Commit operations, but the 'position_in_parent'
525 # field provides an absolute ordering in GetUpdates contexts. Here 560 # field provides an absolute ordering in GetUpdates contexts. Here
526 # we convert from the former to the latter. Specifically, we'll 561 # we convert from the former to the latter. Specifically, we'll
527 # generate a numeric position placing the item just after the object 562 # generate a numeric position placing the item just after the object
528 # identified by 'insert_after_item_id', and then clear the 563 # identified by 'insert_after_item_id', and then clear the
529 # 'insert_after_item_id' field so that it's not sent back to the client 564 # 'insert_after_item_id' field so that it's not sent back to the client
530 # during later GetUpdates requests. 565 # during later GetUpdates requests.
531 if entry.HasField('insert_after_item_id'): 566 if entry.HasField('insert_after_item_id'):
532 self._WritePosition(entry, entry.parent_id_string, 567 self._WritePosition(entry, entry.parent_id_string,
533 entry.insert_after_item_id) 568 entry.insert_after_item_id)
534 else: 569 else:
535 self._WritePosition(entry, entry.parent_id_string) 570 self._WritePosition(entry, entry.parent_id_string)
536 571
537 # Preserve the originator info, which the client is not required to send 572 # Preserve the originator info, which the client is not required to send
538 # when updating. 573 # when updating.
539 base_entry = self._entries.get(entry.id_string) 574 base_entry = self._entries.get(entry.id_string)
540 if base_entry and not entry.HasField("originator_cache_guid"): 575 if base_entry and not entry.HasField("originator_cache_guid"):
541 entry.originator_cache_guid = base_entry.originator_cache_guid 576 entry.originator_cache_guid = base_entry.originator_cache_guid
542 entry.originator_client_item_id = base_entry.originator_client_item_id 577 entry.originator_client_item_id = base_entry.originator_client_item_id
543 578
544 # Commit the change. This also updates the version number. 579 # Commit the change. This also updates the version number.
545 self._SaveEntry(entry) 580 self._SaveEntry(entry)
546 # TODO(nick): Handle recursive deletion.
547 return entry 581 return entry
548 582
549 class TestServer(object): 583 class TestServer(object):
550 """An object to handle requests for one (and only one) Chrome Sync account. 584 """An object to handle requests for one (and only one) Chrome Sync account.
551 585
552 TestServer consumes the sync command messages that are the outermost 586 TestServer consumes the sync command messages that are the outermost
553 layers of the protocol, performs the corresponding actions on its 587 layers of the protocol, performs the corresponding actions on its
554 SyncDataModel, and constructs an appropropriate response message. 588 SyncDataModel, and constructs an appropropriate response message.
555 """ 589 """
556 590
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 new_timestamp, entries = self.account.GetChangesFromTimestamp( 692 new_timestamp, entries = self.account.GetChangesFromTimestamp(
659 requested_types, update_request.from_timestamp) 693 requested_types, update_request.from_timestamp)
660 694
661 # If the client is up to date, we are careful not to set the 695 # If the client is up to date, we are careful not to set the
662 # new_timestamp field. 696 # new_timestamp field.
663 if new_timestamp != update_request.from_timestamp: 697 if new_timestamp != update_request.from_timestamp:
664 update_response.new_timestamp = new_timestamp 698 update_response.new_timestamp = new_timestamp
665 for e in entries: 699 for e in entries:
666 reply = update_response.entries.add() 700 reply = update_response.entries.add()
667 reply.CopyFrom(e) 701 reply.CopyFrom(e)
OLDNEW
« no previous file with comments | « chrome/test/live_sync/two_client_live_bookmarks_sync_test.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698