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

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

Issue 7919001: test cases for server directed error handling code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: For trybots. Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python2.4 1 #!/usr/bin/python2.4
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 98
99 99
100 class StoreBirthdayError(Error): 100 class StoreBirthdayError(Error):
101 """The client sent a birthday that doesn't correspond to this server.""" 101 """The client sent a birthday that doesn't correspond to this server."""
102 102
103 103
104 class TransientError(Error): 104 class TransientError(Error):
105 """The client would be sent a transient error.""" 105 """The client would be sent a transient error."""
106 106
107 107
108 class SyncInducedError(Error):
109 """The client would be sent an error."""
110
111
108 def GetEntryType(entry): 112 def GetEntryType(entry):
109 """Extract the sync type from a SyncEntry. 113 """Extract the sync type from a SyncEntry.
110 114
111 Args: 115 Args:
112 entry: A SyncEntity protobuf object whose type to determine. 116 entry: A SyncEntity protobuf object whose type to determine.
113 Returns: 117 Returns:
114 An enum value from ALL_TYPES if the entry's type can be determined, or None 118 An enum value from ALL_TYPES if the entry's type can be determined, or None
115 if the type cannot be determined. 119 if the type cannot be determined.
116 Raises: 120 Raises:
117 ProtobufExtensionNotUnique: More than one type was indicated by the entry. 121 ProtobufExtensionNotUnique: More than one type was indicated by the entry.
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 self._version = 0 412 self._version = 0
409 413
410 # The definitive copy of this client's items: a map from ID string to a 414 # The definitive copy of this client's items: a map from ID string to a
411 # SyncEntity protocol buffer. 415 # SyncEntity protocol buffer.
412 self._entries = {} 416 self._entries = {}
413 417
414 self.ResetStoreBirthday() 418 self.ResetStoreBirthday()
415 419
416 self.migration_history = MigrationHistory() 420 self.migration_history = MigrationHistory()
417 421
422 self.induced_error = sync_pb2.ClientToServerResponse.Error()
423
418 def _SaveEntry(self, entry): 424 def _SaveEntry(self, entry):
419 """Insert or update an entry in the change log, and give it a new version. 425 """Insert or update an entry in the change log, and give it a new version.
420 426
421 The ID fields of this entry are assumed to be valid server IDs. This 427 The ID fields of this entry are assumed to be valid server IDs. This
422 entry will be updated with a new version number and sync_timestamp. 428 entry will be updated with a new version number and sync_timestamp.
423 429
424 Args: 430 Args:
425 entry: The entry to be added or updated. 431 entry: The entry to be added or updated.
426 """ 432 """
427 self._version += 1 433 self._version += 1
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 nigori_tag = "google_chrome_nigori" 879 nigori_tag = "google_chrome_nigori"
874 nigori_original = self._entries.get(self._ServerTagToId(nigori_tag)) 880 nigori_original = self._entries.get(self._ServerTagToId(nigori_tag))
875 if (nigori_original.specifics.Extensions[nigori_specifics_pb2.nigori]. 881 if (nigori_original.specifics.Extensions[nigori_specifics_pb2.nigori].
876 sync_tabs): 882 sync_tabs):
877 return 883 return
878 nigori_new = copy.deepcopy(nigori_original) 884 nigori_new = copy.deepcopy(nigori_original)
879 nigori_new.specifics.Extensions[nigori_specifics_pb2.nigori].sync_tabs = ( 885 nigori_new.specifics.Extensions[nigori_specifics_pb2.nigori].sync_tabs = (
880 True) 886 True)
881 self._SaveEntry(nigori_new) 887 self._SaveEntry(nigori_new)
882 888
889 def SetInducedError(self, error):
890 self.induced_error = error
891
892 def GetInducedError(self):
893 return self.induced_error
894
883 895
884 class TestServer(object): 896 class TestServer(object):
885 """An object to handle requests for one (and only one) Chrome Sync account. 897 """An object to handle requests for one (and only one) Chrome Sync account.
886 898
887 TestServer consumes the sync command messages that are the outermost 899 TestServer consumes the sync command messages that are the outermost
888 layers of the protocol, performs the corresponding actions on its 900 layers of the protocol, performs the corresponding actions on its
889 SyncDataModel, and constructs an appropropriate response message. 901 SyncDataModel, and constructs an appropropriate response message.
890 """ 902 """
891 903
892 def __init__(self): 904 def __init__(self):
(...skipping 22 matching lines...) Expand all
915 if not request.HasField('store_birthday'): 927 if not request.HasField('store_birthday'):
916 return 928 return
917 if self.account.StoreBirthday() != request.store_birthday: 929 if self.account.StoreBirthday() != request.store_birthday:
918 raise StoreBirthdayError 930 raise StoreBirthdayError
919 931
920 def CheckTransientError(self): 932 def CheckTransientError(self):
921 """Raises TransientError if transient_error variable is set.""" 933 """Raises TransientError if transient_error variable is set."""
922 if self.transient_error: 934 if self.transient_error:
923 raise TransientError 935 raise TransientError
924 936
937 def CheckSendError(self):
938 """Raises SyncInducedError if needed."""
939 if self.account.induced_error.error_type !=\
940 sync_pb2.ClientToServerResponse.UNKNOWN:
941 raise SyncInducedError
942
925 def HandleMigrate(self, path): 943 def HandleMigrate(self, path):
926 query = urlparse.urlparse(path)[4] 944 query = urlparse.urlparse(path)[4]
927 code = 200 945 code = 200
928 self.account_lock.acquire() 946 self.account_lock.acquire()
929 try: 947 try:
930 datatypes = [DataTypeStringToSyncTypeLoose(x) 948 datatypes = [DataTypeStringToSyncTypeLoose(x)
931 for x in urlparse.parse_qs(query).get('type',[])] 949 for x in urlparse.parse_qs(query).get('type',[])]
932 if datatypes: 950 if datatypes:
933 self.account.TriggerMigration(datatypes) 951 self.account.TriggerMigration(datatypes)
934 response = 'Migrated datatypes %s' % ( 952 response = 'Migrated datatypes %s' % (
935 ' and '.join(SyncTypeToString(x).upper() for x in datatypes)) 953 ' and '.join(SyncTypeToString(x).upper() for x in datatypes))
936 else: 954 else:
937 response = 'Please specify one or more <i>type=name</i> parameters' 955 response = 'Please specify one or more <i>type=name</i> parameters'
938 code = 400 956 code = 400
939 except DataTypeIdNotRecognized, error: 957 except DataTypeIdNotRecognized, error:
940 response = 'Could not interpret datatype name' 958 response = 'Could not interpret datatype name'
941 code = 400 959 code = 400
942 finally: 960 finally:
943 self.account_lock.release() 961 self.account_lock.release()
944 return (code, '<html><title>Migration: %d</title><H1>%d %s</H1></html>' % 962 return (code, '<html><title>Migration: %d</title><H1>%d %s</H1></html>' %
945 (code, code, response)) 963 (code, code, response))
946 964
965 def HandleSetInducedError(self, path):
966 query = urlparse.urlparse(path)[4]
967 self.account_lock.acquire()
968 code = 200;
969 response = 'Success'
970 error = sync_pb2.ClientToServerResponse.Error()
971 try:
972 error_type = urlparse.parse_qs(query)['error']
973 action = urlparse.parse_qs(query)['action']
974 error.error_type = int(error_type[0])
975 error.action = int(action[0])
976 try:
977 error.url = (urlparse.parse_qs(query)['url'])[0]
978 except KeyError:
979 error.url = ''
980 try:
981 error.error_description = \
982 (urlparse.parse_qs(query)['error_description'])[0]
983 except KeyError:
984 error.error_description = ''
985 self.account.SetInducedError(error)
986 response = ('Error = %d, action = %d, url = %s, description = %s' %
987 (error.error_type, error.action,
988 error.url,
989 error.error_description))
990 except error:
991 response = 'Could not parse url'
992 code = 400
993 finally:
994 self.account_lock.release()
995 return (code, '<html><title>SetError: %d</title><H1>%d %s</H1></html>' %
996 (code, code, response))
997
947 def HandleCreateBirthdayError(self): 998 def HandleCreateBirthdayError(self):
948 self.account.ResetStoreBirthday() 999 self.account.ResetStoreBirthday()
949 return ( 1000 return (
950 200, 1001 200,
951 '<html><title>Birthday error</title><H1>Birthday error</H1></html>') 1002 '<html><title>Birthday error</title><H1>Birthday error</H1></html>')
952 1003
953 def HandleSetTransientError(self): 1004 def HandleSetTransientError(self):
954 self.transient_error = True 1005 self.transient_error = True
955 return ( 1006 return (
956 200, 1007 200,
(...skipping 28 matching lines...) Expand all
985 try: 1036 try:
986 request = sync_pb2.ClientToServerMessage() 1037 request = sync_pb2.ClientToServerMessage()
987 request.MergeFromString(raw_request) 1038 request.MergeFromString(raw_request)
988 contents = request.message_contents 1039 contents = request.message_contents
989 1040
990 response = sync_pb2.ClientToServerResponse() 1041 response = sync_pb2.ClientToServerResponse()
991 response.error_code = sync_pb2.ClientToServerResponse.SUCCESS 1042 response.error_code = sync_pb2.ClientToServerResponse.SUCCESS
992 self.CheckStoreBirthday(request) 1043 self.CheckStoreBirthday(request)
993 response.store_birthday = self.account.store_birthday 1044 response.store_birthday = self.account.store_birthday
994 self.CheckTransientError(); 1045 self.CheckTransientError();
1046 self.CheckSendError();
995 1047
996 print_context('->') 1048 print_context('->')
997 1049
998 if contents == sync_pb2.ClientToServerMessage.AUTHENTICATE: 1050 if contents == sync_pb2.ClientToServerMessage.AUTHENTICATE:
999 print 'Authenticate' 1051 print 'Authenticate'
1000 # We accept any authentication token, and support only one account. 1052 # We accept any authentication token, and support only one account.
1001 # TODO(nick): Mock out the GAIA authentication as well; hook up here. 1053 # TODO(nick): Mock out the GAIA authentication as well; hook up here.
1002 response.authenticate.user.email = 'syncjuser@chromium' 1054 response.authenticate.user.email = 'syncjuser@chromium'
1003 response.authenticate.user.display_name = 'Sync J User' 1055 response.authenticate.user.display_name = 'Sync J User'
1004 elif contents == sync_pb2.ClientToServerMessage.COMMIT: 1056 elif contents == sync_pb2.ClientToServerMessage.COMMIT:
(...skipping 18 matching lines...) Expand all
1023 SyncTypeToProtocolDataTypeId(x) for x in error.datatypes] 1075 SyncTypeToProtocolDataTypeId(x) for x in error.datatypes]
1024 return (200, response.SerializeToString()) 1076 return (200, response.SerializeToString())
1025 except StoreBirthdayError, error: 1077 except StoreBirthdayError, error:
1026 print_context('<-') 1078 print_context('<-')
1027 print 'NOT_MY_BIRTHDAY' 1079 print 'NOT_MY_BIRTHDAY'
1028 response = sync_pb2.ClientToServerResponse() 1080 response = sync_pb2.ClientToServerResponse()
1029 response.store_birthday = self.account.store_birthday 1081 response.store_birthday = self.account.store_birthday
1030 response.error_code = sync_pb2.ClientToServerResponse.NOT_MY_BIRTHDAY 1082 response.error_code = sync_pb2.ClientToServerResponse.NOT_MY_BIRTHDAY
1031 return (200, response.SerializeToString()) 1083 return (200, response.SerializeToString())
1032 except TransientError, error: 1084 except TransientError, error:
1085 ### This is deprecated now. Would be remvoved once test cases are removed.
Raghu Simha 2011/09/22 21:57:41 This comment still doesn't follow the style guide.
1033 print_context('<-') 1086 print_context('<-')
1034 print 'TRANSIENT_ERROR' 1087 print 'TRANSIENT_ERROR'
1035 response.store_birthday = self.account.store_birthday 1088 response.store_birthday = self.account.store_birthday
1036 response.error_code = sync_pb2.ClientToServerResponse.TRANSIENT_ERROR 1089 response.error_code = sync_pb2.ClientToServerResponse.TRANSIENT_ERROR
1037 return (200, response.SerializeToString()) 1090 return (200, response.SerializeToString())
1091 except SyncInducedError, error:
1092 print_context('<-')
1093 print 'INDUCED_ERROR'
1094 response.store_birthday = self.account.store_birthday
1095 error = self.account.GetInducedError()
1096 response.error.error_type = error.error_type
1097 response.error.url = error.url
1098 response.error.error_description = error.error_description
1099 response.error.action = error.action
1100 return (200, response.SerializeToString())
1038 finally: 1101 finally:
1039 self.account_lock.release() 1102 self.account_lock.release()
1040 1103
1041 def HandleCommit(self, commit_message, commit_response): 1104 def HandleCommit(self, commit_message, commit_response):
1042 """Respond to a Commit request by updating the user's account state. 1105 """Respond to a Commit request by updating the user's account state.
1043 1106
1044 Commit attempts stop after the first error, returning a CONFLICT result 1107 Commit attempts stop after the first error, returning a CONFLICT result
1045 for any unattempted entries. 1108 for any unattempted entries.
1046 1109
1047 Args: 1110 Args:
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 1165
1103 update_sieve.CheckMigrationState() 1166 update_sieve.CheckMigrationState()
1104 1167
1105 new_timestamp, entries, remaining = self.account.GetChanges(update_sieve) 1168 new_timestamp, entries, remaining = self.account.GetChanges(update_sieve)
1106 1169
1107 update_response.changes_remaining = remaining 1170 update_response.changes_remaining = remaining
1108 for entry in entries: 1171 for entry in entries:
1109 reply = update_response.entries.add() 1172 reply = update_response.entries.add()
1110 reply.CopyFrom(entry) 1173 reply.CopyFrom(entry)
1111 update_sieve.SaveProgress(new_timestamp, update_response) 1174 update_sieve.SaveProgress(new_timestamp, update_response)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698