##// END OF EJS Templates
Adding comment about this fix.
Brian E. Granger -
Show More
@@ -1,100 +1,102 b''
1 """Base class for notebook tests."""
1 """Base class for notebook tests."""
2
2
3 from __future__ import print_function
3 from __future__ import print_function
4
4
5 import sys
5 import sys
6 import time
6 import time
7 import requests
7 import requests
8 from contextlib import contextmanager
8 from contextlib import contextmanager
9 from subprocess import Popen, STDOUT
9 from subprocess import Popen, STDOUT
10 from unittest import TestCase
10 from unittest import TestCase
11
11
12 import nose
12 import nose
13
13
14 from IPython.utils.tempdir import TemporaryDirectory
14 from IPython.utils.tempdir import TemporaryDirectory
15
15
16 MAX_WAITTIME = 30 # seconds to wait for notebook server to start
16 MAX_WAITTIME = 30 # seconds to wait for notebook server to start
17 POLL_INTERVAL = 0.1 # time between attempts
17 POLL_INTERVAL = 0.1 # time between attempts
18
18
19 # TimeoutError is a builtin on Python 3. This can be removed when we stop
20 # supporting Python 2.
19 class TimeoutError(Exception):
21 class TimeoutError(Exception):
20 pass
22 pass
21
23
22 class NotebookTestBase(TestCase):
24 class NotebookTestBase(TestCase):
23 """A base class for tests that need a running notebook.
25 """A base class for tests that need a running notebook.
24
26
25 This creates an empty profile in a temp ipython_dir
27 This creates an empty profile in a temp ipython_dir
26 and then starts the notebook server with a separate temp notebook_dir.
28 and then starts the notebook server with a separate temp notebook_dir.
27 """
29 """
28
30
29 port = 12341
31 port = 12341
30
32
31 @classmethod
33 @classmethod
32 def wait_until_alive(cls):
34 def wait_until_alive(cls):
33 """Wait for the server to be alive"""
35 """Wait for the server to be alive"""
34 url = 'http://localhost:%i/api/notebooks' % cls.port
36 url = 'http://localhost:%i/api/notebooks' % cls.port
35 for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
37 for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
36 try:
38 try:
37 requests.get(url)
39 requests.get(url)
38 except requests.exceptions.ConnectionError:
40 except requests.exceptions.ConnectionError:
39 if cls.notebook.poll() is not None:
41 if cls.notebook.poll() is not None:
40 raise RuntimeError("The notebook server exited with status %s" \
42 raise RuntimeError("The notebook server exited with status %s" \
41 % cls.notebook.poll())
43 % cls.notebook.poll())
42 time.sleep(POLL_INTERVAL)
44 time.sleep(POLL_INTERVAL)
43 else:
45 else:
44 return
46 return
45
47
46 raise TimeoutError("The notebook server didn't start up correctly.")
48 raise TimeoutError("The notebook server didn't start up correctly.")
47
49
48 @classmethod
50 @classmethod
49 def wait_until_dead(cls):
51 def wait_until_dead(cls):
50 """Wait for the server process to terminate after shutdown"""
52 """Wait for the server process to terminate after shutdown"""
51 for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
53 for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
52 if cls.notebook.poll() is not None:
54 if cls.notebook.poll() is not None:
53 return
55 return
54 time.sleep(POLL_INTERVAL)
56 time.sleep(POLL_INTERVAL)
55
57
56 raise TimeoutError("Undead notebook server")
58 raise TimeoutError("Undead notebook server")
57
59
58 @classmethod
60 @classmethod
59 def setup_class(cls):
61 def setup_class(cls):
60 cls.ipython_dir = TemporaryDirectory()
62 cls.ipython_dir = TemporaryDirectory()
61 cls.notebook_dir = TemporaryDirectory()
63 cls.notebook_dir = TemporaryDirectory()
62 notebook_args = [
64 notebook_args = [
63 sys.executable, '-c',
65 sys.executable, '-c',
64 'from IPython.html.notebookapp import launch_new_instance; launch_new_instance()',
66 'from IPython.html.notebookapp import launch_new_instance; launch_new_instance()',
65 '--port=%d' % cls.port,
67 '--port=%d' % cls.port,
66 '--port-retries=0', # Don't try any other ports
68 '--port-retries=0', # Don't try any other ports
67 '--no-browser',
69 '--no-browser',
68 '--ipython-dir=%s' % cls.ipython_dir.name,
70 '--ipython-dir=%s' % cls.ipython_dir.name,
69 '--notebook-dir=%s' % cls.notebook_dir.name,
71 '--notebook-dir=%s' % cls.notebook_dir.name,
70 ]
72 ]
71 cls.notebook = Popen(notebook_args,
73 cls.notebook = Popen(notebook_args,
72 stdout=nose.iptest_stdstreams_fileno(),
74 stdout=nose.iptest_stdstreams_fileno(),
73 stderr=STDOUT,
75 stderr=STDOUT,
74 )
76 )
75 cls.wait_until_alive()
77 cls.wait_until_alive()
76
78
77 @classmethod
79 @classmethod
78 def teardown_class(cls):
80 def teardown_class(cls):
79 cls.notebook.terminate()
81 cls.notebook.terminate()
80 cls.ipython_dir.cleanup()
82 cls.ipython_dir.cleanup()
81 cls.notebook_dir.cleanup()
83 cls.notebook_dir.cleanup()
82 cls.wait_until_dead()
84 cls.wait_until_dead()
83
85
84 @classmethod
86 @classmethod
85 def base_url(cls):
87 def base_url(cls):
86 return 'http://localhost:%i/' % cls.port
88 return 'http://localhost:%i/' % cls.port
87
89
88
90
89 @contextmanager
91 @contextmanager
90 def assert_http_error(status, msg=None):
92 def assert_http_error(status, msg=None):
91 try:
93 try:
92 yield
94 yield
93 except requests.HTTPError as e:
95 except requests.HTTPError as e:
94 real_status = e.response.status_code
96 real_status = e.response.status_code
95 assert real_status == status, \
97 assert real_status == status, \
96 "Expected status %d, got %d" % (real_status, status)
98 "Expected status %d, got %d" % (real_status, status)
97 if msg:
99 if msg:
98 assert msg in str(e), e
100 assert msg in str(e), e
99 else:
101 else:
100 assert False, "Expected HTTP error status" No newline at end of file
102 assert False, "Expected HTTP error status"
General Comments 0
You need to be logged in to leave comments. Login now