Permalink
Browse files

sending error report events with buffered stderr output upon failure …

…of spawned process
  • Loading branch information...
1 parent 356a20b commit a6f96e1f618c11f88841c87ce8820b4e2d2eda2e @mriehl mriehl committed Mar 19, 2013
@@ -39,7 +39,14 @@
TYPE_REQUEST = 'request'
TYPE_SERVICE_CHANGE = 'service-change'
TYPE_HEARTBEAT = 'heartbeat'
-KNOWN_EVENT_TYPES = [TYPE_COMMAND, TYPE_FULL_UPDATE, TYPE_REQUEST, TYPE_SERVICE_CHANGE, TYPE_HEARTBEAT]
+TYPE_ERROR_REPORT = 'error-report'
+
+KNOWN_EVENT_TYPES = [TYPE_COMMAND,
+ TYPE_FULL_UPDATE,
+ TYPE_REQUEST,
+ TYPE_SERVICE_CHANGE,
+ TYPE_HEARTBEAT,
+ TYPE_ERROR_REPORT]
class IncompleteEventDataException(Exception):
@@ -157,6 +164,10 @@ def is_a_command(self):
def is_a_heartbeat(self):
return self.event_type == TYPE_HEARTBEAT
+ @property
+ def is_an_error_report(self):
+ return self.event_type == TYPE_ERROR_REPORT
+
def __str__(self):
if self.is_a_request:
return 'target[{0}] requested command "{1}" using arguments "{2}"'.format(self.target, self.command, self.arguments)
@@ -175,7 +186,10 @@ def __str__(self):
return '(broadcaster) target[{0}] command "{1}" {2}.'.format(self.target, self.command, self.state)
if self.is_a_heartbeat:
- return 'heartbeat'
+ return 'Heartbeat on {0}'.format(self.target)
+
+ if self.is_an_error_report:
+ return 'Error report on {0}'.format(self.target)
raise NotImplementedError('Unknown event type {0}'.format(self.event_type))
@@ -82,6 +82,6 @@ def errReceived(self, data):
self.error_buffer += str(data)
def _report_error_summary(self):
- log.err('Errors in executing {0} on {1}:'.format(self.readable_command, self.target))
+ log.msg('Reporting errors of execution of {0} on {1}.'.format(self.readable_command, self.target))
for error_line in self.error_buffer.split('\n'):
- log.err(error_line)
+ self.broadcaster._sendEvent(events.TYPE_ERROR_REPORT, data=error_line, tracking_id=self.tracking_id)
@@ -82,11 +82,18 @@ def test_should_return_description_of_request(self):
def test_should_return_description_of_heartbeat(self):
event = Event('target-name', {'id': 'heartbeat',
'type': 'event',
- 'target': 'dev12',
+ 'target': 'target-name',
'tracking_id': None,
'payload': None})
+ self.assertEqual('Heartbeat on target-name', str(event))
- self.assertEqual('heartbeat', str(event))
+ def test_should_return_description_of_error_report(self):
+ event = Event('target-name', {'id': 'error-report',
+ 'type': 'event',
+ 'target': 'target-name',
+ 'tracking_id': None,
+ 'payload': None})
+ self.assertEqual('Error report on target-name', str(event))
def test_should_return_description_of_full_update(self):
event = Event('target-name', {'id': 'full-update'})
@@ -92,10 +92,23 @@ def test_should_accumulate_error_output(self, mock_log):
protocol.errReceived('foo\nbar')
protocol.errReceived('baz')
- protocol._report_error_summary()
+ self.assertEqual('foo\nbarbaz', protocol.error_buffer)
- self.assertEqual([call('Errors in executing /usr/bin/python abc 123 on devabc123:'),
- call('foo'),
- call('barbaz')],
- mock_log.err.call_args_list)
+ @patch('yadtreceiver.protocols.log')
+ def test_should_send_error_reports_upon_failure(self, mock_log):
+ mock_protocol = Mock(ProcessProtocol)
+ mock_broadcaster = Mock()
+ mock_protocol.broadcaster = mock_broadcaster
+ mock_protocol.hostname = 'hostname'
+ mock_protocol.target = 'dev123'
+ mock_protocol.readable_command = '/usr/bin/python abc'
+ mock_protocol.tracking_id = 'tracking_id'
+ mock_protocol.error_buffer= 'foo\nbar\nbaz'
+
+ ProcessProtocol._report_error_summary(mock_protocol)
+
+ self.assertEqual([call('error-report', data='foo', tracking_id='tracking_id'),
+ call('error-report', data='bar', tracking_id='tracking_id'),
+ call('error-report', data='baz', tracking_id='tracking_id')],
+ mock_broadcaster._sendEvent.call_args_list)

0 comments on commit a6f96e1

Please sign in to comment.