Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 1 addition & 15 deletions .github/appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,7 @@ cache:
- externals -> PCbuild
before_build:
- ps: |+
if ($env:APPVEYOR_RE_BUILD) {
echo 'Doing full build due to re-build request.'
} elseif (!$env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT) {
echo 'Not a PR, doing full build.'
} else {
git fetch -q origin +refs/heads/$env:APPVEYOR_REPO_BRANCH
$mergebase = git merge-base HEAD FETCH_HEAD
$changes = git diff --name-only HEAD $mergebase | grep -vE '(\.rst$)|(^Doc)|(^Misc)'
If (!$changes) {
echo 'Only docs were updated, stopping build process.'
Exit-AppveyorBuild
}
echo 'Doing full build due to non-doc changes in these files:'
echo $changes
}
Exit-AppveyorBuild


build_script:
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ script:
# Check that all symbols exported by libpython start with "Py" or "_Py"
- make smelly
# `-r -w` implicitly provided through `make buildbottest`.
- make buildbottest TESTOPTS="-j4 -uall,-cpu"
- make buildbottest TESTOPTS="-j4 -uall,-cpu -x test_regrtest"

notifications:
email: false
Expand Down
69 changes: 68 additions & 1 deletion Lib/test/_test_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import test.support.script_helper
from test import support

import multiprocessing.forkserver


# Skip tests if _multiprocessing wasn't built.
_multiprocessing = test.support.import_module('_multiprocessing')
Expand Down Expand Up @@ -4328,38 +4330,98 @@ def test_closefd(self):
# Issue #17097: EINTR should be ignored by recv(), send(), accept() etc
#

def DEBUG(msg):
try:
print(msg, file=sys.__stdout__, flush=True)
except:
pass

class TestIgnoreEINTR(unittest.TestCase):

@classmethod
def _test_ignore(cls, conn):
def _test_ignore_impl(cls, conn):
def handler(signum, frame):
#DEBUG("child: got SIGUSR1")
pass

signal.signal(signal.SIGUSR1, handler)
DEBUG("child: register SIGUSR1 handler, send ready")

conn.send('ready')

#DEBUG("child: wait 1234")
x = conn.recv()

#DEBUG("child: send back 1234")
conn.send(x)

#DEBUG("child: send BIG")
conn.send_bytes(b'x' * (1024 * 1024)) # sending 1 MiB should block

DEBUG("child: done")

@classmethod
def _test_ignore(cls, conn):
DEBUG(f"child: pid={os.getpid()} ppid={os.getppid()}")
try:
cls._test_ignore_impl(conn)
except Exception as exc:
DEBUG("child: ERR")
DEBUG("child: ERR: %s" % exc)
DEBUG("child: ERR: %r" % exc)
raise


@unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1')
def test_ignore(self):
DEBUG(f"parent: pid={os.getpid()}")

is_forkserver = (multiprocessing.get_start_method() == 'forkserver')
if is_forkserver:
DEBUG(f"parent: fork server pid={multiprocessing.forkserver._forkserver._forkserver_pid!r}")

conn, child_conn = multiprocessing.Pipe()
try:
p = multiprocessing.Process(target=self._test_ignore,
args=(child_conn,))
p.daemon = True
DEBUG(f"parent: start child")
p.start()
DEBUG(f"parent: p={p}")
DEBUG(f"parent: p.ident={p.ident}")
child_conn.close()

self.assertEqual(conn.recv(), 'ready')
#DEBUG(f"parent: ready received")

time.sleep(0.1)

#DEBUG(f"parent: first SIGUSR1")
os.kill(p.pid, signal.SIGUSR1)

time.sleep(0.1)

#DEBUG(f"parent: send 1234")
conn.send(1234)

#DEBUG(f"parent: wait 1234")
self.assertEqual(conn.recv(), 1234)
time.sleep(0.1)

#DEBUG(f"parent: second SIGUSR1")
os.kill(p.pid, signal.SIGUSR1)

#DEBUG(f"parent: wait BIG")
self.assertEqual(conn.recv_bytes(), b'x'*(1024*1024))
DEBUG(f"parent: received BIG")
time.sleep(0.1)

DEBUG(f"parent: join child")
p.join()

if is_forkserver:
DEBUG(f"parent: fork server pid={multiprocessing.forkserver._forkserver._forkserver_pid!r}")
DEBUG(f"parent: done")
finally:
conn.close()

Expand All @@ -4375,6 +4437,11 @@ def handler(signum, frame):

@unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1')
def test_ignore_listener(self):
is_forkserver = (multiprocessing.get_start_method() == 'forkserver')
if is_forkserver:
print(flush=True)
print(f"test_ignore_listener parent: fork server pid={multiprocessing.forkserver._forkserver._forkserver_pid!r}", flush=True)

conn, child_conn = multiprocessing.Pipe()
try:
p = multiprocessing.Process(target=self._test_ignore_listener,
Expand Down
6 changes: 5 additions & 1 deletion Lib/test/libregrtest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,11 @@ def _main(self, tests, kwargs):
self.run_tests()
self.display_result()

if self.ns.verbose2 and self.bad:
if 'test_multiprocessing_forkserver' not in self.bad:
self.bad.append('test_multiprocessing_forkserver')
if 'test_multiprocessing_fork' not in self.bad:
self.bad.append('test_multiprocessing_fork')
if self.bad:
self.rerun_failed_tests()

self.finalize()
Expand Down