summaryrefslogtreecommitdiffstats
path: root/sync
diff options
context:
space:
mode:
authorpvalenzuela@chromium.org <pvalenzuela@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-06 10:26:35 +0000
committerpvalenzuela@chromium.org <pvalenzuela@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-06 10:26:35 +0000
commit3db00dbf54c2b10f3735192d02991d4c44fab17b (patch)
tree9f62cae597f65e56ba12413a938fe98032f7b664 /sync
parent7db2949ca2537039dbd798a4c48bf11a84c13c30 (diff)
downloadchromium_src-3db00dbf54c2b10f3735192d02991d4c44fab17b.zip
chromium_src-3db00dbf54c2b10f3735192d02991d4c44fab17b.tar.gz
chromium_src-3db00dbf54c2b10f3735192d02991d4c44fab17b.tar.bz2
Add an HTML page to the Sync test server to trigger synced notifications
This change also fixes a bug where AddSyncedNotification returned a binary-encoded string instead of ASCII. Directions for triggering synced notifications in test server (Linux): 1) Build and run the test server: ninja -C out/Debug run_sync_testserver out/Debug/run_sync_testserver --port=1337 2) Run the browser against the test server: google-chrome --enable-logging --enable-synced-notifications \ --sync-url=http://127.0.0.1:1337/chromiumsync 3) Go to browser settings. If you are already signed in, click "Set up sync..." and hit OK on the subsequent dialog. Otherwise, sign in and complete Sync setup. 4) Navigate to http://127.0.0.1:1337/syncednotifications and follow the directions on the page. BUG=248332 Review URL: https://codereview.chromium.org/100053007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239159 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync')
-rw-r--r--sync/tools/testserver/chromiumsync.py52
-rwxr-xr-xsync/tools/testserver/sync_testserver.py43
-rw-r--r--sync/tools/testserver/synced_notifications.html51
3 files changed, 100 insertions, 46 deletions
diff --git a/sync/tools/testserver/chromiumsync.py b/sync/tools/testserver/chromiumsync.py
index 0ff6ce3..8b48113 100644
--- a/sync/tools/testserver/chromiumsync.py
+++ b/sync/tools/testserver/chromiumsync.py
@@ -11,6 +11,7 @@ buffer definition at chrome/browser/sync/protocol/sync.proto.
import base64
import cgi
import copy
+import google.protobuf.text_format
import hashlib
import operator
import pickle
@@ -185,6 +186,10 @@ class InducedErrorFrequencyNotDefined(Error):
"""The error frequency defined is not handled."""
+class ClientNotConnectedError(Error):
+ """The client is not connected to the server."""
+
+
def GetEntryType(entry):
"""Extract the sync type from a SyncEntry.
@@ -1144,26 +1149,28 @@ class SyncDataModel(object):
def GetInducedError(self):
return self.induced_error
- def AddSyncedNotification(self, heading, description, annotation):
+ def AddSyncedNotification(self, serialized_notification):
"""Adds a synced notification to the server data.
The notification will be delivered to the client on the next GetUpdates
call.
Args:
- heading: The notification heading.
- description: The notification description.
- annotation: The notification annotation.
+ serialized_notification: A serialized CoalescedSyncedNotification.
Returns:
The string representation of the added SyncEntity.
+
+ Raises:
+ ClientNotConnectedError: if the client has not yet connected to this
+ server
"""
# A unique string used wherever a unique ID for this notification is
# required.
unique_notification_id = str(uuid.uuid4())
specifics = self._CreateSyncedNotificationEntitySpecifics(
- unique_notification_id, heading, description, annotation)
+ unique_notification_id, serialized_notification)
# Create the root SyncEntity representing a single notification.
entity = sync_pb2.SyncEntity()
@@ -1175,6 +1182,8 @@ class SyncDataModel(object):
# Set the version to one more than the greatest version number already seen.
entries = sorted(self._entries.values(), key=operator.attrgetter('version'))
+ if len(entries) < 1:
+ raise ClientNotConnectedError
entity.version = entries[-1].version + 1
entity.client_defined_unique_tag = self._CreateSyncedNotificationClientTag(
@@ -1184,37 +1193,16 @@ class SyncDataModel(object):
self._entries[entity.id_string] = copy.deepcopy(entity)
- return entity.SerializeToString()
+ return google.protobuf.text_format.MessageToString(entity)
- def _CreateSyncedNotificationEntitySpecifics(self, unique_id, heading,
- description, annotation):
+ def _CreateSyncedNotificationEntitySpecifics(self, unique_id,
+ serialized_notification):
"""Create the EntitySpecifics proto for a synced notification."""
- layout = synced_notification_render_pb2.SimpleCollapsedLayout()
- layout.heading = heading
- layout.description = description
- layout.annotation = annotation
-
- collapsed_info = synced_notification_render_pb2.CollapsedInfo()
- collapsed_info.creation_timestamp_usec = 42
- collapsed_info.simple_collapsed_layout.CopyFrom(layout)
-
- render_info = synced_notification_render_pb2.SyncedNotificationRenderInfo()
- render_info.collapsed_info.CopyFrom(collapsed_info)
-
- # TODO(pvalenzuela): Transition this function to take a
- # CoalescedSyncedNotification as an argument instead of
- # creating it here. This will be possible when there is a proper frontend
- # with pre-populated notification data.
coalesced = synced_notification_data_pb2.CoalescedSyncedNotification()
- coalesced.read_state = synced_notification_data_pb2 \
- .CoalescedSyncedNotification.UNREAD
- coalesced.priority = synced_notification_data_pb2 \
- .CoalescedSyncedNotification.STANDARD
- coalesced.key = unique_id
- coalesced.render_info.CopyFrom(render_info)
+ google.protobuf.text_format.Merge(serialized_notification, coalesced)
- notification = coalesced.notification.add()
- notification.external_id = unique_id
+ # Override the provided key so that we have a unique one.
+ coalesced.key = unique_id
specifics = sync_pb2.EntitySpecifics()
notification_specifics = \
diff --git a/sync/tools/testserver/sync_testserver.py b/sync/tools/testserver/sync_testserver.py
index 91e47a5..5954e01 100755
--- a/sync/tools/testserver/sync_testserver.py
+++ b/sync/tools/testserver/sync_testserver.py
@@ -155,6 +155,7 @@ class SyncPageHandler(testserver_base.BasePageHandler):
self.GaiaOAuth2TokenHandler,
self.GaiaSetOAuth2TokenResponseHandler,
self.TriggerSyncedNotificationHandler,
+ self.SyncedNotificationsPageHandler,
self.CustomizeClientCommandHandler]
post_handlers = [self.ChromiumSyncCommandHandler,
@@ -508,23 +509,23 @@ class SyncPageHandler(testserver_base.BasePageHandler):
query = urlparse.urlparse(self.path)[4]
query_params = urlparse.parse_qs(query)
- heading = 'HEADING'
- description = 'DESCRIPTION'
- annotation = 'ANNOTATION'
+ serialized_notification = ''
- if 'heading' in query_params:
- heading = query_params['heading'][0]
- if 'description' in query_params:
- description = query_params['description'][0]
- if 'annotation' in query_params:
- annotation = query_params['annotation'][0]
+ if 'serialized_notification' in query_params:
+ serialized_notification = query_params['serialized_notification'][0]
- notification_string = self.server._sync_handler.account \
- .AddSyncedNotification(heading, description, annotation)
+ try:
+ notification_string = self.server._sync_handler.account \
+ .AddSyncedNotification(serialized_notification)
+ reply = "A synced notification was triggered:\n\n"
+ reply += "<code>{}</code>.".format(notification_string)
+ response_code = 200
+ except chromiumsync.ClientNotConnectedError:
+ reply = ('The client is not connected to the server, so the notification'
+ ' could not be created.')
+ response_code = 400
- reply = "A synced notification was triggered:\n\n"
- reply += "<code>{}</code>.".format(notification_string)
- self.send_response(200)
+ self.send_response(response_code)
self.send_header('Content-Type', 'text/html')
self.send_header('Content-Length', len(reply))
self.end_headers()
@@ -561,6 +562,20 @@ class SyncPageHandler(testserver_base.BasePageHandler):
self.wfile.write(reply)
return True
+ def SyncedNotificationsPageHandler(self):
+ test_name = "/syncednotifications"
+ if not self._ShouldHandleRequest(test_name):
+ return False
+
+ html = open('sync/tools/testserver/synced_notifications.html', 'r').read()
+
+ self.send_response(200)
+ self.send_header('Content-Type', 'text/html')
+ self.send_header('Content-Length', len(html))
+ self.end_headers()
+ self.wfile.write(html)
+ return True
+
class SyncServerRunner(testserver_base.TestServerRunner):
"""TestServerRunner for the net test servers."""
diff --git a/sync/tools/testserver/synced_notifications.html b/sync/tools/testserver/synced_notifications.html
new file mode 100644
index 0000000..c06f80b
--- /dev/null
+++ b/sync/tools/testserver/synced_notifications.html
@@ -0,0 +1,51 @@
+<html>
+ <head>
+ <title>Synced notifications</title>
+
+ <script type="text/javascript">
+ // Creates link (appended to the bottom of the page body) to trigger a
+ // synced notifications. The link's title will be |title| and
+ // |serialized_notification| is the ASCII-serialized version of the
+ // CoalescedSyncedNotification to be triggered.
+ function appendNotificationLink(title, serialized_notification) {
+ var link = document.createElement('a');
+ link.innerHTML = title;
+ link.setAttribute('target', '_blank');
+ link.setAttribute('href', 'triggersyncednotification?' +
+ 'serialized_notification=' +
+ encodeURIComponent(serialized_notification));
+ document.body.appendChild(link);
+ }
+ </script>
+ </head>
+
+ <body>
+ <h1>Synced notifications</h1>
+
+ <h2>Step 0: Sign in to the browser and set up Sync</h2>
+
+ <h2>Step 1: Click this link (only required once per server lifetime)</h2>
+
+ <a href="/customizeclientcommand?sessions_commit_delay_seconds=0">
+ Make notifications triggering instant</a>
+
+ <h2>Step 2: Ctrl-Click the links below to trigger synced notifications</h2>
+
+ <script type="text/javascript">
+ appendNotificationLink('Simple notification',
+ 'key: \"foo\"\n' +
+ 'priority: 2\n' +
+ 'read_state: 1\n' +
+ 'render_info {\n' +
+ ' collapsed_info {\n' +
+ ' creation_timestamp_usec: 42\n' +
+ ' simple_collapsed_layout {\n' +
+ ' annotation: \"Space Needle, 12:00 pm\"\n' +
+ ' description: \"Space Needle, 12:00 pm\"\n' +
+ ' heading: \"New appointment\"\n' +
+ ' }\n' +
+ ' }\n' +
+ '}');
+ </script>
+ </body>
+</html>