def testBroadcastChannel(self):
    broadcast_channel = channel.BroadcastChannel('some-unique-channel-id')

    # This shouldn't error without any clients connected, but it shouldn't
    # queue up the message either.
    broadcast_channel.send_message('Hello world!')

    tokens = []
    self.assertFalse(broadcast_channel.exists)
    tokens.append(channel.create_channel('foo'))
    tokens.append(channel.create_channel('bar'))
    tokens.append(channel.create_channel('*****@*****.**'))
    self.assertTrue(all(tokens), 'Bad tokens: %r' % tokens)

    broadcast_channel.subscribe('foo')
    broadcast_channel.subscribe('bar')
    broadcast_channel.subscribe('*****@*****.**')
    self.assertTrue(broadcast_channel.exists)

    # Must connect each client to the channel before broadcast.
    # This happens automatically by the client scripts in the real world.
    for token in tokens:
      self.channel_stub.connect_channel(token)

    broadcast_channel.send_message('Hello world!')
    for token in tokens:
      message = self.channel_stub.pop_first_message(token)
      message_data = {
          'message': 'Hello world!',
          'broadcast_channel_key': 'some-unique-channel-id'
      }
      self.assertEqual(json.dumps(message_data), message)
Example #2
0
    def testBroadcastChannel(self):
        broadcast_channel = channel.BroadcastChannel('some-unique-channel-id')

        # This shouldn't error without any clients connected, but it shouldn't
        # queue up the message either.
        broadcast_channel.send_message('Hello world!')

        tokens = []
        self.assertFalse(broadcast_channel.exists)
        tokens.append(channel.create_channel('foo'))
        tokens.append(channel.create_channel('bar'))
        tokens.append(channel.create_channel('*****@*****.**'))
        self.assertTrue(all(tokens), 'Bad tokens: %r' % tokens)

        broadcast_channel.subscribe('foo')
        broadcast_channel.subscribe('bar')
        broadcast_channel.subscribe('*****@*****.**')
        self.assertTrue(broadcast_channel.exists)

        # Must connect each client to the channel before broadcast.
        # This happens automatically by the client scripts in the real world.
        for token in tokens:
            self.channel_stub.connect_channel(token)

        broadcast_channel.send_message('Hello world!')
        for token in tokens:
            message = self.channel_stub.pop_first_message(token)
            message_data = {
                'message': 'Hello world!',
                'broadcast_channel_key': 'some-unique-channel-id'
            }
            self.assertEqual(json.dumps(message_data), message)
    def testTaskManagerSubscribeHandlerTest(self):
        url = "/_titan/tasks/taskmanager/subscribe"
        response = self.app.post(url, expect_errors=True)
        self.assertEqual(400, response.status_int)

        url = "/_titan/tasks/taskmanager/subscribe?key=fake&client_id=foo"
        response = self.app.post(url, expect_errors=True)
        self.assertEqual(404, response.status_int)

        client_id = "unique-client-id"
        token = channel.create_channel(client_id)
        task_manager = tasks.TaskManager.new(broadcast_channel_key="broadcast")
        url = "/_titan/tasks/taskmanager/subscribe?key=%s&client_id=%s" % (task_manager.key, client_id)
        response = self.app.post(url)
        self.assertEqual(200, response.status_int)

        # Must connect each client to the channel before broadcast.
        # This happens automatically by the client scripts in the real world.
        self.channel_stub.connect_channel(token)

        task_manager.defer_task("task-key0", GoodCallback)
        task_manager.defer_task("task-key1", BadCallback)
        task_manager.finalize()

        # Weakly assert that messages were sent to the broadcast channel.
        self.assertTrue(self.channel_stub.pop_first_message(token))
Example #4
0
    def testTaskManagerSubscribeHandlerTest(self):
        url = '/_titan/tasks/taskmanager/subscribe'
        response = self.app.post(url, expect_errors=True)
        self.assertEqual(400, response.status_int)

        url = '/_titan/tasks/taskmanager/subscribe?key=fake&client_id=foo'
        response = self.app.post(url, expect_errors=True)
        self.assertEqual(404, response.status_int)

        client_id = 'unique-client-id'
        token = channel.create_channel(client_id)
        task_manager = tasks.TaskManager.new(broadcast_channel_key='broadcast')
        url = '/_titan/tasks/taskmanager/subscribe?key=%s&client_id=%s' % (
            task_manager.key, client_id)
        response = self.app.post(url)
        self.assertEqual(200, response.status_int)

        # Must connect each client to the channel before broadcast.
        # This happens automatically by the client scripts in the real world.
        self.channel_stub.connect_channel(token)

        task_manager.defer_task('task-key0', GoodCallback)
        task_manager.defer_task('task-key1', BadCallback)
        task_manager.finalize()

        # Weakly assert that messages were sent to the broadcast channel.
        self.assertTrue(self.channel_stub.pop_first_message(token))
