def sign(authenticator, message): """ Sign the message using the specified validator. signed document: { message: <message>, signature: <signature> } :param authenticator: A message authenticator. :type authenticator: Authenticator :param message: A (signed) json encoded AMQP message. :rtype message: str """ if not authenticator: return message try: h = sha256() h.update(message) digest = h.hexdigest() signature = authenticator.sign(digest) signed = Document(message=message, signature=encode(signature)) message = signed.dump() except Exception, e: log.info(utf8(e)) log.debug(message, exc_info=True)
def test_unbind_succeeded_with_error_report(self, mock_task_objects, mock_unbind_failed, mock_date): task_id = 'task_1' consumer_id = 'consumer_1' repo_id = 'repo_1' dist_id = 'dist_1' call_context = { 'action': 'unbind', 'task_id': task_id, 'consumer_id': consumer_id, 'repo_id': repo_id, 'distributor_id': dist_id } mock_return_tasks = Mock() mock_task_objects.return_value = mock_return_tasks test_date = '2014-12-16T20:03:10Z' mock_date.return_value = test_date dispatch_report = dict(succeeded=False) result = Document(retval=dispatch_report) document = Document(routing=['A', 'B'], result=result, data=call_context) reply = Succeeded(document) handler = self.reply_handler() handler.succeeded(reply) # validate task updated mock_task_objects.assert_called_with(task_id=task_id) mock_return_tasks.update_one.assert_called_with( set__finish_time=test_date, set__state=constants.CALL_FINISHED_STATE, set__result=dispatch_report) # validate bind action updated mock_unbind_failed.assert_called_with(task_id, call_context)
def test_search(self, _find): _impl = Mock() plugin = Mock() plugin.Reader.return_value = _impl _find.return_value = plugin received = [(Mock(), Document(sn='1')), (Mock(), Document(sn='2')), (Mock(), Document(sn='3'))] # test url = TEST_URL node = Node('') sn = received[1][1].sn reader = Reader(node, url) reader.next = Mock(side_effect=received) document = reader.search(sn, timeout=10) # validation next_calls = reader.next.call_args_list self.assertEqual(len(next_calls), 2) self.assertEqual(document, received[1][1]) for call in next_calls: self.assertEqual(call[0][0], 10) self.assertTrue(received[0][0].ack.called) self.assertTrue(received[1][0].ack.called) self.assertFalse(received[2][0].ack.called)
def test_unbind_succeeded_with_error_report(self, mock_task_succeeded, mock_unbind_failed): task_id = 'task_1' consumer_id = 'consumer_1' repo_id = 'repo_1' dist_id = 'dist_1' call_context = { 'action': 'unbind', 'task_id': task_id, 'consumer_id': consumer_id, 'repo_id': repo_id, 'distributor_id': dist_id } dispatch_report = dict(succeeded=False) result = Document(retval=dispatch_report) document = Document(routing=['A', 'B'], result=result, any=call_context) reply = Succeeded(document) handler = self.reply_handler() handler.succeeded(reply) # validate task updated mock_task_succeeded.assert_called_with(task_id, dispatch_report) # validate bind action updated mock_unbind_failed.assert_called_with(task_id, call_context)
def sign(authenticator, message): """ Sign the message using the specified validator. signed document: { message: <message>, signature: <signature> } :param authenticator: A message authenticator. :type authenticator: Authenticator :param message: A (signed) json encoded AMQP message. :rtype message: str """ if not authenticator: return message try: h = sha256() h.update(message.encode(ENCODING)) digest = h.hexdigest() signature = authenticator.sign(digest) signed = Document(message=message, signature=encode(signature)) message = signed.dump() except Exception as e: log.info(str(e)) log.debug(message, exc_info=True) return message
def peal(message): """ Peal the incoming message. The message one of: - A signed document: { message: <message>, signature: <signature> } - A plain (unsigned) RMI request. Returns: - The document to be passed along. - The original (signed) AMQP message to be validated. - The signature. :param message: A json encoded AMQP message. :type message: str :return: tuple of: (document, original, signature) :rtype: tuple """ document = Document() document.load(message) signature = document.signature original = document.message if original: document = Document() document.load(original) else: original = message return document, original, signature
def load(json): """ Load the json document. Decoding errors are intentionally ignored. :param json: A json string. :type json: str :return: The loaded document. :rtype: Document """ document = Document() try: document.load(json) except (TypeError, ValueError): pass return document
def test_dump(self): document = Document( A=1, B=2, C=Document(a=1, b=2), D=dict(x=10, y=20), E=[1, Document(), dict()], F=10, G='howdy', H=True, ) s = document.dump() self.assertEqual( s, '{"A": 1, "B": 2, "C": {"a": 1, "b": 2}, "D": {"x": 10, "y": 20}, ' '"E": [1, {}, {}], "F": 10, "G": "howdy", "H": true}')
def test_unbind_rejected(self, mock_task_objects, mock_unbind_failed, mock_date): task_id = 'task_1' consumer_id = 'consumer_1' repo_id = 'repo_1' dist_id = 'dist_1' call_context = { 'action': 'unbind', 'task_id': task_id, 'consumer_id': consumer_id, 'repo_id': repo_id, 'distributor_id': dist_id } mock_return_tasks = Mock() mock_task_objects.return_value = mock_return_tasks test_date = '2014-12-16T20:03:10Z' mock_date.return_value = test_date document = Document(routing=['A', 'B'], status='rejected', data=call_context) reply = Rejected(document) handler = self.reply_handler() handler.rejected(reply) # validate task updated mock_task_objects.assert_called_with(task_id=task_id) mock_return_tasks.update_one.assert_called_with( set__finish_time=test_date, set__state=constants.CALL_ERROR_STATE) # validate bind action updated mock_unbind_failed.assert_called_with(task_id, call_context)
def test_unbind_failed(self, mock_task_failed, mock_unbind_failed): task_id = 'task_1' consumer_id = 'consumer_1' repo_id = 'repo_1' dist_id = 'dist_1' call_context = { 'action': 'unbind', 'task_id': task_id, 'consumer_id': consumer_id, 'repo_id': repo_id, 'distributor_id': dist_id } raised = dict(exval='Boom', xmodule='foo.py', xclass=ValueError, xstate={'trace': 'stack-trace'}, xargs=[]) document = Document(routing=['A', 'B'], result=raised, any=call_context) reply = Failed(document) handler = self.reply_handler() handler.failed(reply) # validate task updated mock_task_failed.assert_called_with(task_id, 'stack-trace') # validate bind action updated mock_unbind_failed.assert_called_with(task_id, call_context)
def test_agent_raised_exception(self, mock_task_objects, mock_date): task_id = 'task_1' consumer_id = 'consumer_1' repo_id = 'repo_1' dist_id = 'dist_1' traceback = 'stack-trace' call_context = { 'task_id': task_id, 'consumer_id': consumer_id, 'repo_id': repo_id, 'distributor_id': dist_id } raised = dict(exval='Boom', xmodule='foo.py', xclass=ValueError, xstate={'trace': traceback}, xargs=[]) mock_return_tasks = Mock() mock_task_objects.return_value = mock_return_tasks test_date = '2014-12-16T20:03:10Z' mock_date.return_value = test_date document = Document(routing=['A', 'B'], result=raised, data=call_context) reply = Failed(document) handler = self.reply_handler() handler.failed(reply) # validate task updated mock_task_objects.assert_called_with(task_id=task_id) mock_return_tasks.update_one.assert_called_with( set__finish_time=test_date, set__state=constants.CALL_ERROR_STATE, set__traceback=traceback)
def __init__(self, details=None, document=None): """ :param details: A detailed description. :type details: str :param document: The (optional) invalid document. :type document: Document """ DocumentError.__init__(self, self.CODE, self.DESCRIPTION, document or Document(), details)
def test_accepted(self, mock_task_accepted): task_id = 'task_1' call_context = {'task_id': task_id} document = Document(routing=['A', 'B'], any=call_context) reply = Accepted(document) handler = self.reply_handler() handler.accepted(reply) # validate task updated mock_task_accepted.assert_called_with(task_id)
def send(self, address, ttl=None, **body): """ Send a message. :param address: An AMQP address. :type address: str :param ttl: Time to Live (seconds) :type ttl: float :keyword body: document body. :return: The message serial number. :rtype: str :raise: ModelError """ sn = utf8(uuid4()) routing = (None, address) document = Document(sn=sn, version=VERSION, routing=routing) document += body unsigned = document.dump() signed = auth.sign(self.authenticator, unsigned) self._impl.send(address, signed, ttl) return sn
def test_progress_reported(self, mock_task_objects): task_id = 'task_1' call_context = {'task_id': task_id} progress_report = {'step': 'step-1'} test_task_documents = Mock() mock_task_objects.return_value = test_task_documents document = Document(routing=['A', 'B'], any=call_context, details=progress_report) reply = Progress(document) handler = self.reply_handler() handler.progress(reply) # validate task updated mock_task_objects.assert_called_with(task_id=task_id) test_task_documents.update_one.assert_called_with(set__progress_report=progress_report)
def test_progress_reported(self, mock_update_task_status): task_id = 'task_1' call_context = {'task_id': task_id} progress_report = {'step': 'step-1'} document = Document(routing=['A', 'B'], any=call_context, details=progress_report) reply = Progress(document) handler = self.reply_handler() handler.progress(reply) # validate task updated delta = {'progress_report': progress_report} mock_update_task_status.assert_called_with(task_id, delta)
def test_accepted(self, mock_task_objects): task_id = 'task_1' call_context = {'task_id': task_id} mock_returned_tasks = Mock() mock_task_objects.return_value = mock_returned_tasks document = Document(routing=['A', 'B'], data=call_context) reply = Accepted(document) handler = self.reply_handler() handler.accepted(reply) # validate task updated mock_task_objects.assert_called_once_with( task_id=task_id, state=constants.CALL_WAITING_STATE) mock_returned_tasks.update_one.assert_called_once_with( set__state=constants.CALL_ACCEPTED_STATE)
def test_invalid_version(self): expected = '1.0' found = '2.0' document = Document(version='1.0') details = 'expected:1.0, found:2.0' # test exception = VersionError(document, expected, found) # validation self.assertEqual(exception.code, VersionError.CODE) self.assertEqual(exception.args, ('%s : %s' % (VersionError.DESCRIPTION, details),)) self.assertEqual(exception.description, VersionError.DESCRIPTION) self.assertEqual(exception.document, document) self.assertEqual(exception.details, details) self.assertTrue(isinstance(exception, ModelError))
def test_rejected(self, mock_task_objects, mock_date): task_id = 'task_1' call_context = { 'task_id': task_id, } mock_return_tasks = Mock() mock_task_objects.return_value = mock_return_tasks test_date = '2014-12-16T20:03:10Z' mock_date.return_value = test_date document = Document(routing=['A', 'B'], data=call_context) reply = Rejected(document) handler = self.reply_handler() handler.rejected(reply) # validate task updated mock_task_objects.assert_called_with(task_id=task_id) mock_return_tasks.update_one.assert_called_with( set__finish_time=test_date, set__state=constants.CALL_ERROR_STATE)
def test_agent_succeeded(self, mock_task_succeeded): dispatch_report = dict(succeeded=True) task_id = 'task_1' consumer_id = 'consumer_1' repo_id = 'repo_1' dist_id = 'dist_1' call_context = { 'task_id': task_id, 'consumer_id': consumer_id, 'repo_id': repo_id, 'distributor_id': dist_id } result = dict(retval=dispatch_report) document = Document(routing=['A', 'B'], result=result, any=call_context) reply = Succeeded(document) handler = self.reply_handler() handler.succeeded(reply) # validate task updated mock_task_succeeded.assert_called_with(task_id, dispatch_report)
def test_unbind_rejected(self, mock_task_failed, mock_unbind_failed): task_id = 'task_1' consumer_id = 'consumer_1' repo_id = 'repo_1' dist_id = 'dist_1' call_context = { 'action': 'unbind', 'task_id': task_id, 'consumer_id': consumer_id, 'repo_id': repo_id, 'distributor_id': dist_id } document = Document(routing=['A', 'B'], status='rejected', any=call_context) reply = Rejected(document) handler = self.reply_handler() handler.rejected(reply) # validate task updated mock_task_failed.assert_called_with(task_id) # validate bind action updated mock_unbind_failed.assert_called_with(task_id, call_context)
def test_load(self): s = '{"A": 1}' document = Document() document.load(s) self.assertEqual(document.__dict__, {'A': 1})
def test_invalid(self): document = Document(version=VERSION + '.0') self.assertRaises(InvalidVersion, validate, document)
def test_valid(self): document = Document(version=VERSION) validate(document)