Update tobiko shell package
Change-Id: I18d87d1763d5b501bd3694f79940d2b1ee441dd9
This commit is contained in:
parent
319803da4d
commit
2cde963248
@ -66,6 +66,7 @@ str_from_stream = _process.str_from_stream
|
||||
ShellProcessFixture = _process.ShellProcessFixture
|
||||
|
||||
PsError = _ps.PsError
|
||||
PsProcess = _ps.PsProcess
|
||||
PsWaitTimeout = _ps.PsWaitTimeout
|
||||
list_all_processes = _ps.list_all_processes
|
||||
list_kernel_processes = _ps.list_kernel_processes
|
||||
|
@ -85,13 +85,12 @@ class ShellReadable(ShellIOBase):
|
||||
def readable(self):
|
||||
return True
|
||||
|
||||
def read(self, size=None):
|
||||
def read(self, size: int = None) -> bytes:
|
||||
size = size or self.buffer_size
|
||||
try:
|
||||
chunk = self.delegate.read(size)
|
||||
except IOError:
|
||||
LOG.exception('Error reading from %r', self)
|
||||
chunk = None
|
||||
try:
|
||||
self.close()
|
||||
except Exception:
|
||||
@ -100,6 +99,8 @@ class ShellReadable(ShellIOBase):
|
||||
|
||||
if chunk:
|
||||
self._data_chunks.append(chunk)
|
||||
elif chunk is None:
|
||||
chunk = 'b'
|
||||
return chunk
|
||||
|
||||
@property
|
||||
|
@ -18,12 +18,20 @@ from __future__ import absolute_import
|
||||
import collections
|
||||
import re
|
||||
import time
|
||||
import typing
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
import tobiko
|
||||
from tobiko.shell.sh import _command
|
||||
from tobiko.shell.sh import _exception
|
||||
from tobiko.shell.sh import _execute
|
||||
from tobiko.shell.sh import _hostname
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class PsError(tobiko.TobikoException):
|
||||
message = "Unable to list processes from host: {error}"
|
||||
|
||||
@ -36,6 +44,9 @@ class PsWaitTimeout(PsError):
|
||||
IS_KERNEL_RE = re.compile('^\\[.*\\]$')
|
||||
|
||||
|
||||
_NOT_FOUND = object()
|
||||
|
||||
|
||||
class PsProcess(collections.namedtuple('PsProcess', ['ssh_client',
|
||||
'pid',
|
||||
'command'])):
|
||||
@ -46,6 +57,27 @@ class PsProcess(collections.namedtuple('PsProcess', ['ssh_client',
|
||||
def is_kernel(self):
|
||||
return IS_KERNEL_RE.match(self.command) is not None
|
||||
|
||||
@property
|
||||
def command_line(self) -> typing.Optional[_command.ShellCommand]:
|
||||
command_line = self.__dict__.get('_command_line', _NOT_FOUND)
|
||||
if command_line is _NOT_FOUND:
|
||||
command_line = None
|
||||
try:
|
||||
output = _execute.execute(f'cat /proc/{self.pid}/cmdline',
|
||||
ssh_client=self.ssh_client).stdout
|
||||
except _exception.ShellCommandFailed as ex:
|
||||
LOG.error(f"Unable to get process command line: {ex.stderr}")
|
||||
else:
|
||||
line = _command.ShellCommand(output.strip().split('\0')[:-1])
|
||||
if line[0] != self.command:
|
||||
LOG.error(f"Command line of process {self.pid} "
|
||||
"doesn't match its command "
|
||||
f"({self.command}): {line}")
|
||||
else:
|
||||
command_line = line
|
||||
self.__dict__['command_line'] = command_line
|
||||
return command_line
|
||||
|
||||
|
||||
def list_kernel_processes(**list_params):
|
||||
return list_processes(is_kernel=True, **list_params)
|
||||
@ -55,8 +87,12 @@ def list_all_processes(**list_params):
|
||||
return list_processes(is_kernel=None, **list_params)
|
||||
|
||||
|
||||
def list_processes(pid=None, command=None, is_kernel=False, ssh_client=None,
|
||||
**execute_params):
|
||||
def list_processes(pid=None,
|
||||
command: typing.Optional[str] = None,
|
||||
is_kernel=False,
|
||||
ssh_client=None,
|
||||
command_line: typing.Optional[str] = None,
|
||||
**execute_params) -> tobiko.Selection[PsProcess]:
|
||||
"""Returns the number of seconds passed since last host reboot
|
||||
|
||||
It reads and parses remote special file /proc/uptime and returns a floating
|
||||
@ -70,7 +106,7 @@ def list_processes(pid=None, command=None, is_kernel=False, ssh_client=None,
|
||||
raise PsError(error=result.stderr)
|
||||
|
||||
# Extract a list of PsProcess instances from table body
|
||||
processes = tobiko.Selection()
|
||||
processes = tobiko.Selection[PsProcess]()
|
||||
for process_data in parse_table(lines=output.splitlines(),
|
||||
schema=PS_TABLE_SCHEMA):
|
||||
processes.append(PsProcess(ssh_client=ssh_client, **process_data))
|
||||
@ -83,15 +119,24 @@ def list_processes(pid=None, command=None, is_kernel=False, ssh_client=None,
|
||||
|
||||
if processes and command is not None:
|
||||
# filter processes by command
|
||||
command = re.compile(command)
|
||||
processes = tobiko.select(process
|
||||
for process in processes
|
||||
if command.match(process.command))
|
||||
pattern = re.compile(command)
|
||||
processes = tobiko.Selection[PsProcess](
|
||||
process
|
||||
for process in processes
|
||||
if pattern.match(process.command))
|
||||
|
||||
if processes and is_kernel is not None:
|
||||
# filter kernel processes
|
||||
processes = processes.with_attributes(is_kernel=bool(is_kernel))
|
||||
|
||||
if processes and command_line is not None:
|
||||
pattern = re.compile(command_line)
|
||||
processes = tobiko.Selection[PsProcess](
|
||||
process
|
||||
for process in processes
|
||||
if (process.command_line is not None and
|
||||
pattern.match(f"{process.command_line}")))
|
||||
|
||||
return processes
|
||||
|
||||
|
||||
|
@ -31,6 +31,9 @@ ssh_command = _command.ssh_command
|
||||
ssh_proxy_client = _client.ssh_proxy_client
|
||||
SSHConnectFailure = _client.SSHConnectFailure
|
||||
gather_ssh_connect_parameters = _client.gather_ssh_connect_parameters
|
||||
SSHClientType = _client.SSHClientType
|
||||
ssh_client_fixture = _client.ssh_client_fixture
|
||||
|
||||
|
||||
reset_default_ssh_port_forward_manager = \
|
||||
_forward.reset_default_ssh_port_forward_manager
|
||||
|
@ -625,3 +625,17 @@ def check_ssh_connection(client):
|
||||
transport.send_ignore()
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
SSHClientType = typing.Union[None, bool, SSHClientFixture]
|
||||
|
||||
|
||||
def ssh_client_fixture(obj: SSHClientType) -> \
|
||||
typing.Optional[SSHClientFixture]:
|
||||
if obj is None:
|
||||
return ssh_proxy_client()
|
||||
if obj is False:
|
||||
return None
|
||||
if isinstance(obj, SSHClientFixture):
|
||||
return obj
|
||||
raise TypeError(f"Can't get an SSHClientFixture from objeck {obj}")
|
||||
|
@ -4,7 +4,7 @@
|
||||
name: tobiko-infrared
|
||||
parent: tox
|
||||
nodeset: tobiko-infrared-centos
|
||||
timeout: 1800
|
||||
timeout: 3600
|
||||
description: |
|
||||
Run test cases using tobiko infrared plugin
|
||||
pre-run: playbooks/infrared/pre.yaml
|
||||
|
Loading…
x
Reference in New Issue
Block a user