ÿØÿà JFIF ` ` ÿþxØ
| Server IP : 109.234.164.53 / Your IP : 216.73.216.110 Web Server : Apache System : Linux cervelle.o2switch.net 4.18.0-553.32.1.lve.el8.x86_64 #1 SMP Thu Dec 19 13:14:03 UTC 2024 x86_64 User : computer3 ( 1098) PHP Version : 7.1.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /proc/thread-self/root/opt/alt/python37/lib/python3.7/site-packages/testfixtures/ |
Upload File : |
# Copyright (c) 2015 Simplistix Ltd
# See license.txt for license details.
from mock import Mock
from subprocess import Popen as Popen
from tempfile import TemporaryFile
from testfixtures.compat import basestring
from testfixtures.utils import extend_docstring
class MockPopen(object):
"""
A specialised mock for testing use of :class:`subprocess.Popen`.
An instance of this class can be used in place of the
:class:`subprocess.Popen` and is often inserted where it's needed using
:func:`mock.patch` or a :class:`Replacer`.
"""
default_command = None
def __init__(self):
self.commands = {}
self.mock = mock = Mock()
self.mock.Popen.side_effect = self.Popen
mock.Popen_instance = Mock(spec=Popen)
inst = mock.Popen.return_value = mock.Popen_instance
inst.communicate.side_effect = self.communicate
inst.wait.side_effect = self.wait
inst.send_signal.side_effect = self.send_signal
inst.terminate.side_effect = self.terminate
inst.kill.side_effect = self.kill
inst.poll.side_effect = self.poll
def set_command(self, command, stdout=b'', stderr=b'', returncode=0,
pid=1234, poll_count=3):
"""
Set the behaviour of this mock when it is used to simulate the
specified command.
:param command: A string representing the command to be simulated.
"""
self.commands[command] = (stdout, stderr, returncode, pid, poll_count)
def set_default(self, stdout=b'', stderr=b'', returncode=0,
pid=1234, poll_count=3):
"""
Set the behaviour of this mock when it is used to simulate commands
that have no explicit behavior specified using
:meth:`~MockPopen.set_command`.
"""
self.default_command = (stdout, stderr, returncode, pid, poll_count)
def __call__(self, *args, **kw):
return self.mock.Popen(*args, **kw)
def Popen(self, args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False, cwd=None,
env=None, universal_newlines=False,
startupinfo=None, creationflags=0):
if isinstance(args, basestring):
cmd = args
else:
cmd = ' '.join(args)
behaviour = self.commands.get(cmd, self.default_command)
if behaviour is None:
raise KeyError('Nothing specified for command %r' % cmd)
self.stdout, self.stderr, self.returncode, pid, poll = behaviour
self.poll_count = poll
for name in 'stdout', 'stderr':
f = TemporaryFile()
f.write(getattr(self, name))
f.flush()
f.seek(0)
setattr(self.mock.Popen_instance, name, f)
self.mock.Popen_instance.pid = pid
self.mock.Popen_instance.returncode = None
return self.mock.Popen_instance
def wait(self):
"Simulate calls to :meth:`subprocess.Popen.wait`"
self.mock.Popen_instance.returncode = self.returncode
return self.returncode
def communicate(self, input=None):
"Simulate calls to :meth:`subprocess.Popen.communicate`"
self.wait()
return self.stdout, self.stderr
def poll(self):
"Simulate calls to :meth:`subprocess.Popen.poll`"
while self.poll_count and self.mock.Popen_instance.returncode is None:
self.poll_count -= 1
return None
# This call to wait() is NOT how poll() behaves in reality.
# poll() NEVER sets the returncode.
# The returncode is *only* ever set by process completion.
# The following is an artifact of the fixture's implementation.
return self.wait()
# These are here to check parameter types
def send_signal(self, signal):
"Simulate calls to :meth:`subprocess.Popen.send_signal`"
pass
def terminate(self):
"Simulate calls to :meth:`subprocess.Popen.terminate`"
pass
def kill(self):
"Simulate calls to :meth:`subprocess.Popen.kill`"
pass
set_command_params = """
:param stdout:
A string representing the simulated content written by the process
to the stdout pipe.
:param stderr:
A string representing the simulated content written by the process
to the stderr pipe.
:param returncode:
An integer representing the return code of the simulated process.
:param pid:
An integer representing the process identifier of the simulated
process. This is useful if you have code the prints out the pids
of running processes.
:param poll_count:
Specifies the number of times :meth:`MockPopen.poll` can be
called before :attr:`MockPopen.returncode` is set and returned
by :meth:`MockPopen.poll`.
"""
# add the param docs, so we only have one copy of them!
extend_docstring(set_command_params,
[MockPopen.set_command, MockPopen.set_default])