diff options
author | Victor Stinner <vstinner@python.org> | 2020-12-16 11:11:24 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-16 11:11:24 (GMT) |
commit | 99d28c56708bff1f442e1df5748adb2620542c61 (patch) | |
tree | 5af36d44fea2703337105c867cf69cfadc6eb61f /Lib/test/test_asyncio | |
parent | 5f0fe8ec70120f4586d08978b0911b436f82c421 (diff) | |
download | cpython-99d28c56708bff1f442e1df5748adb2620542c61.zip cpython-99d28c56708bff1f442e1df5748adb2620542c61.tar.gz cpython-99d28c56708bff1f442e1df5748adb2620542c61.tar.bz2 |
bpo-40364: asyncio uses os.waitstatus_to_exitcode() (GH-23798)
test_unix_events.py no longer checks if waitstatus_to_exitcode() mock
has been called or not to make the test more functional, rather than
checking the exact implementation.
Diffstat (limited to 'Lib/test/test_asyncio')
-rw-r--r-- | Lib/test/test_asyncio/test_unix_events.py | 261 |
1 files changed, 65 insertions, 196 deletions
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 2c7d52a..6436385 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1,6 +1,5 @@ """Tests for unix_events.py.""" -import collections import contextlib import errno import io @@ -30,6 +29,15 @@ from test.test_asyncio import utils as test_utils MOCK_ANY = mock.ANY +def EXITCODE(exitcode): + return 32768 + exitcode + + +def SIGNAL(signum): + assert 1 <= signum <= 68 + return 32768 - signum + + def tearDownModule(): asyncio.set_event_loop_policy(None) @@ -1125,15 +1133,6 @@ class BaseChildWatcherTests(unittest.TestCase): NotImplementedError, watcher._do_waitpid, f) -WaitPidMocks = collections.namedtuple("WaitPidMocks", - ("waitpid", - "WIFEXITED", - "WIFSIGNALED", - "WEXITSTATUS", - "WTERMSIG", - )) - - class ChildWatcherTestsMixin: ignore_warnings = mock.patch.object(log.logger, "warning") @@ -1164,22 +1163,16 @@ class ChildWatcherTestsMixin: else: raise ChildProcessError() - def add_zombie(self, pid, returncode): - self.zombies[pid] = returncode + 32768 - - def WIFEXITED(self, status): - return status >= 32768 + def add_zombie(self, pid, status): + self.zombies[pid] = status - def WIFSIGNALED(self, status): - return 32700 < status < 32768 - - def WEXITSTATUS(self, status): - self.assertTrue(self.WIFEXITED(status)) - return status - 32768 - - def WTERMSIG(self, status): - self.assertTrue(self.WIFSIGNALED(status)) - return 32768 - status + def waitstatus_to_exitcode(self, status): + if status > 32768: + return status - 32768 + elif 32700 < status < 32768: + return status - 32768 + else: + return status def test_create_watcher(self): self.m_add_signal_handler.assert_called_once_with( @@ -1191,19 +1184,13 @@ class ChildWatcherTestsMixin: return mock.patch(target, wraps=wrapper, new_callable=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, \ + with patch('asyncio.unix_events.waitstatus_to_exitcode', self.waitstatus_to_exitcode), \ patch('os.waitpid', self.waitpid) as m_waitpid: - func(self, WaitPidMocks(m_waitpid, - m_WIFEXITED, m_WIFSIGNALED, - m_WEXITSTATUS, m_WTERMSIG, - )) + func(self, m_waitpid) return wrapped_func @waitpid_mocks - def test_sigchld(self, m): + def test_sigchld(self, m_waitpid): # register a child callback = mock.Mock() @@ -1212,59 +1199,36 @@ 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) # 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) # child terminates (returncode 12) self.running = False - self.add_zombie(42, 12) + self.add_zombie(42, EXITCODE(12)) self.watcher._sig_chld() - 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() callback.reset_mock() # ensure that the child is effectively reaped - self.add_zombie(42, 13) + self.add_zombie(42, EXITCODE(13)) with self.ignore_warnings: self.watcher._sig_chld() self.assertFalse(callback.called) - self.assertFalse(m.WTERMSIG.called) - - 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) @waitpid_mocks - def test_sigchld_two_children(self, m): + def test_sigchld_two_children(self, m_waitpid): callback1 = mock.Mock() callback2 = mock.Mock() @@ -1275,10 +1239,6 @@ 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) # register child 2 with self.watcher: @@ -1286,34 +1246,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) # children 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) # child 1 terminates (signal 3) - self.add_zombie(43, -3) + self.add_zombie(43, SIGNAL(3)) self.watcher._sig_chld() 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) - m.WIFSIGNALED.reset_mock() - m.WIFEXITED.reset_mock() - m.WTERMSIG.reset_mock() callback1.reset_mock() # child 2 still running @@ -1321,40 +1267,25 @@ 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) # child 2 terminates (code 108) - self.add_zombie(44, 108) + self.add_zombie(44, EXITCODE(108)) self.running = False self.watcher._sig_chld() 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) - m.WIFSIGNALED.reset_mock() - m.WIFEXITED.reset_mock() - m.WEXITSTATUS.reset_mock() callback2.reset_mock() # ensure that the children are effectively reaped - self.add_zombie(43, 14) - self.add_zombie(44, 15) + self.add_zombie(43, EXITCODE(14)) + self.add_zombie(44, EXITCODE(15)) with self.ignore_warnings: self.watcher._sig_chld() self.assertFalse(callback1.called) self.assertFalse(callback2.called) - self.assertFalse(m.WTERMSIG.called) - - m.WIFSIGNALED.reset_mock() - m.WIFEXITED.reset_mock() - m.WEXITSTATUS.reset_mock() # sigchld called again self.zombies.clear() @@ -1362,13 +1293,9 @@ 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) @waitpid_mocks - def test_sigchld_two_children_terminating_together(self, m): + def test_sigchld_two_children_terminating_together(self, m_waitpid): callback1 = mock.Mock() callback2 = mock.Mock() @@ -1379,10 +1306,6 @@ 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) # register child 2 with self.watcher: @@ -1390,60 +1313,43 @@ 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) # children 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) # child 1 terminates (code 78) # child 2 terminates (signal 5) - self.add_zombie(45, 78) - self.add_zombie(46, -5) + self.add_zombie(45, EXITCODE(78)) + self.add_zombie(46, SIGNAL(5)) self.running = False self.watcher._sig_chld() 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) - - m.WIFSIGNALED.reset_mock() - m.WIFEXITED.reset_mock() - m.WTERMSIG.reset_mock() - m.WEXITSTATUS.reset_mock() + callback1.reset_mock() callback2.reset_mock() # ensure that the children are effectively reaped - self.add_zombie(45, 14) - self.add_zombie(46, 15) + self.add_zombie(45, EXITCODE(14)) + self.add_zombie(46, EXITCODE(15)) with self.ignore_warnings: self.watcher._sig_chld() self.assertFalse(callback1.called) self.assertFalse(callback2.called) - self.assertFalse(m.WTERMSIG.called) @waitpid_mocks - def test_sigchld_race_condition(self, m): + def test_sigchld_race_condition(self, m_waitpid): # register a child callback = mock.Mock() with self.watcher: # child terminates before being registered - self.add_zombie(50, 4) + self.add_zombie(50, EXITCODE(4)) self.watcher._sig_chld() self.watcher.add_child_handler(50, callback, 1, 12) @@ -1452,14 +1358,14 @@ class ChildWatcherTestsMixin: callback.reset_mock() # ensure that the child is effectively reaped - self.add_zombie(50, -1) + self.add_zombie(50, SIGNAL(1)) with self.ignore_warnings: self.watcher._sig_chld() self.assertFalse(callback.called) @waitpid_mocks - def test_sigchld_replace_handler(self, m): + def test_sigchld_replace_handler(self, m_waitpid): callback1 = mock.Mock() callback2 = mock.Mock() @@ -1470,10 +1376,6 @@ 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) # register the same child again with self.watcher: @@ -1481,38 +1383,27 @@ 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) # child terminates (signal 8) self.running = False - self.add_zombie(51, -8) + self.add_zombie(51, SIGNAL(8)) self.watcher._sig_chld() 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) - m.WIFSIGNALED.reset_mock() - m.WIFEXITED.reset_mock() - m.WTERMSIG.reset_mock() callback2.reset_mock() # ensure that the child is effectively reaped - self.add_zombie(51, 13) + self.add_zombie(51, EXITCODE(13)) with self.ignore_warnings: self.watcher._sig_chld() self.assertFalse(callback1.called) self.assertFalse(callback2.called) - self.assertFalse(m.WTERMSIG.called) @waitpid_mocks - def test_sigchld_remove_handler(self, m): + def test_sigchld_remove_handler(self, m_waitpid): callback = mock.Mock() # register a child @@ -1521,30 +1412,22 @@ 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) # 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) # child terminates (code 99) self.running = False - self.add_zombie(52, 99) + self.add_zombie(52, EXITCODE(99)) with self.ignore_warnings: self.watcher._sig_chld() self.assertFalse(callback.called) @waitpid_mocks - def test_sigchld_unknown_status(self, m): + def test_sigchld_unknown_status(self, m_waitpid): callback = mock.Mock() # register a child @@ -1553,10 +1436,6 @@ 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) # terminate with unknown status self.zombies[53] = 1178 @@ -1564,24 +1443,18 @@ 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) callback.reset_mock() - m.WIFEXITED.reset_mock() - m.WIFSIGNALED.reset_mock() # ensure that the child is effectively reaped - self.add_zombie(53, 101) + self.add_zombie(53, EXITCODE(101)) with self.ignore_warnings: self.watcher._sig_chld() self.assertFalse(callback.called) @waitpid_mocks - def test_remove_child_handler(self, m): + def test_remove_child_handler(self, m_waitpid): callback1 = mock.Mock() callback2 = mock.Mock() callback3 = mock.Mock() @@ -1602,9 +1475,9 @@ class ChildWatcherTestsMixin: self.assertFalse(self.watcher.remove_child_handler(55)) # all children terminate - self.add_zombie(54, 0) - self.add_zombie(55, 1) - self.add_zombie(56, 2) + self.add_zombie(54, EXITCODE(0)) + self.add_zombie(55, EXITCODE(1)) + self.add_zombie(56, EXITCODE(2)) self.running = False with self.ignore_warnings: self.watcher._sig_chld() @@ -1614,7 +1487,7 @@ class ChildWatcherTestsMixin: callback3.assert_called_once_with(56, 2, 3) @waitpid_mocks - def test_sigchld_unhandled_exception(self, m): + def test_sigchld_unhandled_exception(self, m_waitpid): callback = mock.Mock() # register a child @@ -1623,7 +1496,7 @@ class ChildWatcherTestsMixin: self.watcher.add_child_handler(57, callback) # raise an exception - m.waitpid.side_effect = ValueError + m_waitpid.side_effect = ValueError with mock.patch.object(log.logger, 'error') as m_error: @@ -1632,7 +1505,7 @@ class ChildWatcherTestsMixin: self.assertTrue(m_error.called) @waitpid_mocks - def test_sigchld_child_reaped_elsewhere(self, m): + def test_sigchld_child_reaped_elsewhere(self, m_waitpid): # register a child callback = mock.Mock() @@ -1641,19 +1514,15 @@ 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) # child terminates self.running = False - self.add_zombie(58, 4) + self.add_zombie(58, EXITCODE(4)) # waitpid is called elsewhere os.waitpid(58, os.WNOHANG) - m.waitpid.reset_mock() + m_waitpid.reset_mock() # sigchld with self.ignore_warnings: @@ -1667,7 +1536,7 @@ class ChildWatcherTestsMixin: callback.assert_called_once_with(58, 255) @waitpid_mocks - def test_sigchld_unknown_pid_during_registration(self, m): + def test_sigchld_unknown_pid_during_registration(self, m_waitpid): # register two children callback1 = mock.Mock() callback2 = mock.Mock() @@ -1675,9 +1544,9 @@ class ChildWatcherTestsMixin: with self.ignore_warnings, self.watcher: self.running = True # child 1 terminates - self.add_zombie(591, 7) + self.add_zombie(591, EXITCODE(7)) # an unknown child terminates - self.add_zombie(593, 17) + self.add_zombie(593, EXITCODE(17)) self.watcher._sig_chld() @@ -1688,7 +1557,7 @@ class ChildWatcherTestsMixin: self.assertFalse(callback2.called) @waitpid_mocks - def test_set_loop(self, m): + def test_set_loop(self, m_waitpid): # register a child callback = mock.Mock() @@ -1713,13 +1582,13 @@ class ChildWatcherTestsMixin: # child terminates self.running = False - self.add_zombie(60, 9) + self.add_zombie(60, EXITCODE(9)) self.watcher._sig_chld() callback.assert_called_once_with(60, 9) @waitpid_mocks - def test_set_loop_race_condition(self, m): + def test_set_loop_race_condition(self, m_waitpid): # register 3 children callback1 = mock.Mock() callback2 = mock.Mock() @@ -1746,8 +1615,8 @@ class ChildWatcherTestsMixin: signal.SIGCHLD) # child 1 & 2 terminate - self.add_zombie(61, 11) - self.add_zombie(62, -5) + self.add_zombie(61, EXITCODE(11)) + self.add_zombie(62, SIGNAL(5)) # SIGCHLD was not caught self.assertFalse(callback1.called) @@ -1773,7 +1642,7 @@ class ChildWatcherTestsMixin: # child 3 terminates self.running = False - self.add_zombie(622, 19) + self.add_zombie(622, EXITCODE(19)) self.watcher._sig_chld() self.assertFalse(callback1.called) @@ -1781,16 +1650,16 @@ class ChildWatcherTestsMixin: callback3.assert_called_once_with(622, 19) @waitpid_mocks - def test_close(self, m): + def test_close(self, m_waitpid): # register two children callback1 = mock.Mock() with self.watcher: self.running = True # child 1 terminates - self.add_zombie(63, 9) + self.add_zombie(63, EXITCODE(9)) # other child terminates - self.add_zombie(65, 18) + self.add_zombie(65, EXITCODE(18)) self.watcher._sig_chld() self.watcher.add_child_handler(63, callback1) |