Skip to content

Commit

Permalink
Merge pull request #5339 from minrk/iptest-qt-js-wtf
Browse files Browse the repository at this point in the history
Don't use fork to start the notebook in js tests
  • Loading branch information
minrk committed Mar 24, 2014
2 parents 0e14026 + dcd8107 commit 38d326e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 32 deletions.
2 changes: 1 addition & 1 deletion IPython/testing/iptest.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ def will_run(self):

# html:
sec = test_sections['html']
sec.requires('zmq', 'tornado', 'requests')
sec.requires('zmq', 'tornado', 'requests', 'sqlite3')
# The notebook 'static' directory contains JS, css and other
# files for web serving. Occasionally projects may put a .py
# file in there (MathJax ships a conf.py), so we might as
Expand Down
91 changes: 60 additions & 31 deletions IPython/testing/iptestcontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@
from __future__ import print_function

import argparse
import json
import multiprocessing.pool
from multiprocessing import Process, Queue
import os
import shutil
import signal
import sys
import subprocess
import time

from .iptest import have, test_group_names as py_test_group_names, test_sections
from .iptest import have, test_group_names as py_test_group_names, test_sections, StreamCapturer
from IPython.utils.path import compress_user
from IPython.utils.py3compat import bytes_to_str
from IPython.utils.sysinfo import get_sys_info
Expand Down Expand Up @@ -220,48 +220,77 @@ def setup(self):
os.makedirs(os.path.join(self.nbdir.name, os.path.join(u'sub ∂ir2', u'sub ∂ir 1b')))

# start the ipython notebook, so we get the port number
self.server_port = 0
self._init_server()
self.cmd.append('--port=%s' % self.server_port)

if self.server_port:
self.cmd.append("--port=%i" % self.server_port)
else:
# don't launch tests if the server didn't start
self.cmd = [sys.executable, '-c', 'raise SystemExit(1)']

def print_extra_info(self):
print("Running tests with notebook directory %r" % self.nbdir.name)

@property
def will_run(self):
return all(have[a] for a in ['zmq', 'tornado', 'jinja2', 'casperjs'])
return all(have[a] for a in ['zmq', 'tornado', 'jinja2', 'casperjs', 'sqlite3'])

def _init_server(self):
"Start the notebook server in a separate process"
self.queue = q = Queue()
self.server = Process(target=run_webapp, args=(q, self.ipydir.name, self.nbdir.name))
self.server.start()
self.server_port = q.get()
self.server_command = command = [sys.executable,
'-m', 'IPython.html',
'--no-browser',
'--ipython-dir', self.ipydir.name,
'--notebook-dir', self.nbdir.name,
]
# ipc doesn't work on Windows, and darwin has crazy-long temp paths,
# which run afoul of ipc's maximum path length.
if sys.platform.startswith('linux'):
command.append('--KernelManager.transport=ipc')
self.stream_capturer = c = StreamCapturer()
c.start()
self.server = subprocess.Popen(command, stdout=c.writefd, stderr=subprocess.STDOUT)
self.server_info_file = os.path.join(self.ipydir.name,
'profile_default', 'security', 'nbserver-%i.json' % self.server.pid
)
self._wait_for_server()

def _wait_for_server(self):
"""Wait 30 seconds for the notebook server to start"""
for i in range(300):
if self.server.poll() is not None:
return self._failed_to_start()
if os.path.exists(self.server_info_file):
self._load_server_info()
return
time.sleep(0.1)
print("Notebook server-info file never arrived: %s" % self.server_info_file,
file=sys.stderr
)

def _failed_to_start(self):
"""Notebook server exited prematurely"""
captured = self.stream_capturer.get_buffer().decode('utf-8', 'replace')
print("Notebook failed to start: ", file=sys.stderr)
print(self.server_command)
print(captured, file=sys.stderr)

def _load_server_info(self):
"""Notebook server started, load connection info from JSON"""
with open(self.server_info_file) as f:
info = json.load(f)
self.server_port = info['port']

def cleanup(self):
self.server.terminate()
self.server.join()
try:
self.server.terminate()
except OSError:
# already dead
pass
self.server.wait()
self.stream_capturer.halt()
TestController.cleanup(self)

def run_webapp(q, ipydir, nbdir, loglevel=0):
"""start the IPython Notebook, and pass port back to the queue"""
import os
import IPython.html.notebookapp as nbapp
import sys
sys.stderr = open(os.devnull, 'w')
server = nbapp.NotebookApp()
args = ['--no-browser']
args.extend(['--ipython-dir', ipydir,
'--notebook-dir', nbdir,
'--log-level', str(loglevel),
])
# ipc doesn't work on Windows, and darwin has crazy-long temp paths,
# which run afoul of ipc's maximum path length.
if sys.platform.startswith('linux'):
args.append('--KernelManager.transport=ipc')
server.initialize(args)
# communicate the port number to the parent process
q.put(server.port)
server.start()

def prepare_controllers(options):
"""Returns two lists of TestController instances, those to run, and those
Expand Down

0 comments on commit 38d326e

Please sign in to comment.