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

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

`

29

29

`except ImportError:

`

30

30

`threading = None

`

31

31

``

``

32

`+

try:

`

``

33

`+

import _testcapi

`

``

34

`+

except ImportError:

`

``

35

`+

_testcapi = None

`

``

36

+

32

37

`if support.PGO:

`

33

38

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

`

34

39

``

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

`

2567

2572

`proc.communicate(timeout=999)

`

2568

2573

`mock_proc_stdin.close.assert_called_once_with()

`

2569

2574

``

2570

``

`-

@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):

`

2573

2579

`"""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)

`

2606

2593

``

2607

2594

``

2608

2595

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

`