Commit 5e5d4803 authored by Jérome Perrin's avatar Jérome Perrin

grid: report summary of partitions processing/promises

Because it's sometimes hard to find out in the full output of slapos
node instance which partition failed, report a more concise summary at
the end.

/reviewed-on nexedi/slapos.core!134
parent 901ce265
......@@ -1253,6 +1253,9 @@ stderr_logfile_backups=1
computer_partition_list = self.FilterComputerPartitionList(
self.getComputerPartitionList())
process_error_partition_list = []
promise_error_partition_list = []
for computer_partition in computer_partition_list:
# Nothing should raise outside of the current loop iteration, so that
# even if something is terribly wrong while processing an instance, it
......@@ -1271,6 +1274,7 @@ stderr_logfile_backups=1
try:
self.logger.error(exc)
computer_partition.error(exc, logger=self.logger)
promise_error_partition_list.append((computer_partition, exc))
except (SystemExit, KeyboardInterrupt):
raise
except Exception:
......@@ -1284,12 +1288,30 @@ stderr_logfile_backups=1
self.logger.exception('')
try:
computer_partition.error(exc, logger=self.logger)
process_error_partition_list.append((computer_partition, exc))
except (SystemExit, KeyboardInterrupt):
raise
except Exception:
self.logger.exception('Problem while reporting error, continuing:')
def getPartitionType(part):
"""returns the partition type, if known at that point.
"""
try:
return part.getType()
except slapos.slap.ResourceNotReady:
return '(not ready)'
self.logger.info('Finished computer partitions.')
self.logger.info('=' * 80)
if process_error_partition_list:
self.logger.info('Error while processing the following partitions:')
for partition, exc in process_error_partition_list:
self.logger.info(' %s[%s]: %s', partition.getId(), getPartitionType(partition), exc)
if promise_error_partition_list:
self.logger.info('Error with promises for the following partitions:')
for partition, exc in promise_error_partition_list:
self.logger.info(' %s[%s]: %s', partition.getId(), getPartitionType(partition), exc)
# Return success value
if not clean_run:
......
......@@ -1643,6 +1643,45 @@ echo %s; echo %s; exit 42""" % (line1, line2))
self.assertIn(line2, instance.error_log)
self.assertIn('Failed to run buildout', instance.error_log)
def test_processing_summary(self):
"""At the end of instance processing, a summary of partition with errors is displayed.
"""
computer = ComputerForTest(self.software_root, self.instance_root, 3, 3)
_, instance1, instance2 = computer.instance_list
# instance0 has no problem, it is not in summary
# instance 1 fails software
instance1 = computer.instance_list[1]
instance1.software = computer.software_list[1]
instance1.software.setBuildout("""#!/bin/sh
echo fake buildout error
exit 1""")
# instance 2 fails promises
instance2 = computer.instance_list[2]
instance2.requested_state = 'started'
instance2.setPromise("failing_promise", """#!/bin/sh
echo fake promise error
exit 1""")
with httmock.HTTMock(computer.request_handler), \
patch.object(self.grid.logger, 'info',) as dummyLogger:
self.launchSlapgrid()
# reconstruct the string like logger does
self.assertEqual(
dummyLogger.mock_calls[-4][1][0] % dummyLogger.mock_calls[-4][1][1:],
'Error while processing the following partitions:')
self.assertRegexpMatches(
dummyLogger.mock_calls[-3][1][0] % dummyLogger.mock_calls[-3][1][1:],
r" 1\[\(not ready\)\]: Failed to run buildout profile in directory '.*/instance/1':\nfake buildout error\n\n")
self.assertEqual(
dummyLogger.mock_calls[-2][1][0] % dummyLogger.mock_calls[-2][1][1:],
'Error with promises for the following partitions:')
self.assertEqual(
dummyLogger.mock_calls[-1][1][0] % dummyLogger.mock_calls[-1][1][1:],
" 2[(not ready)]: Promise 'failing_promise' failed.")
class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment