|
|
|
@ -10,6 +10,7 @@ import mock
|
|
|
|
|
import unittest2
|
|
|
|
|
|
|
|
|
|
import mitogen.parent
|
|
|
|
|
from mitogen.core import b
|
|
|
|
|
|
|
|
|
|
import testlib
|
|
|
|
|
|
|
|
|
@ -36,20 +37,18 @@ def run_fd_check(func, fd, mode, on_start=None):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def close_proc(proc):
|
|
|
|
|
proc.receive_side.close()
|
|
|
|
|
proc.transmit_side.close()
|
|
|
|
|
if proc.diag_receive_side:
|
|
|
|
|
proc.diag_receive_side.close()
|
|
|
|
|
if proc.diag_transmit_side:
|
|
|
|
|
proc.diag_transmit_side.close()
|
|
|
|
|
proc.stdin.close()
|
|
|
|
|
proc.stdout.close()
|
|
|
|
|
if proc.stderr:
|
|
|
|
|
prco.stderr.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def wait_read(side, n):
|
|
|
|
|
def wait_read(fp, n):
|
|
|
|
|
poller = mitogen.core.Poller()
|
|
|
|
|
try:
|
|
|
|
|
poller.start_receive(side.fd)
|
|
|
|
|
poller.start_receive(fp.fileno())
|
|
|
|
|
for _ in poller.poll():
|
|
|
|
|
return side.read(n)
|
|
|
|
|
return os.read(fp.fileno(), n)
|
|
|
|
|
assert False
|
|
|
|
|
finally:
|
|
|
|
|
poller.close()
|
|
|
|
@ -58,12 +57,12 @@ def wait_read(side, n):
|
|
|
|
|
class StdinSockMixin(object):
|
|
|
|
|
def test_stdin(self):
|
|
|
|
|
proc, info, _ = run_fd_check(self.func, 0, 'read',
|
|
|
|
|
lambda proc: proc.transmit_side.write('TEST'))
|
|
|
|
|
st = os.fstat(proc.transmit_side.fd)
|
|
|
|
|
lambda proc: proc.stdin.send(b('TEST')))
|
|
|
|
|
st = os.fstat(proc.stdin.fileno())
|
|
|
|
|
self.assertTrue(stat.S_ISSOCK(st.st_mode))
|
|
|
|
|
self.assertEquals(st.st_dev, info['st_dev'])
|
|
|
|
|
self.assertEquals(st.st_mode, info['st_mode'])
|
|
|
|
|
flags = fcntl.fcntl(proc.transmit_side.fd, fcntl.F_GETFL)
|
|
|
|
|
flags = fcntl.fcntl(proc.stdin.fileno(), fcntl.F_GETFL)
|
|
|
|
|
self.assertTrue(flags & os.O_RDWR)
|
|
|
|
|
self.assertTrue(info['buf'], 'TEST')
|
|
|
|
|
self.assertTrue(info['flags'] & os.O_RDWR)
|
|
|
|
@ -72,12 +71,12 @@ class StdinSockMixin(object):
|
|
|
|
|
class StdoutSockMixin(object):
|
|
|
|
|
def test_stdout(self):
|
|
|
|
|
proc, info, buf = run_fd_check(self.func, 1, 'write',
|
|
|
|
|
lambda proc: wait_read(proc.receive_side, 4))
|
|
|
|
|
st = os.fstat(proc.transmit_side.fd)
|
|
|
|
|
lambda proc: wait_read(proc.stdout, 4))
|
|
|
|
|
st = os.fstat(proc.stdout.fileno())
|
|
|
|
|
self.assertTrue(stat.S_ISSOCK(st.st_mode))
|
|
|
|
|
self.assertEquals(st.st_dev, info['st_dev'])
|
|
|
|
|
self.assertEquals(st.st_mode, info['st_mode'])
|
|
|
|
|
flags = fcntl.fcntl(proc.receive_side.fd, fcntl.F_GETFL)
|
|
|
|
|
flags = fcntl.fcntl(proc.stdout.fileno(), fcntl.F_GETFL)
|
|
|
|
|
self.assertTrue(flags & os.O_RDWR)
|
|
|
|
|
self.assertTrue(buf, 'TEST')
|
|
|
|
|
self.assertTrue(info['flags'] & os.O_RDWR)
|
|
|
|
@ -94,35 +93,42 @@ class CreateChildTest(StdinSockMixin, StdoutSockMixin, testlib.TestCase):
|
|
|
|
|
self.assertEquals(st.st_ino, info['st_ino'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MergedCreateChildTest(StdinSockMixin, StdoutSockMixin,
|
|
|
|
|
class CreateChildMergedTest(StdinSockMixin, StdoutSockMixin,
|
|
|
|
|
testlib.TestCase):
|
|
|
|
|
func = staticmethod(mitogen.parent.merged_create_child)
|
|
|
|
|
def func(self, *args, **kwargs):
|
|
|
|
|
return mitogen.parent.create_child(
|
|
|
|
|
*args, merge_stdio=True, **kwargs
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def test_stderr(self):
|
|
|
|
|
proc, info, buf = run_fd_check(self.func, 2, 'write',
|
|
|
|
|
lambda proc: wait_read(proc.receive_side, 4))
|
|
|
|
|
st = os.fstat(proc.transmit_side.fd)
|
|
|
|
|
lambda proc: wait_read(proc.stdout, 4))
|
|
|
|
|
self.assertEquals(None, proc.stderr)
|
|
|
|
|
st = os.fstat(proc.stdout.fileno())
|
|
|
|
|
self.assertTrue(stat.S_ISSOCK(st.st_mode))
|
|
|
|
|
self.assertEquals(st.st_dev, info['st_dev'])
|
|
|
|
|
self.assertEquals(st.st_mode, info['st_mode'])
|
|
|
|
|
flags = fcntl.fcntl(proc.receive_side.fd, fcntl.F_GETFL)
|
|
|
|
|
flags = fcntl.fcntl(proc.stdout.fileno(), fcntl.F_GETFL)
|
|
|
|
|
self.assertTrue(flags & os.O_RDWR)
|
|
|
|
|
self.assertTrue(buf, 'TEST')
|
|
|
|
|
self.assertTrue(info['flags'] & os.O_RDWR)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class StderrCreateChildTest(StdinSockMixin, StdoutSockMixin,
|
|
|
|
|
class CreateChildStderrPipeTest(StdinSockMixin, StdoutSockMixin,
|
|
|
|
|
testlib.TestCase):
|
|
|
|
|
func = staticmethod(mitogen.parent.stderr_create_child)
|
|
|
|
|
def func(self, *args, **kwargs):
|
|
|
|
|
return mitogen.parent.create_child(
|
|
|
|
|
*args, stderr_pipe=True, **kwargs
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def test_stderr(self):
|
|
|
|
|
proc, info, buf = run_fd_check(self.func, 2, 'write',
|
|
|
|
|
lambda proc: wait_read(proc.diag_receive_side, 4))
|
|
|
|
|
st = os.fstat(proc.diag_receive_side.fd)
|
|
|
|
|
lambda proc: wait_read(proc.stderr, 4))
|
|
|
|
|
st = os.fstat(proc.stderr.fileno())
|
|
|
|
|
self.assertTrue(stat.S_ISFIFO(st.st_mode))
|
|
|
|
|
self.assertEquals(st.st_dev, info['st_dev'])
|
|
|
|
|
self.assertEquals(st.st_mode, info['st_mode'])
|
|
|
|
|
flags = fcntl.fcntl(proc.diag_receive_side.fd, fcntl.F_GETFL)
|
|
|
|
|
flags = fcntl.fcntl(proc.stderr.fileno(), fcntl.F_GETFL)
|
|
|
|
|
self.assertFalse(flags & os.O_WRONLY)
|
|
|
|
|
self.assertFalse(flags & os.O_RDWR)
|
|
|
|
|
self.assertTrue(buf, 'TEST')
|
|
|
|
@ -134,16 +140,16 @@ class TtyCreateChildTest(testlib.TestCase):
|
|
|
|
|
|
|
|
|
|
def test_stdin(self):
|
|
|
|
|
proc, info, _ = run_fd_check(self.func, 0, 'read',
|
|
|
|
|
lambda proc: proc.transmit_side.write('TEST'))
|
|
|
|
|
st = os.fstat(proc.transmit_side.fd)
|
|
|
|
|
lambda proc: proc.stdin.write(b('TEST')))
|
|
|
|
|
st = os.fstat(proc.stdin.fileno())
|
|
|
|
|
self.assertTrue(stat.S_ISCHR(st.st_mode))
|
|
|
|
|
self.assertTrue(stat.S_ISCHR(info['st_mode']))
|
|
|
|
|
|
|
|
|
|
self.assertTrue(isinstance(info['ttyname'],
|
|
|
|
|
mitogen.core.UnicodeType))
|
|
|
|
|
os.ttyname(proc.transmit_side.fd) # crashes if wrong
|
|
|
|
|
os.ttyname(proc.stdin.fileno()) # crashes if not TTY
|
|
|
|
|
|
|
|
|
|
flags = fcntl.fcntl(proc.transmit_side.fd, fcntl.F_GETFL)
|
|
|
|
|
flags = fcntl.fcntl(proc.stdin.fileno(), fcntl.F_GETFL)
|
|
|
|
|
self.assertTrue(flags & os.O_RDWR)
|
|
|
|
|
self.assertTrue(info['flags'] & os.O_RDWR)
|
|
|
|
|
|
|
|
|
@ -152,17 +158,17 @@ class TtyCreateChildTest(testlib.TestCase):
|
|
|
|
|
|
|
|
|
|
def test_stdout(self):
|
|
|
|
|
proc, info, buf = run_fd_check(self.func, 1, 'write',
|
|
|
|
|
lambda proc: wait_read(proc.receive_side, 4))
|
|
|
|
|
lambda proc: wait_read(proc.stdout, 4))
|
|
|
|
|
|
|
|
|
|
st = os.fstat(proc.receive_side.fd)
|
|
|
|
|
st = os.fstat(proc.stdout.fileno())
|
|
|
|
|
self.assertTrue(stat.S_ISCHR(st.st_mode))
|
|
|
|
|
self.assertTrue(stat.S_ISCHR(info['st_mode']))
|
|
|
|
|
|
|
|
|
|
self.assertTrue(isinstance(info['ttyname'],
|
|
|
|
|
mitogen.core.UnicodeType))
|
|
|
|
|
os.ttyname(proc.transmit_side.fd) # crashes if wrong
|
|
|
|
|
os.ttyname(proc.stdout.fileno()) # crashes if wrong
|
|
|
|
|
|
|
|
|
|
flags = fcntl.fcntl(proc.receive_side.fd, fcntl.F_GETFL)
|
|
|
|
|
flags = fcntl.fcntl(proc.stdout.fileno(), fcntl.F_GETFL)
|
|
|
|
|
self.assertTrue(flags & os.O_RDWR)
|
|
|
|
|
self.assertTrue(info['flags'] & os.O_RDWR)
|
|
|
|
|
|
|
|
|
@ -172,17 +178,17 @@ class TtyCreateChildTest(testlib.TestCase):
|
|
|
|
|
|
|
|
|
|
def test_stderr(self):
|
|
|
|
|
proc, info, buf = run_fd_check(self.func, 2, 'write',
|
|
|
|
|
lambda proc: wait_read(proc.receive_side, 4))
|
|
|
|
|
lambda proc: wait_read(proc.stdout, 4))
|
|
|
|
|
|
|
|
|
|
st = os.fstat(proc.receive_side.fd)
|
|
|
|
|
st = os.fstat(proc.stdout.fileno())
|
|
|
|
|
self.assertTrue(stat.S_ISCHR(st.st_mode))
|
|
|
|
|
self.assertTrue(stat.S_ISCHR(info['st_mode']))
|
|
|
|
|
|
|
|
|
|
self.assertTrue(isinstance(info['ttyname'],
|
|
|
|
|
mitogen.core.UnicodeType))
|
|
|
|
|
os.ttyname(proc.transmit_side.fd) # crashes if wrong
|
|
|
|
|
os.ttyname(proc.stdin.fileno()) # crashes if not TTY
|
|
|
|
|
|
|
|
|
|
flags = fcntl.fcntl(proc.receive_side.fd, fcntl.F_GETFL)
|
|
|
|
|
flags = fcntl.fcntl(proc.stdout.fileno(), fcntl.F_GETFL)
|
|
|
|
|
self.assertTrue(flags & os.O_RDWR)
|
|
|
|
|
self.assertTrue(info['flags'] & os.O_RDWR)
|
|
|
|
|
|
|
|
|
@ -206,17 +212,18 @@ class TtyCreateChildTest(testlib.TestCase):
|
|
|
|
|
'bash', '-c', 'exec 2>%s; echo hi > /dev/tty' % (tf.name,)
|
|
|
|
|
])
|
|
|
|
|
deadline = time.time() + 5.0
|
|
|
|
|
mitogen.core.set_block(proc.receive_side.fd)
|
|
|
|
|
self.assertEquals(mitogen.core.b('hi\n'), proc.receive_side.read())
|
|
|
|
|
self.assertEquals(mitogen.core.b('hi\n'), wait_read(proc.stdout, 3))
|
|
|
|
|
waited_pid, status = os.waitpid(proc.pid, 0)
|
|
|
|
|
self.assertEquals(proc.pid, waited_pid)
|
|
|
|
|
self.assertEquals(0, status)
|
|
|
|
|
self.assertEquals(mitogen.core.b(''), tf.read())
|
|
|
|
|
proc.receive_side.close()
|
|
|
|
|
proc.stdout.close()
|
|
|
|
|
finally:
|
|
|
|
|
tf.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if 0:
|
|
|
|
|
|
|
|
|
|
class StderrDiagTtyMixin(object):
|
|
|
|
|
def test_stderr(self):
|
|
|
|
|
proc, info, buf = run_fd_check(self.func, 2, 'write',
|
|
|
|
|