Merge pull request #63 from chrizzFTD/update_tests_for_windows

Update tests for windows
propagate_loglevel
goodboy 2019-03-14 21:06:37 -04:00 committed by GitHub
commit 29ffbfe6ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 10 deletions

View File

@ -34,5 +34,6 @@ def pytest_generate_tests(metafunc):
if 'start_method' in metafunc.fixturenames: if 'start_method' in metafunc.fixturenames:
from multiprocessing import get_all_start_methods from multiprocessing import get_all_start_methods
methods = get_all_start_methods() methods = get_all_start_methods()
if 'fork' in methods: # fork not available on windows, so check before removing
methods.remove('fork') methods.remove('fork')
metafunc.parametrize("start_method", methods, scope='module') metafunc.parametrize("start_method", methods, scope='module')

View File

@ -45,13 +45,15 @@ async def hi():
async def say_hello(other_actor): async def say_hello(other_actor):
await trio.sleep(0.4) # wait for other actor to spawn await trio.sleep(1) # wait for other actor to spawn
async with tractor.find_actor(other_actor) as portal: async with tractor.find_actor(other_actor) as portal:
assert portal is not None
return await portal.run(__name__, 'hi') return await portal.run(__name__, 'hi')
async def say_hello_use_wait(other_actor): async def say_hello_use_wait(other_actor):
async with tractor.wait_for_actor(other_actor) as portal: async with tractor.wait_for_actor(other_actor) as portal:
assert portal is not None
result = await portal.run(__name__, 'hi') result = await portal.run(__name__, 'hi')
return result return result

View File

@ -8,8 +8,19 @@ import subprocess
import pytest import pytest
import tractor import tractor
import platform
from conftest import tractor_test from conftest import tractor_test
# Sending signal.SIGINT on subprocess fails on windows. Use CTRL_* alternatives
if platform.system() == 'Windows':
_KILL_SIGNAL = signal.CTRL_BREAK_EVENT
_INT_SIGNAL = signal.CTRL_C_EVENT
_INT_RETURN_CODE = 3221225786
else:
_KILL_SIGNAL = signal.SIGKILL
_INT_SIGNAL = signal.SIGINT
_INT_RETURN_CODE = 1
def sig_prog(proc, sig): def sig_prog(proc, sig):
"Kill the actor-process with ``sig``." "Kill the actor-process with ``sig``."
@ -18,8 +29,7 @@ def sig_prog(proc, sig):
if not proc.poll(): if not proc.poll():
# TODO: why sometimes does SIGINT not work on teardown? # TODO: why sometimes does SIGINT not work on teardown?
# seems to happen only when trace logging enabled? # seems to happen only when trace logging enabled?
proc.send_signal(signal.SIGKILL) proc.send_signal(_KILL_SIGNAL)
ret = proc.wait() ret = proc.wait()
assert ret assert ret
@ -33,24 +43,32 @@ def daemon(loglevel, testdir, arb_addr):
arb_addr, arb_addr,
"'{}'".format(loglevel) if loglevel else None) "'{}'".format(loglevel) if loglevel else None)
] ]
kwargs = dict()
if platform.system() == 'Windows':
# without this, tests hang on windows forever
kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
proc = testdir.popen( proc = testdir.popen(
cmdargs, cmdargs,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
**kwargs,
) )
assert not proc.returncode assert not proc.returncode
wait = 0.6 if sys.version_info < (3, 7) else 0.4 wait = 0.6 if sys.version_info < (3, 7) else 0.4
time.sleep(wait) time.sleep(wait)
yield proc yield proc
sig_prog(proc, signal.SIGINT) sig_prog(proc, _INT_SIGNAL)
def test_abort_on_sigint(daemon): def test_abort_on_sigint(daemon):
assert daemon.returncode is None assert daemon.returncode is None
time.sleep(0.1) time.sleep(0.1)
sig_prog(daemon, signal.SIGINT) sig_prog(daemon, _INT_SIGNAL)
assert daemon.returncode == 1 assert daemon.returncode == _INT_RETURN_CODE
# XXX: oddly, couldn't get capfd.readouterr() to work here? # XXX: oddly, couldn't get capfd.readouterr() to work here?
if platform.system() != 'Windows':
# don't check stderr on windows as its empty when sending CTRL_C_EVENT
assert "KeyboardInterrupt" in str(daemon.stderr.read()) assert "KeyboardInterrupt" in str(daemon.stderr.read())

View File

@ -24,10 +24,9 @@ def try_set_start_method(name: str) -> mp.context.BaseContext:
global _ctx global _ctx
allowed = mp.get_all_start_methods() allowed = mp.get_all_start_methods()
assert name in allowed
if name not in allowed: if name not in allowed:
name == 'spawn' name = 'spawn'
elif name == 'fork': elif name == 'fork':
raise ValueError( raise ValueError(
"`fork` is unsupported due to incompatibility with `trio`" "`fork` is unsupported due to incompatibility with `trio`"
@ -35,6 +34,8 @@ def try_set_start_method(name: str) -> mp.context.BaseContext:
elif name == 'forkserver': elif name == 'forkserver':
_forkserver_hackzorz.override_stdlib() _forkserver_hackzorz.override_stdlib()
assert name in allowed
_ctx = mp.get_context(name) _ctx = mp.get_context(name)
return _ctx return _ctx