|
39 | 39 | from test.support import socket_helper |
40 | 40 | from test.support import threading_helper |
41 | 41 | from test.support import warnings_helper |
42 | | - |
| 42 | +from test.support.script_helper import run_python_until_end |
43 | 43 |
|
44 | 44 | # Skip tests if _multiprocessing wasn't built. |
45 | 45 | _multiprocessing = import_helper.import_module('_multiprocessing') |
@@ -7142,3 +7142,67 @@ class SemLock(_multiprocessing.SemLock): |
7142 | 7142 | name = f'test_semlock_subclass-{os.getpid()}' |
7143 | 7143 | s = SemLock(1, 0, 10, name, False) |
7144 | 7144 | _multiprocessing.sem_unlink(name) |
| 7145 | + |
| 7146 | + |
| 7147 | +@unittest.skipIf(sys.platform != "linux", "Linux only") |
| 7148 | +class ForkInThreads(unittest.TestCase): |
| 7149 | + |
| 7150 | + def test_fork(self): |
| 7151 | + code = """ |
| 7152 | + import os, sys, threading, time |
| 7153 | +
|
| 7154 | + t = threading.Thread(target=time.sleep, args=(1,), daemon=True) |
| 7155 | + t.start() |
| 7156 | +
|
| 7157 | + assert threading.active_count() == 2 |
| 7158 | +
|
| 7159 | + pid = os.fork() |
| 7160 | + if pid < 0: |
| 7161 | + print("Fork failed") |
| 7162 | + elif pid == 0: |
| 7163 | + print("In child") |
| 7164 | + sys.exit(0) |
| 7165 | + print("In parent") |
| 7166 | + """ |
| 7167 | + |
| 7168 | + res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='always') |
| 7169 | + self.assertIn(b'In child', res.out) |
| 7170 | + self.assertIn(b'In parent', res.out) |
| 7171 | + self.assertIn(b'DeprecationWarning', res.err) |
| 7172 | + self.assertIn(b'is multi-threaded, use of fork() may lead to deadlocks in the child', res.err) |
| 7173 | + |
| 7174 | + res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='error') |
| 7175 | + self.assertIn(b'In child', res.out) |
| 7176 | + self.assertIn(b'In parent', res.out) |
| 7177 | + self.assertIn(b'DeprecationWarning', res.err) |
| 7178 | + self.assertIn(b'is multi-threaded, use of fork() may lead to deadlocks in the child', res.err) |
| 7179 | + |
| 7180 | + def test_forkpty(self): |
| 7181 | + code = """ |
| 7182 | + import os, sys, threading, time |
| 7183 | +
|
| 7184 | + t = threading.Thread(target=time.sleep, args=(1,), daemon=True) |
| 7185 | + t.start() |
| 7186 | +
|
| 7187 | + assert threading.active_count() == 2 |
| 7188 | +
|
| 7189 | + pid, _ = os.forkpty() |
| 7190 | + if pid < 0: |
| 7191 | + print(f"forkpty failed") |
| 7192 | + elif pid == 0: |
| 7193 | + print(f"In child") |
| 7194 | + sys.exit(0) |
| 7195 | + print(f"In parent") |
| 7196 | + """ |
| 7197 | + |
| 7198 | + res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='always') |
| 7199 | + print(res) |
| 7200 | + self.assertIn(b'In parent', res.out) |
| 7201 | + self.assertIn(b'DeprecationWarning', res.err) |
| 7202 | + self.assertIn(b'is multi-threaded, use of forkpty() may lead to deadlocks in the child', res.err) |
| 7203 | + |
| 7204 | + res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='error') |
| 7205 | + print(res) |
| 7206 | + self.assertIn(b'In parent', res.out) |
| 7207 | + self.assertIn(b'DeprecationWarning', res.err) |
| 7208 | + self.assertIn(b'is multi-threaded, use of forkpty() may lead to deadlocks in the child', res.err) |
0 commit comments