Skip to content
Merged
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
77 changes: 50 additions & 27 deletions ipykernel/tests/test_embed_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import os
import sys
import time
import json

from contextlib import contextmanager
from subprocess import Popen, PIPE
from flaky import flaky

from jupyter_client import BlockingKernelClient
from jupyter_core import paths
Expand All @@ -28,39 +30,57 @@ def setup_kernel(cmd):
-------
kernel_manager: connected KernelManager instance
"""
kernel = Popen([sys.executable, '-c', cmd], stdout=PIPE, stderr=PIPE)
connection_file = os.path.join(
paths.jupyter_runtime_dir(),
'kernel-%i.json' % kernel.pid,
)
# wait for connection file to exist, timeout after 5s
tic = time.time()
while not os.path.exists(connection_file) \
and kernel.poll() is None \
and time.time() < tic + SETUP_TIMEOUT:
time.sleep(0.1)

if kernel.poll() is not None:
o,e = kernel.communicate()
e = py3compat.cast_unicode(e)
raise IOError("Kernel failed to start:\n%s" % e)

if not os.path.exists(connection_file):
if kernel.poll() is None:
kernel.terminate()
raise IOError("Connection file %r never arrived" % connection_file)

client = BlockingKernelClient(connection_file=connection_file)
client.load_connection_file()
client.start_channels()
client.wait_for_ready()
def connection_file_ready(connection_file):
"""Check if connection_file is a readable json file."""
if not os.path.exists(connection_file):
return False
try:
with open(connection_file) as f:
json.load(f)
return True
except ValueError:
return False

kernel = Popen([sys.executable, '-c', cmd], stdout=PIPE, stderr=PIPE)
try:
yield client
connection_file = os.path.join(
paths.jupyter_runtime_dir(),
'kernel-%i.json' % kernel.pid,
)
# wait for connection file to exist, timeout after 5s
tic = time.time()
while not connection_file_ready(connection_file) \
and kernel.poll() is None \
and time.time() < tic + SETUP_TIMEOUT:
time.sleep(0.1)

# Wait 100ms for the writing to finish
time.sleep(0.1)

if kernel.poll() is not None:
o,e = kernel.communicate()
e = py3compat.cast_unicode(e)
raise IOError("Kernel failed to start:\n%s" % e)

if not os.path.exists(connection_file):
if kernel.poll() is None:
kernel.terminate()
raise IOError("Connection file %r never arrived" % connection_file)

client = BlockingKernelClient(connection_file=connection_file)
client.load_connection_file()
client.start_channels()
client.wait_for_ready()
try:
yield client
finally:
client.stop_channels()
finally:
client.stop_channels()
kernel.terminate()


@flaky(max_runs=3)
def test_embed_kernel_basic():
"""IPython.embed_kernel() is basically functional"""
cmd = '\n'.join([
Expand Down Expand Up @@ -93,6 +113,8 @@ def test_embed_kernel_basic():
text = content['data']['text/plain']
assert '10' in text


@flaky(max_runs=3)
def test_embed_kernel_namespace():
"""IPython.embed_kernel() inherits calling namespace"""
cmd = '\n'.join([
Expand Down Expand Up @@ -128,6 +150,7 @@ def test_embed_kernel_namespace():
content = msg['content']
assert not content['found']

@flaky(max_runs=3)
def test_embed_kernel_reentrant():
"""IPython.embed_kernel() can be called multiple times"""
cmd = '\n'.join([
Expand Down
4 changes: 4 additions & 0 deletions ipykernel/tests/test_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import time

import nose.tools as nt
from flaky import flaky

from IPython.testing import decorators as dec, tools as tt
from ipython_genutils import py3compat
Expand Down Expand Up @@ -75,6 +76,7 @@ def test_sys_path_profile_dir():
assert '' in sys_path


@flaky(max_runs=3)
@dec.skipif(sys.platform == 'win32', "subprocess prints fail on Windows")
def test_subprocess_print():
"""printing from forked mp.Process"""
Expand Down Expand Up @@ -104,6 +106,7 @@ def test_subprocess_print():
_check_master(kc, expected=True, stream="stderr")


@flaky(max_runs=3)
def test_subprocess_noprint():
"""mp.Process without print doesn't trigger iostream mp_mode"""
with kernel() as kc:
Expand All @@ -126,6 +129,7 @@ def test_subprocess_noprint():
_check_master(kc, expected=True, stream="stderr")


@flaky(max_runs=3)
@dec.skipif(sys.platform == 'win32', "subprocess prints fail on Windows")
def test_subprocess_error():
"""error in mp.Process doesn't crash"""
Expand Down
5 changes: 5 additions & 0 deletions ipykernel/tests/test_start_kernel.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from .test_embed_kernel import setup_kernel
from flaky import flaky

TIMEOUT = 15


@flaky(max_runs=3)
def test_ipython_start_kernel_userns():
cmd = ('from IPython import start_kernel\n'
'ns = {"tre": 123}\n'
Expand All @@ -27,6 +30,8 @@ def test_ipython_start_kernel_userns():
text = content['data']['text/plain']
assert u'DummyMod' in text


@flaky(max_runs=3)
def test_ipython_start_kernel_no_userns():
# Issue #4188 - user_ns should be passed to shell as None, not {}
cmd = ('from IPython import start_kernel\n'
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def run(self):
'test': [
'pytest',
'pytest-cov',
'flaky',
'nose', # nose because there are still a few nose.tools imports hanging around
],
},
Expand Down