diff options
author | Zeno Albisser <zeno.albisser@digia.com> | 2013-08-15 21:46:11 +0200 |
---|---|---|
committer | Zeno Albisser <zeno.albisser@digia.com> | 2013-08-15 21:46:11 +0200 |
commit | 679147eead574d186ebf3069647b4c23e8ccace6 (patch) | |
tree | fc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/sync/tools/testserver/chromiumsync_test.py | |
download | qtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz |
Initial import.
Diffstat (limited to 'chromium/sync/tools/testserver/chromiumsync_test.py')
-rwxr-xr-x | chromium/sync/tools/testserver/chromiumsync_test.py | 680 |
1 files changed, 680 insertions, 0 deletions
diff --git a/chromium/sync/tools/testserver/chromiumsync_test.py b/chromium/sync/tools/testserver/chromiumsync_test.py new file mode 100755 index 00000000000..d83e4146c82 --- /dev/null +++ b/chromium/sync/tools/testserver/chromiumsync_test.py @@ -0,0 +1,680 @@ +#!/usr/bin/env python +# Copyright 2013 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. + +"""Tests exercising chromiumsync and SyncDataModel.""" + +import pickle +import unittest + +import autofill_specifics_pb2 +import bookmark_specifics_pb2 +import chromiumsync +import managed_user_specifics_pb2 +import sync_pb2 +import theme_specifics_pb2 + +class SyncDataModelTest(unittest.TestCase): + def setUp(self): + self.model = chromiumsync.SyncDataModel() + # The Synced Bookmarks folder is not created by default + self._expect_synced_bookmarks_folder = False + + def AddToModel(self, proto): + self.model._entries[proto.id_string] = proto + + def GetChangesFromTimestamp(self, requested_types, timestamp): + message = sync_pb2.GetUpdatesMessage() + message.from_timestamp = timestamp + for data_type in requested_types: + getattr(message.requested_types, + chromiumsync.SYNC_TYPE_TO_DESCRIPTOR[ + data_type].name).SetInParent() + return self.model.GetChanges( + chromiumsync.UpdateSieve(message, self.model.migration_history)) + + def FindMarkerByNumber(self, markers, datatype): + """Search a list of progress markers and find the one for a datatype.""" + for marker in markers: + if marker.data_type_id == datatype.number: + return marker + self.fail('Required marker not found: %s' % datatype.name) + + def testPermanentItemSpecs(self): + specs = chromiumsync.SyncDataModel._PERMANENT_ITEM_SPECS + + declared_specs = set(['0']) + for spec in specs: + self.assertTrue(spec.parent_tag in declared_specs, 'parent tags must ' + 'be declared before use') + declared_specs.add(spec.tag) + + unique_datatypes = set([x.sync_type for x in specs]) + self.assertEqual(unique_datatypes, + set(chromiumsync.ALL_TYPES[1:]), + 'Every sync datatype should have a permanent folder ' + 'associated with it') + + def testSaveEntry(self): + proto = sync_pb2.SyncEntity() + proto.id_string = 'abcd' + proto.version = 0 + self.assertFalse(self.model._ItemExists(proto.id_string)) + self.model._SaveEntry(proto) + self.assertEqual(1, proto.version) + self.assertTrue(self.model._ItemExists(proto.id_string)) + self.model._SaveEntry(proto) + self.assertEqual(2, proto.version) + proto.version = 0 + self.assertTrue(self.model._ItemExists(proto.id_string)) + self.assertEqual(2, self.model._entries[proto.id_string].version) + + def testCreatePermanentItems(self): + self.model._CreateDefaultPermanentItems(chromiumsync.ALL_TYPES) + self.assertEqual(len(chromiumsync.ALL_TYPES) + 1, + len(self.model._entries)) + + def ExpectedPermanentItemCount(self, sync_type): + if sync_type == chromiumsync.BOOKMARK: + if self._expect_synced_bookmarks_folder: + return 4 + else: + return 3 + else: + return 1 + + def testGetChangesFromTimestampZeroForEachType(self): + all_types = chromiumsync.ALL_TYPES[1:] + for sync_type in all_types: + self.model = chromiumsync.SyncDataModel() + request_types = [sync_type] + + version, changes, remaining = ( + self.GetChangesFromTimestamp(request_types, 0)) + + expected_count = self.ExpectedPermanentItemCount(sync_type) + self.assertEqual(expected_count, version) + self.assertEqual(expected_count, len(changes)) + for change in changes: + self.assertTrue(change.HasField('server_defined_unique_tag')) + self.assertEqual(change.version, change.sync_timestamp) + self.assertTrue(change.version <= version) + + # Test idempotence: another GetUpdates from ts=0 shouldn't recreate. + version, changes, remaining = ( + self.GetChangesFromTimestamp(request_types, 0)) + self.assertEqual(expected_count, version) + self.assertEqual(expected_count, len(changes)) + self.assertEqual(0, remaining) + + # Doing a wider GetUpdates from timestamp zero shouldn't recreate either. + new_version, changes, remaining = ( + self.GetChangesFromTimestamp(all_types, 0)) + if self._expect_synced_bookmarks_folder: + self.assertEqual(len(chromiumsync.SyncDataModel._PERMANENT_ITEM_SPECS), + new_version) + else: + self.assertEqual( + len(chromiumsync.SyncDataModel._PERMANENT_ITEM_SPECS) -1, + new_version) + self.assertEqual(new_version, len(changes)) + self.assertEqual(0, remaining) + version, changes, remaining = ( + self.GetChangesFromTimestamp(request_types, 0)) + self.assertEqual(new_version, version) + self.assertEqual(expected_count, len(changes)) + self.assertEqual(0, remaining) + + def testBatchSize(self): + for sync_type in chromiumsync.ALL_TYPES[1:]: + specifics = chromiumsync.GetDefaultEntitySpecifics(sync_type) + self.model = chromiumsync.SyncDataModel() + request_types = [sync_type] + + for i in range(self.model._BATCH_SIZE*3): + entry = sync_pb2.SyncEntity() + entry.id_string = 'batch test %d' % i + entry.specifics.CopyFrom(specifics) + self.model._SaveEntry(entry) + last_bit = self.ExpectedPermanentItemCount(sync_type) + version, changes, changes_remaining = ( + self.GetChangesFromTimestamp(request_types, 0)) + self.assertEqual(self.model._BATCH_SIZE, version) + self.assertEqual(self.model._BATCH_SIZE*2 + last_bit, changes_remaining) + version, changes, changes_remaining = ( + self.GetChangesFromTimestamp(request_types, version)) + self.assertEqual(self.model._BATCH_SIZE*2, version) + self.assertEqual(self.model._BATCH_SIZE + last_bit, changes_remaining) + version, changes, changes_remaining = ( + self.GetChangesFromTimestamp(request_types, version)) + self.assertEqual(self.model._BATCH_SIZE*3, version) + self.assertEqual(last_bit, changes_remaining) + version, changes, changes_remaining = ( + self.GetChangesFromTimestamp(request_types, version)) + self.assertEqual(self.model._BATCH_SIZE*3 + last_bit, version) + self.assertEqual(0, changes_remaining) + + # Now delete a third of the items. + for i in xrange(self.model._BATCH_SIZE*3 - 1, 0, -3): + entry = sync_pb2.SyncEntity() + entry.id_string = 'batch test %d' % i + entry.deleted = True + self.model._SaveEntry(entry) + + # The batch counts shouldn't change. + version, changes, changes_remaining = ( + self.GetChangesFromTimestamp(request_types, 0)) + self.assertEqual(self.model._BATCH_SIZE, len(changes)) + self.assertEqual(self.model._BATCH_SIZE*2 + last_bit, changes_remaining) + version, changes, changes_remaining = ( + self.GetChangesFromTimestamp(request_types, version)) + self.assertEqual(self.model._BATCH_SIZE, len(changes)) + self.assertEqual(self.model._BATCH_SIZE + last_bit, changes_remaining) + version, changes, changes_remaining = ( + self.GetChangesFromTimestamp(request_types, version)) + self.assertEqual(self.model._BATCH_SIZE, len(changes)) + self.assertEqual(last_bit, changes_remaining) + version, changes, changes_remaining = ( + self.GetChangesFromTimestamp(request_types, version)) + self.assertEqual(last_bit, len(changes)) + self.assertEqual(self.model._BATCH_SIZE*4 + last_bit, version) + self.assertEqual(0, changes_remaining) + + def testCommitEachDataType(self): + for sync_type in chromiumsync.ALL_TYPES[1:]: + specifics = chromiumsync.GetDefaultEntitySpecifics(sync_type) + self.model = chromiumsync.SyncDataModel() + my_cache_guid = '112358132134' + parent = 'foobar' + commit_session = {} + + # Start with a GetUpdates from timestamp 0, to populate permanent items. + original_version, original_changes, changes_remaining = ( + self.GetChangesFromTimestamp([sync_type], 0)) + + def DoCommit(original=None, id_string='', name=None, parent=None, + position=0): + proto = sync_pb2.SyncEntity() + if original is not None: + proto.version = original.version + proto.id_string = original.id_string + proto.parent_id_string = original.parent_id_string + proto.name = original.name + else: + proto.id_string = id_string + proto.version = 0 + proto.specifics.CopyFrom(specifics) + if name is not None: + proto.name = name + if parent: + proto.parent_id_string = parent.id_string + proto.insert_after_item_id = 'please discard' + proto.position_in_parent = position + proto.folder = True + proto.deleted = False + result = self.model.CommitEntry(proto, my_cache_guid, commit_session) + self.assertTrue(result) + return (proto, result) + + # Commit a new item. + proto1, result1 = DoCommit(name='namae', id_string='Foo', + parent=original_changes[-1], position=100) + # Commit an item whose parent is another item (referenced via the + # pre-commit ID). + proto2, result2 = DoCommit(name='Secondo', id_string='Bar', + parent=proto1, position=-100) + # Commit a sibling of the second item. + proto3, result3 = DoCommit(name='Third!', id_string='Baz', + parent=proto1, position=-50) + + self.assertEqual(3, len(commit_session)) + for p, r in [(proto1, result1), (proto2, result2), (proto3, result3)]: + self.assertNotEqual(r.id_string, p.id_string) + self.assertEqual(r.originator_client_item_id, p.id_string) + self.assertEqual(r.originator_cache_guid, my_cache_guid) + self.assertTrue(r is not self.model._entries[r.id_string], + "Commit result didn't make a defensive copy.") + self.assertTrue(p is not self.model._entries[r.id_string], + "Commit result didn't make a defensive copy.") + self.assertEqual(commit_session.get(p.id_string), r.id_string) + self.assertTrue(r.version > original_version) + self.assertEqual(result1.parent_id_string, proto1.parent_id_string) + self.assertEqual(result2.parent_id_string, result1.id_string) + version, changes, remaining = ( + self.GetChangesFromTimestamp([sync_type], original_version)) + self.assertEqual(3, len(changes)) + self.assertEqual(0, remaining) + self.assertEqual(original_version + 3, version) + self.assertEqual([result1, result2, result3], changes) + for c in changes: + self.assertTrue(c is not self.model._entries[c.id_string], + "GetChanges didn't make a defensive copy.") + self.assertTrue(result2.position_in_parent < result3.position_in_parent) + self.assertEqual(-100, result2.position_in_parent) + + # Now update the items so that the second item is the parent of the + # first; with the first sandwiched between two new items (4 and 5). + # Do this in a new commit session, meaning we'll reference items from + # the first batch by their post-commit, server IDs. + commit_session = {} + old_cache_guid = my_cache_guid + my_cache_guid = 'A different GUID' + proto2b, result2b = DoCommit(original=result2, + parent=original_changes[-1]) + proto4, result4 = DoCommit(id_string='ID4', name='Four', + parent=result2, position=-200) + proto1b, result1b = DoCommit(original=result1, + parent=result2, position=-150) + proto5, result5 = DoCommit(id_string='ID5', name='Five', parent=result2, + position=150) + + self.assertEqual(2, len(commit_session), 'Only new items in second ' + 'batch should be in the session') + for p, r, original in [(proto2b, result2b, proto2), + (proto4, result4, proto4), + (proto1b, result1b, proto1), + (proto5, result5, proto5)]: + self.assertEqual(r.originator_client_item_id, original.id_string) + if original is not p: + self.assertEqual(r.id_string, p.id_string, + 'Ids should be stable after first commit') + self.assertEqual(r.originator_cache_guid, old_cache_guid) + else: + self.assertNotEqual(r.id_string, p.id_string) + self.assertEqual(r.originator_cache_guid, my_cache_guid) + self.assertEqual(commit_session.get(p.id_string), r.id_string) + self.assertTrue(r is not self.model._entries[r.id_string], + "Commit result didn't make a defensive copy.") + self.assertTrue(p is not self.model._entries[r.id_string], + "Commit didn't make a defensive copy.") + self.assertTrue(r.version > p.version) + version, changes, remaining = ( + self.GetChangesFromTimestamp([sync_type], original_version)) + self.assertEqual(5, len(changes)) + self.assertEqual(0, remaining) + self.assertEqual(original_version + 7, version) + self.assertEqual([result3, result2b, result4, result1b, result5], changes) + for c in changes: + self.assertTrue(c is not self.model._entries[c.id_string], + "GetChanges didn't make a defensive copy.") + self.assertTrue(result4.parent_id_string == + result1b.parent_id_string == + result5.parent_id_string == + result2b.id_string) + self.assertTrue(result4.position_in_parent < + result1b.position_in_parent < + result5.position_in_parent) + + def testUpdateSieve(self): + # from_timestamp, legacy mode + autofill = chromiumsync.SYNC_TYPE_FIELDS['autofill'] + theme = chromiumsync.SYNC_TYPE_FIELDS['theme'] + msg = sync_pb2.GetUpdatesMessage() + msg.from_timestamp = 15412 + msg.requested_types.autofill.SetInParent() + msg.requested_types.theme.SetInParent() + + sieve = chromiumsync.UpdateSieve(msg) + self.assertEqual(sieve._state, + {chromiumsync.TOP_LEVEL: 15412, + chromiumsync.AUTOFILL: 15412, + chromiumsync.THEME: 15412}) + + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(15412, response) + self.assertEqual(0, len(response.new_progress_marker)) + self.assertFalse(response.HasField('new_timestamp')) + + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(15413, response) + self.assertEqual(0, len(response.new_progress_marker)) + self.assertTrue(response.HasField('new_timestamp')) + self.assertEqual(15413, response.new_timestamp) + + # Existing tokens + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.token = pickle.dumps((15412, 1)) + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.token = pickle.dumps((15413, 1)) + sieve = chromiumsync.UpdateSieve(msg) + self.assertEqual(sieve._state, + {chromiumsync.TOP_LEVEL: 15412, + chromiumsync.AUTOFILL: 15412, + chromiumsync.THEME: 15413}) + + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(15413, response) + self.assertEqual(1, len(response.new_progress_marker)) + self.assertFalse(response.HasField('new_timestamp')) + marker = response.new_progress_marker[0] + self.assertEqual(marker.data_type_id, autofill.number) + self.assertEqual(pickle.loads(marker.token), (15413, 1)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + + # Empty tokens indicating from timestamp = 0 + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.token = pickle.dumps((412, 1)) + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.token = '' + sieve = chromiumsync.UpdateSieve(msg) + self.assertEqual(sieve._state, + {chromiumsync.TOP_LEVEL: 0, + chromiumsync.AUTOFILL: 412, + chromiumsync.THEME: 0}) + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(1, response) + self.assertEqual(1, len(response.new_progress_marker)) + self.assertFalse(response.HasField('new_timestamp')) + marker = response.new_progress_marker[0] + self.assertEqual(marker.data_type_id, theme.number) + self.assertEqual(pickle.loads(marker.token), (1, 1)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(412, response) + self.assertEqual(1, len(response.new_progress_marker)) + self.assertFalse(response.HasField('new_timestamp')) + marker = response.new_progress_marker[0] + self.assertEqual(marker.data_type_id, theme.number) + self.assertEqual(pickle.loads(marker.token), (412, 1)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(413, response) + self.assertEqual(2, len(response.new_progress_marker)) + self.assertFalse(response.HasField('new_timestamp')) + marker = self.FindMarkerByNumber(response.new_progress_marker, theme) + self.assertEqual(pickle.loads(marker.token), (413, 1)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + marker = self.FindMarkerByNumber(response.new_progress_marker, autofill) + self.assertEqual(pickle.loads(marker.token), (413, 1)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + + # Migration token timestamps (client gives timestamp, server returns token) + # These are for migrating from the old 'timestamp' protocol to the + # progressmarker protocol, and have nothing to do with the MIGRATION_DONE + # error code. + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.timestamp_token_for_migration = 15213 + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.timestamp_token_for_migration = 15211 + sieve = chromiumsync.UpdateSieve(msg) + self.assertEqual(sieve._state, + {chromiumsync.TOP_LEVEL: 15211, + chromiumsync.AUTOFILL: 15213, + chromiumsync.THEME: 15211}) + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(16000, response) # There were updates + self.assertEqual(2, len(response.new_progress_marker)) + self.assertFalse(response.HasField('new_timestamp')) + marker = self.FindMarkerByNumber(response.new_progress_marker, theme) + self.assertEqual(pickle.loads(marker.token), (16000, 1)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + marker = self.FindMarkerByNumber(response.new_progress_marker, autofill) + self.assertEqual(pickle.loads(marker.token), (16000, 1)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.timestamp_token_for_migration = 3000 + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.timestamp_token_for_migration = 3000 + sieve = chromiumsync.UpdateSieve(msg) + self.assertEqual(sieve._state, + {chromiumsync.TOP_LEVEL: 3000, + chromiumsync.AUTOFILL: 3000, + chromiumsync.THEME: 3000}) + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(3000, response) # Already up to date + self.assertEqual(2, len(response.new_progress_marker)) + self.assertFalse(response.HasField('new_timestamp')) + marker = self.FindMarkerByNumber(response.new_progress_marker, theme) + self.assertEqual(pickle.loads(marker.token), (3000, 1)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + marker = self.FindMarkerByNumber(response.new_progress_marker, autofill) + self.assertEqual(pickle.loads(marker.token), (3000, 1)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + + def testCheckRaiseTransientError(self): + testserver = chromiumsync.TestServer() + http_code, raw_respon = testserver.HandleSetTransientError() + self.assertEqual(http_code, 200) + try: + testserver.CheckTransientError() + self.fail('Should have raised transient error exception') + except chromiumsync.TransientError: + self.assertTrue(testserver.transient_error) + + def testUpdateSieveStoreMigration(self): + autofill = chromiumsync.SYNC_TYPE_FIELDS['autofill'] + theme = chromiumsync.SYNC_TYPE_FIELDS['theme'] + migrator = chromiumsync.MigrationHistory() + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.token = pickle.dumps((15412, 1)) + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.token = pickle.dumps((15413, 1)) + sieve = chromiumsync.UpdateSieve(msg, migrator) + sieve.CheckMigrationState() + + migrator.Bump([chromiumsync.BOOKMARK, chromiumsync.PASSWORD]) # v=2 + sieve = chromiumsync.UpdateSieve(msg, migrator) + sieve.CheckMigrationState() + self.assertEqual(sieve._state, + {chromiumsync.TOP_LEVEL: 15412, + chromiumsync.AUTOFILL: 15412, + chromiumsync.THEME: 15413}) + + migrator.Bump([chromiumsync.AUTOFILL, chromiumsync.PASSWORD]) # v=3 + sieve = chromiumsync.UpdateSieve(msg, migrator) + try: + sieve.CheckMigrationState() + self.fail('Should have raised.') + except chromiumsync.MigrationDoneError, error: + # We want this to happen. + self.assertEqual([chromiumsync.AUTOFILL], error.datatypes) + + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.token = '' + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.token = pickle.dumps((15413, 1)) + sieve = chromiumsync.UpdateSieve(msg, migrator) + sieve.CheckMigrationState() + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(15412, response) # There were updates + self.assertEqual(1, len(response.new_progress_marker)) + self.assertFalse(response.HasField('new_timestamp')) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + marker = self.FindMarkerByNumber(response.new_progress_marker, autofill) + self.assertEqual(pickle.loads(marker.token), (15412, 3)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.token = pickle.dumps((15412, 3)) + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.token = pickle.dumps((15413, 1)) + sieve = chromiumsync.UpdateSieve(msg, migrator) + sieve.CheckMigrationState() + + migrator.Bump([chromiumsync.THEME, chromiumsync.AUTOFILL]) # v=4 + migrator.Bump([chromiumsync.AUTOFILL]) # v=5 + sieve = chromiumsync.UpdateSieve(msg, migrator) + try: + sieve.CheckMigrationState() + self.fail("Should have raised.") + except chromiumsync.MigrationDoneError, error: + # We want this to happen. + self.assertEqual(set([chromiumsync.THEME, chromiumsync.AUTOFILL]), + set(error.datatypes)) + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.token = '' + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.token = pickle.dumps((15413, 1)) + sieve = chromiumsync.UpdateSieve(msg, migrator) + try: + sieve.CheckMigrationState() + self.fail("Should have raised.") + except chromiumsync.MigrationDoneError, error: + # We want this to happen. + self.assertEqual([chromiumsync.THEME], error.datatypes) + + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.token = '' + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.token = '' + sieve = chromiumsync.UpdateSieve(msg, migrator) + sieve.CheckMigrationState() + response = sync_pb2.GetUpdatesResponse() + sieve.SaveProgress(15412, response) # There were updates + self.assertEqual(2, len(response.new_progress_marker)) + self.assertFalse(response.HasField('new_timestamp')) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + marker = self.FindMarkerByNumber(response.new_progress_marker, autofill) + self.assertEqual(pickle.loads(marker.token), (15412, 5)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + marker = self.FindMarkerByNumber(response.new_progress_marker, theme) + self.assertEqual(pickle.loads(marker.token), (15412, 4)) + self.assertFalse(marker.HasField('timestamp_token_for_migration')) + msg = sync_pb2.GetUpdatesMessage() + marker = msg.from_progress_marker.add() + marker.data_type_id = autofill.number + marker.token = pickle.dumps((15412, 5)) + marker = msg.from_progress_marker.add() + marker.data_type_id = theme.number + marker.token = pickle.dumps((15413, 4)) + sieve = chromiumsync.UpdateSieve(msg, migrator) + sieve.CheckMigrationState() + + def testCreateSyncedBookmarks(self): + version1, changes, remaining = ( + self.GetChangesFromTimestamp([chromiumsync.BOOKMARK], 0)) + id_string = self.model._MakeCurrentId(chromiumsync.BOOKMARK, + '<server tag>synced_bookmarks') + self.assertFalse(self.model._ItemExists(id_string)) + self._expect_synced_bookmarks_folder = True + self.model.TriggerCreateSyncedBookmarks() + self.assertTrue(self.model._ItemExists(id_string)) + + # Check that the version changed when the folder was created and the only + # change was the folder creation. + version2, changes, remaining = ( + self.GetChangesFromTimestamp([chromiumsync.BOOKMARK], version1)) + self.assertEqual(len(changes), 1) + self.assertEqual(changes[0].id_string, id_string) + self.assertNotEqual(version1, version2) + self.assertEqual( + self.ExpectedPermanentItemCount(chromiumsync.BOOKMARK), + version2) + + # Ensure getting from timestamp 0 includes the folder. + version, changes, remaining = ( + self.GetChangesFromTimestamp([chromiumsync.BOOKMARK], 0)) + self.assertEqual( + self.ExpectedPermanentItemCount(chromiumsync.BOOKMARK), + len(changes)) + self.assertEqual(version2, version) + + def testAcknowledgeManagedUser(self): + # Create permanent items. + self.GetChangesFromTimestamp([chromiumsync.MANAGED_USER], 0) + proto = sync_pb2.SyncEntity() + proto.id_string = 'abcd' + proto.version = 0 + + # Make sure the managed_user field exists. + proto.specifics.managed_user.acknowledged = False + self.assertTrue(proto.specifics.HasField('managed_user')) + self.AddToModel(proto) + version1, changes1, remaining1 = ( + self.GetChangesFromTimestamp([chromiumsync.MANAGED_USER], 0)) + for change in changes1: + self.assertTrue(not change.specifics.managed_user.acknowledged) + + # Turn on managed user acknowledgement + self.model.acknowledge_managed_users = True + + version2, changes2, remaining2 = ( + self.GetChangesFromTimestamp([chromiumsync.MANAGED_USER], 0)) + for change in changes2: + self.assertTrue(change.specifics.managed_user.acknowledged) + + def testGetKey(self): + [key1] = self.model.GetKeystoreKeys() + [key2] = self.model.GetKeystoreKeys() + self.assertTrue(len(key1)) + self.assertEqual(key1, key2) + + # Trigger the rotation. A subsequent GetUpdates should return the nigori + # node (whose timestamp was bumped by the rotation). + version1, changes, remaining = ( + self.GetChangesFromTimestamp([chromiumsync.NIGORI], 0)) + self.model.TriggerRotateKeystoreKeys() + version2, changes, remaining = ( + self.GetChangesFromTimestamp([chromiumsync.NIGORI], version1)) + self.assertNotEqual(version1, version2) + self.assertEquals(len(changes), 1) + self.assertEquals(changes[0].name, "Nigori") + + # The current keys should contain the old keys, with the new key appended. + [key1, key3] = self.model.GetKeystoreKeys() + self.assertEquals(key1, key2) + self.assertNotEqual(key1, key3) + self.assertTrue(len(key3) > 0) + + def testTriggerEnableKeystoreEncryption(self): + version1, changes, remaining = ( + self.GetChangesFromTimestamp([chromiumsync.EXPERIMENTS], 0)) + keystore_encryption_id_string = ( + self.model._ClientTagToId( + chromiumsync.EXPERIMENTS, + chromiumsync.KEYSTORE_ENCRYPTION_EXPERIMENT_TAG)) + + self.assertFalse(self.model._ItemExists(keystore_encryption_id_string)) + self.model.TriggerEnableKeystoreEncryption() + self.assertTrue(self.model._ItemExists(keystore_encryption_id_string)) + + # The creation of the experiment should be downloaded on the next + # GetUpdates. + version2, changes, remaining = ( + self.GetChangesFromTimestamp([chromiumsync.EXPERIMENTS], version1)) + self.assertEqual(len(changes), 1) + self.assertEqual(changes[0].id_string, keystore_encryption_id_string) + self.assertNotEqual(version1, version2) + + # Verify the experiment was created properly and is enabled. + self.assertEqual(chromiumsync.KEYSTORE_ENCRYPTION_EXPERIMENT_TAG, + changes[0].client_defined_unique_tag) + self.assertTrue(changes[0].HasField("specifics")) + self.assertTrue(changes[0].specifics.HasField("experiments")) + self.assertTrue( + changes[0].specifics.experiments.HasField("keystore_encryption")) + self.assertTrue( + changes[0].specifics.experiments.keystore_encryption.enabled) + +if __name__ == '__main__': + unittest.main() |