autotest: Include last line of log in rpc server failure.
This change makes it so that failures to start an xmlrpc server will
report some of the actual failure message, rather than just saying
"Connection Refused" or "BadStatusLine('')" or an empty string.
This should help figure out the failure reasons from a dashboard,
without digging into the logs every time.
Example (wrapped on spaces):
TestError: Failed to start XMLRPC server.
socket.error: [Errno 104] Connection reset by peer: 'localhost:34065'.
Log tail: 'bash: /usr/local/autotest/cros/faft/rpc_server.py:
/usr/bin/python2: bad interpreter: Permission denied'
BUG=chromium:1054617
TEST=Run a test with DUT python chmod -x, or with rpc_server.py altered to have a syntax error.
Change-Id: Ifb5e35ede336030a3151cfdc68dff5c766a457e3
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2105592
Tested-by: Dana Goyette <[email protected]>
Commit-Queue: Dana Goyette <[email protected]>
Reviewed-by: Greg Edelston <[email protected]>
diff --git a/server/hosts/rpc_server_tracker.py b/server/hosts/rpc_server_tracker.py
index 750781b..61dca8f 100644
--- a/server/hosts/rpc_server_tracker.py
+++ b/server/hosts/rpc_server_tracker.py
@@ -200,24 +200,45 @@
except socket.error as e:
e.filename = server_desc
raise
- successful = False
+
try:
logging.info('Waiting %d seconds for XMLRPC server '
'to start.', timeout_seconds)
ready_test()
- successful = True
- except socket.error as e:
- e.filename = rpc_url.replace('http://', '')
- raise
- finally:
- if not successful:
- logging.error('Failed to start XMLRPC server.')
- if logfile:
- with tempfile.NamedTemporaryFile() as temp:
- self._host.get_file(logfile, temp.name)
- logging.error('The log of XML RPC server:\n%s',
- open(temp.name).read())
+ except Exception as exc:
+ log_lines = []
+ if logfile:
+ logging.warn('Failed to start XMLRPC server; getting log.')
+ with tempfile.NamedTemporaryFile() as temp:
+ self._host.get_file(logfile, temp.name)
+ with open(temp.name) as f:
+ log_lines = f.read().rstrip().splitlines()
+ else:
+ logging.warn('Failed to start XMLRPC server; no log.')
+
+ fail_msg = 'Failed to start XMLRPC server. %s.%s: %s.' % (
+ type(exc).__module__, type(exc).__name__,
+ str(exc).rstrip('.'))
+ if log_lines:
+ fail_msg += ' Log tail: %r' % log_lines[-1]
+ if len(log_lines) > 1:
+ # The failure message includes only the last line,
+ # so report the whole thing separately.
+ logging.error('Full XMLRPC server log:\n%s',
+ '\n'.join(log_lines))
+
+ if isinstance(exc, (httplib.BadStatusLine, socket.error)):
+ # Ordinary failure: raise TestError with the failure info,
+ # and keep the verbose traceback at debug level.
+ logging.debug('Original exception:', exc_info=True)
self.disconnect(port)
+ raise error.TestError(fail_msg)
+ else:
+ # Unusual failure: keep the original exception,
+ # and report the failure info via logging.
+ logging.error('%s', fail_msg)
+ self.disconnect(port)
+ raise
logging.info('XMLRPC server started successfully.')
return proxy