from __future__ import division import os import shutil from subprocess import Popen, PIPE import sys from tempfile import mkdtemp import time PY3 = sys.version_info[0] >= 3 def _launch(extra_env): env = os.environ.copy() env.update(extra_env) return Popen([sys.executable, '-c', 'from jupyter_client.kernelapp import main; main()'], env=env, stderr=(PIPE if PY3 else None)) WAIT_TIME = 10 POLL_FREQ = 10 def hacky_wait(p): """Python 2 subprocess doesn't have timeouts :-(""" for _ in range(WAIT_TIME * POLL_FREQ): if p.poll() is not None: return p.returncode time.sleep(1 / POLL_FREQ) else: raise AssertionError("Process didn't exit in {} seconds" .format(WAIT_TIME)) def test_kernelapp_lifecycle(): # Check that 'jupyter kernel' starts and terminates OK. runtime_dir = mkdtemp() startup_dir = mkdtemp() started = os.path.join(startup_dir, 'started') try: p = _launch({'JUPYTER_RUNTIME_DIR': runtime_dir, 'JUPYTER_CLIENT_TEST_RECORD_STARTUP_PRIVATE': started, }) # Wait for start for _ in range(WAIT_TIME * POLL_FREQ): if os.path.isfile(started): break time.sleep(1 / POLL_FREQ) else: raise AssertionError("No started file created in {} seconds" .format(WAIT_TIME)) # Connection file should be there by now files = os.listdir(runtime_dir) assert len(files) == 1 cf = files[0] assert cf.startswith('kernel') assert cf.endswith('.json') # Send SIGTERM to shut down p.terminate() if PY3: _, stderr = p.communicate(timeout=WAIT_TIME) assert cf in stderr.decode('utf-8', 'replace') else: hacky_wait(p) finally: shutil.rmtree(runtime_dir) shutil.rmtree(startup_dir)