Example #5
0
 def get(self):
     # This is the low-level App Engine Channel API client_id, and should
     # be unique for each individual JavaScript client.
     # https://developers.google.com/appengine/docs/python/channel/functions
     user = users.get_current_user()
     # Make each client unique based on the current user email and request ID.
     client_id = hashlib.md5(user.email + os.environ["REQUEST_ID_HASH"])
     client_id = client_id.hexdigest()
     token = channel.create_channel(client_id)
     context = {"client_id": client_id, "broadcast_channel_key": _GetBroadcastChannelKey(), "token": token}
     template = jinja_environment.get_template("templates/index.html")
     self.response.out.write(template.render(context))
Example #6
0
  def get(self):
    template = jinja_environment.get_template('templates/index.html')

    # This is the low-level App Engine Channel API client_id, and should
    # be unique for each individual JavaScript client.
    # https://developers.google.com/appengine/docs/python/channel/functions
    user = users.get_current_user()
    client_id = hashlib.md5(user.email + os.environ['REQUEST_ID_HASH'])
    client_id = client_id.hexdigest()
    token = channel.create_channel(client_id)
    context = {
        'client_id': client_id,
        'token': token,
    }
    self.response.out.write(template.render(context))
Example #7
0
    def get(self):
        template = jinja_environment.get_template('templates/index.html')

        # This is the low-level App Engine Channel API client_id, and should
        # be unique for each individual JavaScript client.
        # https://developers.google.com/appengine/docs/python/channel/functions
        user = users.get_current_user()
        client_id = hashlib.md5(user.email + os.environ['REQUEST_ID_HASH'])
        client_id = client_id.hexdigest()
        token = channel.create_channel(client_id)
        context = {
            'client_id': client_id,
            'token': token,
        }
        self.response.out.write(template.render(context))
