1
0
mirror of https://github.com/ARM-software/devlib.git synced 2025-09-23 12:21:54 +01:00

Target.execute(): Add .returncode and .output exception attributes

Add Target{Stable,Transient}CalledProcessError exceptions, with an
.returncode and .output attributes, raised by Target.execute(),
mirroring subprocess.CalledProcessError.

This is very useful in client code that uses "exit N" to signal an
abnormal condition, and then inspects the output to find out more.
This commit is contained in:
Douglas Raillard
2021-08-20 15:54:46 +01:00
committed by Marc Bonnici
parent ff57e785f8
commit 0c1878786b
5 changed files with 107 additions and 26 deletions

View File

@@ -40,7 +40,7 @@ try:
except ImportError:
from pipes import quote
from devlib.exception import TargetTransientError, TargetStableError, HostError
from devlib.exception import TargetTransientError, TargetStableError, HostError, TargetTransientCalledProcessError, TargetStableCalledProcessError
from devlib.utils.misc import check_output, which, ABI_MAP, redirect_streams, get_subprocess
from devlib.connection import ConnectionBase, AdbBackgroundCommand, PopenBackgroundCommand, PopenTransferManager
@@ -336,6 +336,14 @@ class AdbConnection(ConnectionBase):
try:
return adb_shell(self.device, command, timeout, check_exit_code,
as_root, adb_server=self.adb_server, su_cmd=self.su_cmd)
except subprocess.CalledProcessError as e:
cls = TargetTransientCalledProcessError if will_succeed else TargetStableCalledProcessError
raise cls(
e.returncode,
command,
e.output,
e.stderr,
)
except TargetStableError as e:
if will_succeed:
raise TargetTransientError(e)
@@ -559,10 +567,15 @@ def adb_shell(device, command, timeout=None, check_exit_code=False,
exit_code = exit_code.strip()
re_search = AM_START_ERROR.findall(output)
if exit_code.isdigit():
if int(exit_code):
message = ('Got exit code {}\nfrom target command: {}\n'
'OUTPUT: {}\nSTDERR: {}\n')
raise TargetStableError(message.format(exit_code, command, output, error))
exit_code = int(exit_code)
if exit_code:
raise subprocess.CalledProcessError(
exit_code,
command,
output,
error,
)
elif re_search:
message = 'Could not start activity; got the following:\n{}'
raise TargetStableError(message.format(re_search[0]))

View File

@@ -197,7 +197,7 @@ def check_subprocess_output(process, timeout=None, ignore=None, inputtext=None):
retcode = process.poll()
if retcode and ignore != 'all' and retcode not in ignore:
raise subprocess.CalledProcessError(retcode, process.args, output='\n'.join([output, error]))
raise subprocess.CalledProcessError(retcode, process.args, output, error)
return output, error

View File

@@ -52,7 +52,10 @@ from pexpect import EOF, TIMEOUT, spawn
# pylint: disable=redefined-builtin,wrong-import-position
from devlib.exception import (HostError, TargetStableError, TargetNotRespondingError,
TimeoutError, TargetTransientError)
TimeoutError, TargetTransientError,
TargetCalledProcessError,
TargetTransientCalledProcessError,
TargetStableCalledProcessError)
from devlib.utils.misc import (which, strip_bash_colors, check_output,
sanitize_cmd_template, memoized, redirect_streams)
from devlib.utils.types import boolean
@@ -524,6 +527,8 @@ class SshConnection(SshConnectionBase):
try:
with _handle_paramiko_exceptions(command):
exit_code, output = self._execute(command, timeout, as_root, strip_colors)
except TargetCalledProcessError:
raise
except TargetStableError as e:
if will_succeed:
raise TargetTransientError(e)
@@ -531,8 +536,13 @@ class SshConnection(SshConnectionBase):
raise
else:
if check_exit_code and exit_code:
message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'
raise TargetStableError(message.format(exit_code, command, output))
cls = TargetTransientCalledProcessError if will_succeed else TargetStableCalledProcessError
raise cls(
exit_code,
command,
output,
None,
)
return output
def background(self, command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, as_root=False):
@@ -843,16 +853,23 @@ class TelnetConnection(SshConnectionBase):
if check_exit_code:
try:
exit_code = int(exit_code_text)
if exit_code:
message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'
raise TargetStableError(message.format(exit_code, command, output))
except (ValueError, IndexError):
logger.warning(
raise ValueError(
'Could not get exit code for "{}",\ngot: "{}"'\
.format(command, exit_code_text))
if exit_code:
cls = TargetTransientCalledProcessError if will_succeed else TargetStableCalledProcessError
raise cls(
exit_code,
command,
output,
None,
)
return output
except EOF:
raise TargetNotRespondingError('Connection lost.')
except TargetCalledProcessError:
raise
except TargetStableError as e:
if will_succeed:
raise TargetTransientError(e)
@@ -1130,7 +1147,10 @@ class Gem5Connection(TelnetConnection):
try:
output = self._gem5_shell(command,
check_exit_code=check_exit_code,
as_root=as_root)
as_root=as_root,
will_succeed=will_succeed)
except TargetCalledProcessError:
raise
except TargetStableError as e:
if will_succeed:
raise TargetTransientError(e)
@@ -1364,7 +1384,7 @@ class Gem5Connection(TelnetConnection):
raise TargetStableError('Path to m5 binary on simulated system is not set!')
self._gem5_shell('{} {}'.format(self.m5_path, command))
def _gem5_shell(self, command, as_root=False, timeout=None, check_exit_code=True, sync=True): # pylint: disable=R0912
def _gem5_shell(self, command, as_root=False, timeout=None, check_exit_code=True, sync=True, will_succeed=False): # pylint: disable=R0912
"""
Execute a command in the gem5 shell
@@ -1429,11 +1449,17 @@ class Gem5Connection(TelnetConnection):
sync=False)
try:
exit_code = int(exit_code_text.split()[0])
if exit_code:
message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'
raise TargetStableError(message.format(exit_code, command, output))
except (ValueError, IndexError):
gem5_logger.warning('Could not get exit code for "{}",\ngot: "{}"'.format(command, exit_code_text))
raise ValueError('Could not get exit code for "{}",\ngot: "{}"'.format(command, exit_code_text))
else:
if exit_code:
cls = TragetTransientCalledProcessError if will_succeed else TargetStableCalledProcessError
raise cls(
exit_code,
command,
output,
None,
)
return output