##// END OF EJS Templates
Merge pull request #5265 from ellisonbg/timeout-error...
Thomas Kluyver -
r15628:dfd5cb1d merge
parent child Browse files
Show More
@@ -1,97 +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.
21 class TimeoutError(Exception):
22 pass
23
19 class NotebookTestBase(TestCase):
24 class NotebookTestBase(TestCase):
20 """A base class for tests that need a running notebook.
25 """A base class for tests that need a running notebook.
21
26
22 This creates an empty profile in a temp ipython_dir
27 This creates an empty profile in a temp ipython_dir
23 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.
24 """
29 """
25
30
26 port = 12341
31 port = 12341
27
32
28 @classmethod
33 @classmethod
29 def wait_until_alive(cls):
34 def wait_until_alive(cls):
30 """Wait for the server to be alive"""
35 """Wait for the server to be alive"""
31 url = 'http://localhost:%i/api/notebooks' % cls.port
36 url = 'http://localhost:%i/api/notebooks' % cls.port
32 for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
37 for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
33 try:
38 try:
34 requests.get(url)
39 requests.get(url)
35 except requests.exceptions.ConnectionError:
40 except requests.exceptions.ConnectionError:
36 if cls.notebook.poll() is not None:
41 if cls.notebook.poll() is not None:
37 raise RuntimeError("The notebook server exited with status %s" \
42 raise RuntimeError("The notebook server exited with status %s" \
38 % cls.notebook.poll())
43 % cls.notebook.poll())
39 time.sleep(POLL_INTERVAL)
44 time.sleep(POLL_INTERVAL)
40 else:
45 else:
41 return
46 return
42
47
43 raise TimeoutError("The notebook server didn't start up correctly.")
48 raise TimeoutError("The notebook server didn't start up correctly.")
44
49
45 @classmethod
50 @classmethod
46 def wait_until_dead(cls):
51 def wait_until_dead(cls):
47 """Wait for the server process to terminate after shutdown"""
52 """Wait for the server process to terminate after shutdown"""
48 for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
53 for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
49 if cls.notebook.poll() is not None:
54 if cls.notebook.poll() is not None:
50 return
55 return
51 time.sleep(POLL_INTERVAL)
56 time.sleep(POLL_INTERVAL)
52
57
53 raise TimeoutError("Undead notebook server")
58 raise TimeoutError("Undead notebook server")
54
59
55 @classmethod
60 @classmethod
56 def setup_class(cls):
61 def setup_class(cls):
57 cls.ipython_dir = TemporaryDirectory()
62 cls.ipython_dir = TemporaryDirectory()
58 cls.notebook_dir = TemporaryDirectory()
63 cls.notebook_dir = TemporaryDirectory()
59 notebook_args = [
64 notebook_args = [
60 sys.executable, '-c',
65 sys.executable, '-c',
61 'from IPython.html.notebookapp import launch_new_instance; launch_new_instance()',
66 'from IPython.html.notebookapp import launch_new_instance; launch_new_instance()',
62 '--port=%d' % cls.port,
67 '--port=%d' % cls.port,
63 '--port-retries=0', # Don't try any other ports
68 '--port-retries=0', # Don't try any other ports
64 '--no-browser',
69 '--no-browser',
65 '--ipython-dir=%s' % cls.ipython_dir.name,
70 '--ipython-dir=%s' % cls.ipython_dir.name,
66 '--notebook-dir=%s' % cls.notebook_dir.name,
71 '--notebook-dir=%s' % cls.notebook_dir.name,
67 ]
72 ]
68 cls.notebook = Popen(notebook_args,
73 cls.notebook = Popen(notebook_args,
69 stdout=nose.iptest_stdstreams_fileno(),
74 stdout=nose.iptest_stdstreams_fileno(),
70 stderr=STDOUT,
75 stderr=STDOUT,
71 )
76 )
72 cls.wait_until_alive()
77 cls.wait_until_alive()
73
78
74 @classmethod
79 @classmethod
75 def teardown_class(cls):
80 def teardown_class(cls):
76 cls.notebook.terminate()
81 cls.notebook.terminate()
77 cls.ipython_dir.cleanup()
82 cls.ipython_dir.cleanup()
78 cls.notebook_dir.cleanup()
83 cls.notebook_dir.cleanup()
79 cls.wait_until_dead()
84 cls.wait_until_dead()
80
85
81 @classmethod
86 @classmethod
82 def base_url(cls):
87 def base_url(cls):
83 return 'http://localhost:%i/' % cls.port
88 return 'http://localhost:%i/' % cls.port
84
89
85
90
86 @contextmanager
91 @contextmanager
87 def assert_http_error(status, msg=None):
92 def assert_http_error(status, msg=None):
88 try:
93 try:
89 yield
94 yield
90 except requests.HTTPError as e:
95 except requests.HTTPError as e:
91 real_status = e.response.status_code
96 real_status = e.response.status_code
92 assert real_status == status, \
97 assert real_status == status, \
93 "Expected status %d, got %d" % (real_status, status)
98 "Expected status %d, got %d" % (real_status, status)
94 if msg:
99 if msg:
95 assert msg in str(e), e
100 assert msg in str(e), e
96 else:
101 else:
97 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