asyncio: Refactor waitpid mocks. Patch by Anthony Baire.

This commit is contained in:
Guido van Rossum 2013-11-14 16:16:29 -08:00
parent 5eb4f59cd9
commit 91d2c5674a
1 changed files with 181 additions and 244 deletions

View File

@ -1,5 +1,6 @@
"""Tests for unix_events.py."""
import collections
import gc
import errno
import io
@ -705,8 +706,16 @@ class BaseChildWatcherTests(unittest.TestCase):
NotImplementedError, watcher._do_waitpid, f)
WaitPidMocks = collections.namedtuple("WaitPidMocks",
("waitpid",
"WIFEXITED",
"WIFSIGNALED",
"WEXITSTATUS",
"WTERMSIG",
))
class ChildWatcherTestsMixin:
instance = None
ignore_warnings = unittest.mock.patch.object(unix_events.logger, "warning")
@ -715,21 +724,12 @@ class ChildWatcherTestsMixin:
self.running = False
self.zombies = {}
assert ChildWatcherTestsMixin.instance is None
ChildWatcherTestsMixin.instance = self
with unittest.mock.patch.object(
self.loop, "add_signal_handler") as self.m_add_signal_handler:
self.watcher = self.create_watcher()
self.watcher.attach_loop(self.loop)
def cleanup():
ChildWatcherTestsMixin.instance = None
self.addCleanup(cleanup)
def waitpid(pid, flags):
self = ChildWatcherTestsMixin.instance
def waitpid(self, pid, flags):
if isinstance(self.watcher, unix_events.SafeChildWatcher) or pid != -1:
self.assertGreater(pid, 0)
try:
@ -747,33 +747,43 @@ class ChildWatcherTestsMixin:
def add_zombie(self, pid, returncode):
self.zombies[pid] = returncode + 32768
def WIFEXITED(status):
def WIFEXITED(self, status):
return status >= 32768
def WIFSIGNALED(status):
def WIFSIGNALED(self, status):
return 32700 < status < 32768
def WEXITSTATUS(status):
self = ChildWatcherTestsMixin.instance
self.assertTrue(type(self).WIFEXITED(status))
def WEXITSTATUS(self, status):
self.assertTrue(self.WIFEXITED(status))
return status - 32768
def WTERMSIG(status):
self = ChildWatcherTestsMixin.instance
self.assertTrue(type(self).WIFSIGNALED(status))
def WTERMSIG(self, status):
self.assertTrue(self.WIFSIGNALED(status))
return 32768 - status
def test_create_watcher(self):
self.m_add_signal_handler.assert_called_once_with(
signal.SIGCHLD, self.watcher._sig_chld)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld(self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED,
m_WEXITSTATUS, m_WTERMSIG):
def waitpid_mocks(func):
def wrapped_func(self):
def patch(target, wrapper):
return unittest.mock.patch(target, wraps=wrapper,
new_callable=unittest.mock.Mock)
with patch('os.WTERMSIG', self.WTERMSIG) as m_WTERMSIG, \
patch('os.WEXITSTATUS', self.WEXITSTATUS) as m_WEXITSTATUS, \
patch('os.WIFSIGNALED', self.WIFSIGNALED) as m_WIFSIGNALED, \
patch('os.WIFEXITED', self.WIFEXITED) as m_WIFEXITED, \
patch('os.waitpid', self.waitpid) as m_waitpid:
func(self, WaitPidMocks(m_waitpid,
m_WIFEXITED, m_WIFSIGNALED,
m_WEXITSTATUS, m_WTERMSIG,
))
return wrapped_func
@waitpid_mocks
def test_sigchld(self, m):
# register a child
callback = unittest.mock.Mock()
@ -782,33 +792,33 @@ class ChildWatcherTestsMixin:
self.watcher.add_child_handler(42, callback, 9, 10, 14)
self.assertFalse(callback.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# child is running
self.watcher._sig_chld()
self.assertFalse(callback.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# child terminates (returncode 12)
self.running = False
self.add_zombie(42, 12)
self.watcher._sig_chld()
self.assertTrue(m_WIFEXITED.called)
self.assertTrue(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertTrue(m.WIFEXITED.called)
self.assertTrue(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
callback.assert_called_once_with(42, 12, 9, 10, 14)
m_WIFSIGNALED.reset_mock()
m_WIFEXITED.reset_mock()
m_WEXITSTATUS.reset_mock()
m.WIFSIGNALED.reset_mock()
m.WIFEXITED.reset_mock()
m.WEXITSTATUS.reset_mock()
callback.reset_mock()
# ensure that the child is effectively reaped
@ -817,29 +827,24 @@ class ChildWatcherTestsMixin:
self.watcher._sig_chld()
self.assertFalse(callback.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WTERMSIG.called)
m_WIFSIGNALED.reset_mock()
m_WIFEXITED.reset_mock()
m_WEXITSTATUS.reset_mock()
m.WIFSIGNALED.reset_mock()
m.WIFEXITED.reset_mock()
m.WEXITSTATUS.reset_mock()
# sigchld called again
self.zombies.clear()
self.watcher._sig_chld()
self.assertFalse(callback.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld_two_children(self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED,
m_WEXITSTATUS, m_WTERMSIG):
@waitpid_mocks
def test_sigchld_two_children(self, m):
callback1 = unittest.mock.Mock()
callback2 = unittest.mock.Mock()
@ -850,10 +855,10 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# register child 2
with self.watcher:
@ -861,20 +866,20 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# childen are running
self.watcher._sig_chld()
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# child 1 terminates (signal 3)
self.add_zombie(43, -3)
@ -882,13 +887,13 @@ class ChildWatcherTestsMixin:
callback1.assert_called_once_with(43, -3, 7, 8)
self.assertFalse(callback2.called)
self.assertTrue(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertTrue(m_WTERMSIG.called)
self.assertTrue(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertTrue(m.WTERMSIG.called)
m_WIFSIGNALED.reset_mock()
m_WIFEXITED.reset_mock()
m_WTERMSIG.reset_mock()
m.WIFSIGNALED.reset_mock()
m.WIFEXITED.reset_mock()
m.WTERMSIG.reset_mock()
callback1.reset_mock()
# child 2 still running
@ -896,10 +901,10 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# child 2 terminates (code 108)
self.add_zombie(44, 108)
@ -908,13 +913,13 @@ class ChildWatcherTestsMixin:
callback2.assert_called_once_with(44, 108, 147, 18)
self.assertFalse(callback1.called)
self.assertTrue(m_WIFEXITED.called)
self.assertTrue(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertTrue(m.WIFEXITED.called)
self.assertTrue(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
m_WIFSIGNALED.reset_mock()
m_WIFEXITED.reset_mock()
m_WEXITSTATUS.reset_mock()
m.WIFSIGNALED.reset_mock()
m.WIFEXITED.reset_mock()
m.WEXITSTATUS.reset_mock()
callback2.reset_mock()
# ensure that the children are effectively reaped
@ -925,11 +930,11 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WTERMSIG.called)
m_WIFSIGNALED.reset_mock()
m_WIFEXITED.reset_mock()
m_WEXITSTATUS.reset_mock()
m.WIFSIGNALED.reset_mock()
m.WIFEXITED.reset_mock()
m.WEXITSTATUS.reset_mock()
# sigchld called again
self.zombies.clear()
@ -937,19 +942,13 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld_two_children_terminating_together(
self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED, m_WEXITSTATUS,
m_WTERMSIG):
@waitpid_mocks
def test_sigchld_two_children_terminating_together(self, m):
callback1 = unittest.mock.Mock()
callback2 = unittest.mock.Mock()
@ -960,10 +959,10 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# register child 2
with self.watcher:
@ -971,20 +970,20 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# childen are running
self.watcher._sig_chld()
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# child 1 terminates (code 78)
# child 2 terminates (signal 5)
@ -995,15 +994,15 @@ class ChildWatcherTestsMixin:
callback1.assert_called_once_with(45, 78, 17, 8)
callback2.assert_called_once_with(46, -5, 1147, 18)
self.assertTrue(m_WIFSIGNALED.called)
self.assertTrue(m_WIFEXITED.called)
self.assertTrue(m_WEXITSTATUS.called)
self.assertTrue(m_WTERMSIG.called)
self.assertTrue(m.WIFSIGNALED.called)
self.assertTrue(m.WIFEXITED.called)
self.assertTrue(m.WEXITSTATUS.called)
self.assertTrue(m.WTERMSIG.called)
m_WIFSIGNALED.reset_mock()
m_WIFEXITED.reset_mock()
m_WTERMSIG.reset_mock()
m_WEXITSTATUS.reset_mock()
m.WIFSIGNALED.reset_mock()
m.WIFEXITED.reset_mock()
m.WTERMSIG.reset_mock()
m.WEXITSTATUS.reset_mock()
callback1.reset_mock()
callback2.reset_mock()
@ -1015,16 +1014,10 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WTERMSIG.called)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld_race_condition(
self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED, m_WEXITSTATUS,
m_WTERMSIG):
@waitpid_mocks
def test_sigchld_race_condition(self, m):
# register a child
callback = unittest.mock.Mock()
@ -1045,14 +1038,8 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback.called)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld_replace_handler(
self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED, m_WEXITSTATUS,
m_WTERMSIG):
@waitpid_mocks
def test_sigchld_replace_handler(self, m):
callback1 = unittest.mock.Mock()
callback2 = unittest.mock.Mock()
@ -1063,10 +1050,10 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# register the same child again
with self.watcher:
@ -1074,10 +1061,10 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# child terminates (signal 8)
self.running = False
@ -1086,13 +1073,13 @@ class ChildWatcherTestsMixin:
callback2.assert_called_once_with(51, -8, 21)
self.assertFalse(callback1.called)
self.assertTrue(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertTrue(m_WTERMSIG.called)
self.assertTrue(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertTrue(m.WTERMSIG.called)
m_WIFSIGNALED.reset_mock()
m_WIFEXITED.reset_mock()
m_WTERMSIG.reset_mock()
m.WIFSIGNALED.reset_mock()
m.WIFEXITED.reset_mock()
m.WTERMSIG.reset_mock()
callback2.reset_mock()
# ensure that the child is effectively reaped
@ -1102,15 +1089,10 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback1.called)
self.assertFalse(callback2.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WTERMSIG.called)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld_remove_handler(self, m_waitpid, m_WIFEXITED,
m_WIFSIGNALED, m_WEXITSTATUS, m_WTERMSIG):
@waitpid_mocks
def test_sigchld_remove_handler(self, m):
callback = unittest.mock.Mock()
# register a child
@ -1119,19 +1101,19 @@ class ChildWatcherTestsMixin:
self.watcher.add_child_handler(52, callback, 1984)
self.assertFalse(callback.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# unregister the child
self.watcher.remove_child_handler(52)
self.assertFalse(callback.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# child terminates (code 99)
self.running = False
@ -1141,13 +1123,8 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback.called)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld_unknown_status(self, m_waitpid, m_WIFEXITED,
m_WIFSIGNALED, m_WEXITSTATUS, m_WTERMSIG):
@waitpid_mocks
def test_sigchld_unknown_status(self, m):
callback = unittest.mock.Mock()
# register a child
@ -1156,10 +1133,10 @@ class ChildWatcherTestsMixin:
self.watcher.add_child_handler(53, callback, -19)
self.assertFalse(callback.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# terminate with unknown status
self.zombies[53] = 1178
@ -1167,14 +1144,14 @@ class ChildWatcherTestsMixin:
self.watcher._sig_chld()
callback.assert_called_once_with(53, 1178, -19)
self.assertTrue(m_WIFEXITED.called)
self.assertTrue(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertTrue(m.WIFEXITED.called)
self.assertTrue(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
callback.reset_mock()
m_WIFEXITED.reset_mock()
m_WIFSIGNALED.reset_mock()
m.WIFEXITED.reset_mock()
m.WIFSIGNALED.reset_mock()
# ensure that the child is effectively reaped
self.add_zombie(53, 101)
@ -1183,13 +1160,8 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback.called)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_remove_child_handler(self, m_waitpid, m_WIFEXITED,
m_WIFSIGNALED, m_WEXITSTATUS, m_WTERMSIG):
@waitpid_mocks
def test_remove_child_handler(self, m):
callback1 = unittest.mock.Mock()
callback2 = unittest.mock.Mock()
callback3 = unittest.mock.Mock()
@ -1221,8 +1193,8 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback2.called)
callback3.assert_called_once_with(56, 2, 3)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld_unhandled_exception(self, m_waitpid):
@waitpid_mocks
def test_sigchld_unhandled_exception(self, m):
callback = unittest.mock.Mock()
# register a child
@ -1231,7 +1203,7 @@ class ChildWatcherTestsMixin:
self.watcher.add_child_handler(57, callback)
# raise an exception
m_waitpid.side_effect = ValueError
m.waitpid.side_effect = ValueError
with unittest.mock.patch.object(unix_events.logger,
"exception") as m_exception:
@ -1239,15 +1211,8 @@ class ChildWatcherTestsMixin:
self.assertEqual(self.watcher._sig_chld(), None)
self.assertTrue(m_exception.called)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld_child_reaped_elsewhere(
self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED, m_WEXITSTATUS,
m_WTERMSIG):
@waitpid_mocks
def test_sigchld_child_reaped_elsewhere(self, m):
# register a child
callback = unittest.mock.Mock()
@ -1256,10 +1221,10 @@ class ChildWatcherTestsMixin:
self.watcher.add_child_handler(58, callback)
self.assertFalse(callback.called)
self.assertFalse(m_WIFEXITED.called)
self.assertFalse(m_WIFSIGNALED.called)
self.assertFalse(m_WEXITSTATUS.called)
self.assertFalse(m_WTERMSIG.called)
self.assertFalse(m.WIFEXITED.called)
self.assertFalse(m.WIFSIGNALED.called)
self.assertFalse(m.WEXITSTATUS.called)
self.assertFalse(m.WTERMSIG.called)
# child terminates
self.running = False
@ -1268,13 +1233,13 @@ class ChildWatcherTestsMixin:
# waitpid is called elsewhere
os.waitpid(58, os.WNOHANG)
m_waitpid.reset_mock()
m.waitpid.reset_mock()
# sigchld
with self.ignore_warnings:
self.watcher._sig_chld()
callback.assert_called(m_waitpid)
callback.assert_called(m.waitpid)
if isinstance(self.watcher, unix_events.FastChildWatcher):
# here the FastChildWatche enters a deadlock
# (there is no way to prevent it)
@ -1282,15 +1247,8 @@ class ChildWatcherTestsMixin:
else:
callback.assert_called_once_with(58, 255)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_sigchld_unknown_pid_during_registration(
self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED, m_WEXITSTATUS,
m_WTERMSIG):
@waitpid_mocks
def test_sigchld_unknown_pid_during_registration(self, m):
# register two children
callback1 = unittest.mock.Mock()
callback2 = unittest.mock.Mock()
@ -1310,15 +1268,8 @@ class ChildWatcherTestsMixin:
callback1.assert_called_once_with(591, 7)
self.assertFalse(callback2.called)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_set_loop(
self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED, m_WEXITSTATUS,
m_WTERMSIG):
@waitpid_mocks
def test_set_loop(self, m):
# register a child
callback = unittest.mock.Mock()
@ -1351,15 +1302,8 @@ class ChildWatcherTestsMixin:
callback.assert_called_once_with(60, 9)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_set_loop_race_condition(
self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED, m_WEXITSTATUS,
m_WTERMSIG):
@waitpid_mocks
def test_set_loop_race_condition(self, m):
# register 3 children
callback1 = unittest.mock.Mock()
callback2 = unittest.mock.Mock()
@ -1418,15 +1362,8 @@ class ChildWatcherTestsMixin:
self.assertFalse(callback2.called)
callback3.assert_called_once_with(622, 19)
@unittest.mock.patch('os.WTERMSIG', wraps=WTERMSIG)
@unittest.mock.patch('os.WEXITSTATUS', wraps=WEXITSTATUS)
@unittest.mock.patch('os.WIFSIGNALED', wraps=WIFSIGNALED)
@unittest.mock.patch('os.WIFEXITED', wraps=WIFEXITED)
@unittest.mock.patch('os.waitpid', wraps=waitpid)
def test_close(
self, m_waitpid, m_WIFEXITED, m_WIFSIGNALED, m_WEXITSTATUS,
m_WTERMSIG):
@waitpid_mocks
def test_close(self, m):
# register two children
callback1 = unittest.mock.Mock()
callback2 = unittest.mock.Mock()