Example #8
0
  def testTaskManager(self):
    task_manager = tasks.TaskManager.new(
        group='group',
        description='desc',
        broadcast_channel_key='broadcast')

    self.assertEqual('group', task_manager.group)
    self.assertEqual('desc', task_manager.description)
    self.assertEqual('broadcast', task_manager._broadcast_channel.key)
    self.assertFalse(task_manager._finalized)
    self.assertTrue(task_manager.exists)
    token = channel.create_channel('foo')
    task_manager.subscribe('foo')
    self.channel_stub.connect_channel(token)

    self.assertRaises(
        tasks.TaskManagerNotFinalizedError, lambda: task_manager.status)

    # Get a new task manager from the key, like a new request would.
    task_manager = tasks.TaskManager(key=task_manager.key, group='group')

    # First task fails.
    task_manager.defer_task('key0', BadCallback)
    self.assertEqual(1, len(self.channel_stub.get_channel_messages(token)))
    # 10 tasks succeed.
    for i in range(1, 11):
      task_manager.defer_task('key%s' % i, GoodCallback, i)

    # Can't add a task with the same key.
    self.assertRaises(
        tasks.DuplicateTaskError,
        lambda: task_manager.defer_task('key0', lambda: None))
    task_manager.finalize()
    # Cannot add tasks after finalization.
    self.assertRaises(
        tasks.TaskManagerFinalizedError,
        lambda: task_manager.defer_task('foo', lambda: None))

    self.assertTrue(task_manager.exists)
    self.assertTrue(task_manager._finalized)
    self.assertRaises(tasks.InvalidTaskError, task_manager.get_task, 'fake-key')

    self.assertEqual(11, task_manager.num_total)
    self.assertEqual(0, task_manager.num_completed)
    self.assertEqual(0, task_manager.num_successful)
    self.assertEqual(0, task_manager.num_failed)
    self.assertEqual(0, len(task_manager.successful_tasks))
    self.assertEqual(0, len(task_manager.failed_tasks))
    self.assertEqual(tasks.STATUS_RUNNING, task_manager.status)
    self.assertEqual('*****@*****.**', task_manager.created_by.email)
    self.assertTrue(isinstance(task_manager.created, datetime.datetime))
    for task in task_manager.tasks:
      self.assertEqual(tasks.STATUS_RUNNING, task.status)
    # Verify number of broadcasted messages.
    self.assertEqual(11, len(self.channel_stub.get_channel_messages(token)))

    # Run three deferred tasks and re-check stats.
    try:
      self.RunDeferredTasks(runs=1)
    except tasks.TaskError:
      pass  # Expected for BadCallback().
    self.RunDeferredTasks(runs=2)

    # Get a new task manager from the key, like a new request would.
    task_manager = tasks.TaskManager(key=task_manager.key, group='group')
    # Ensure that the task_manager can be pickled and unpickled correctly.
    task_manager = pickle.loads(pickle.dumps(task_manager))
    # Cannot add tasks after finalization.
    self.assertRaises(
        tasks.TaskManagerFinalizedError,
        lambda: task_manager.defer_task('foo', lambda: None))
    self.assertEqual('group', task_manager.group)
    self.assertEqual('desc', task_manager.description)
    self.assertEqual('broadcast', task_manager._broadcast_channel.key)
    self.assertTrue(task_manager._finalized)
    self.assertTrue(task_manager.exists)

    self.assertEqual(11, task_manager.num_total)
    self.assertEqual(3, task_manager.num_completed)
    self.assertEqual(2, task_manager.num_successful)
    self.assertEqual(1, task_manager.num_failed)
    self.assertEqual(2, len(task_manager.successful_tasks))
    self.assertEqual(1, len(task_manager.failed_tasks))
    self.assertEqual(tasks.STATUS_RUNNING, task_manager.status)
    for task in task_manager.successful_tasks:
      self.assertEqual(task.status, tasks.STATUS_SUCCESSFUL)
    for task in task_manager.failed_tasks:
      self.assertEqual(task.status, tasks.STATUS_FAILED)
    # Verify number of broadcasted messages (11 queued + 2 per completed task).
    self.assertEqual(17, len(self.channel_stub.get_channel_messages(token)))

    # Run the rest of the deferred tasks and re-check stats.
    self.RunDeferredTasks()
    task_manager = tasks.TaskManager(key=task_manager.key, group='group')
    self.assertEqual(11, task_manager.num_total)
    self.assertEqual(11, task_manager.num_completed)
    self.assertEqual(10, task_manager.num_successful)
    self.assertEqual(1, task_manager.num_failed)
    self.assertEqual(10, len(task_manager.successful_tasks))
    self.assertEqual(1, len(task_manager.failed_tasks))
    self.assertEqual(tasks.STATUS_FAILED, task_manager.status)
    for task in task_manager.successful_tasks:
      self.assertEqual(task.status, tasks.STATUS_SUCCESSFUL)
    for task in task_manager.failed_tasks:
      self.assertEqual(task.status, tasks.STATUS_FAILED)
    # Verify number of broadcasted messages (11 queued + 2 per completed task).
    self.assertEqual(33, len(self.channel_stub.get_channel_messages(token)))

    failed_task = list(task_manager.failed_tasks)[0]
    self.assertEqual('key0', failed_task.key)
    self.assertEqual(
        'Task was too awesome to succeed.', failed_task.error_message)

    # Verify actual broadcasted messages.
    actual_messages = self.channel_stub.get_channel_messages(token)
    actual_messages = [json.loads(msg) for msg in actual_messages]
    for message in actual_messages:
      # Each channel message contains a JSON-encoded task message like this:
      # {
      #     u'message': u'{"status": "successful", "task_key": "key9",
      #         "task_manager_key": "53b642869769c75db38d384deff529e6"}'
      # }
      message = json.loads(message['message'])
      allowed_statuses = (
          tasks.STATUS_QUEUED,
          tasks.STATUS_RUNNING,
          tasks.STATUS_SUCCESSFUL,
          tasks.STATUS_FAILED,
      )
      self.assertIn(message['status'], allowed_statuses)
      self.assertIn('task_manager_key', message)
      self.assertTrue(message['task_key'].startswith('key'))
      if message['status'] == tasks.STATUS_FAILED:
        self.assertEqual('Task was too awesome to succeed.', message['error'])
      else:
        self.assertNotIn('error', message)

    # Verify group is part of what uniquely identifies a task manager.
    task_manager = tasks.TaskManager(key=task_manager.key, group='fake')
    self.assertFalse(task_manager.exists)
    # And verify that the filename is always the keyname.
    task_manager = tasks.TaskManager(key='key', group='group')
    self.assertEqual(
        '/_titan/tasks/group/key/tasks', task_manager._tasks_dir_path)

    # Error handling.
    self.assertRaises(
        ValueError, lambda: tasks.TaskManager.new(group='Invalid Group'))
    self.assertRaises(
        tasks.InvalidTaskManagerError,
        lambda: tasks.TaskManager('fake-key').defer_task('foo', lambda: None))
    self.assertFalse(tasks.TaskManager(key='fake').exists)