Skip to content

Commit 7e6d167

Browse files
committed
Add test of 'jupyter kernel'
1 parent ae03ddd commit 7e6d167

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

jupyter_client/kernelapp.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def initialize(self, argv=None):
3535
cf_basename = 'kernel-%s.json' % uuid.uuid4()
3636
self.km.connection_file = os.path.join(self.runtime_dir, cf_basename)
3737
self.loop = IOLoop.current()
38+
self.loop.add_callback(self._record_started)
3839

3940
def setup_signals(self):
4041
"""Shutdown on SIGTERM or SIGINT (Ctrl-C)"""
@@ -56,6 +57,16 @@ def log_connection_info(self):
5657
self.log.info('Connection file: %s', cf)
5758
self.log.info("To connect a client: --existing %s", os.path.basename(cf))
5859

60+
def _record_started(self):
61+
"""For tests, create a file to indicate that we've started
62+
63+
Do not rely on this except in our own tests!
64+
"""
65+
fn = os.environ.get('JUPYTER_CLIENT_TEST_RECORD_STARTUP_PRIVATE')
66+
if fn is not None:
67+
with open(fn, 'wb'):
68+
pass
69+
5970
def start(self):
6071
self.log.info('Starting kernel %r', self.kernel_name)
6172
try:
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from __future__ import division
2+
3+
import os
4+
import shutil
5+
from subprocess import Popen, PIPE
6+
import sys
7+
from tempfile import mkdtemp
8+
import time
9+
10+
def _launch(extra_env):
11+
env = os.environ.copy()
12+
env.update(extra_env)
13+
return Popen([sys.executable, '-c',
14+
'from jupyter_client.kernelapp import main; main()'],
15+
env=env, stderr=PIPE)
16+
17+
WAIT_TIME = 10
18+
POLL_FREQ = 10
19+
20+
def test_kernelapp_lifecycle():
21+
# Check that 'jupyter kernel' starts and terminates OK.
22+
runtime_dir = mkdtemp()
23+
startup_dir = mkdtemp()
24+
started = os.path.join(startup_dir, 'started')
25+
try:
26+
p = _launch({'JUPYTER_RUNTIME_DIR': runtime_dir,
27+
'JUPYTER_CLIENT_TEST_RECORD_STARTUP_PRIVATE': started,
28+
})
29+
# Wait for start
30+
for _ in range(WAIT_TIME * POLL_FREQ):
31+
if os.path.isfile(started):
32+
break
33+
time.sleep(1 / POLL_FREQ)
34+
else:
35+
raise AssertionError("No started file created in {} seconds"
36+
.format(WAIT_TIME))
37+
38+
# Connection file should be there by now
39+
files = os.listdir(runtime_dir)
40+
assert len(files) == 1
41+
cf = files[0]
42+
assert cf.startswith('kernel')
43+
assert cf.endswith('.json')
44+
45+
# Read the first three lines from stderr. This will hang if there are
46+
# fewer lines to read; I don't see any way to avoid that without lots
47+
# of extra complexity.
48+
b = b''.join(p.stderr.readline() for _ in range(2)).decode('utf-8', 'replace')
49+
assert cf in b
50+
51+
# Send SIGTERM to shut down
52+
p.terminate()
53+
p.wait(timeout=10)
54+
finally:
55+
shutil.rmtree(runtime_dir)
56+
shutil.rmtree(startup_dir)
57+

0 commit comments

Comments
 (0)