bpo-31173: Rewrite WSTOPSIG test of test_subprocess (#3055) (#3070) · python/cpython@bc69d00

@@ -29,6 +29,11 @@

2929

except ImportError:

3030

threading = None

313132+

try:

33+

import _testcapi

34+

except ImportError:

35+

_testcapi = None

36+3237

if support.PGO:

3338

raise unittest.SkipTest("test is not helpful for PGO")

3439

@@ -2567,42 +2572,24 @@ def test_communicate_BrokenPipeError_stdin_close_with_timeout(self):

25672572

proc.communicate(timeout=999)

25682573

mock_proc_stdin.close.assert_called_once_with()

256925742570-

@unittest.skipIf(not ctypes, 'ctypes module required')

2571-

@unittest.skipIf(not sys.executable, 'Test requires sys.executable')

2572-

def test_child_terminated_in_stopped_state(self):

2575+

@unittest.skipUnless(_testcapi is not None

2576+

and hasattr(_testcapi, 'W_STOPCODE'),

2577+

'need _testcapi.W_STOPCODE')

2578+

def test_stopped(self):

25732579

"""Test wait() behavior when waitpid returns WIFSTOPPED; issue29335."""

2574-

PTRACE_TRACEME = 0 # From glibc and MacOS (PT_TRACE_ME).

2575-

libc_name = ctypes.util.find_library('c')

2576-

libc = ctypes.CDLL(libc_name)

2577-

if not hasattr(libc, 'ptrace'):

2578-

raise unittest.SkipTest('ptrace() required')

2579-2580-

code = textwrap.dedent(f"""

2581-

import ctypes

2582-

import faulthandler

2583-

from test.support import SuppressCrashReport

2584-2585-

libc = ctypes.CDLL({libc_name!r})

2586-

libc.ptrace({PTRACE_TRACEME}, 0, 0)

2587-

""")

2588-2589-

child = subprocess.Popen([sys.executable, '-c', code])

2590-

if child.wait() != 0:

2591-

raise unittest.SkipTest('ptrace() failed - unable to test')

2592-2593-

code += textwrap.dedent(f"""

2594-

with SuppressCrashReport():

2595-

# Crash the process

2596-

faulthandler._sigsegv()

2597-

""")

2598-

child = subprocess.Popen([sys.executable, '-c', code])

2599-

try:

2600-

returncode = child.wait()

2601-

except:

2602-

child.kill() # Clean up the hung stopped process.

2603-

raise

2604-

self.assertNotEqual(0, returncode)

2605-

self.assertLess(returncode, 0) # signal death, likely SIGSEGV.

2580+

args = [sys.executable, '-c', 'pass']

2581+

proc = subprocess.Popen(args)

2582+2583+

# Wait until the real process completes to avoid zombie process

2584+

pid = proc.pid

2585+

pid, status = os.waitpid(pid, 0)

2586+

self.assertEqual(status, 0)

2587+2588+

status = _testcapi.W_STOPCODE(3)

2589+

with mock.patch('subprocess.os.waitpid', return_value=(pid, status)):

2590+

returncode = proc.wait()

2591+2592+

self.assertEqual(returncode, -3)

260625932607259426082595

@unittest.skipUnless(mswindows, "Windows specific tests")