##// END OF EJS Templates
Add tests and fix some issues...
Thomas Kluyver -
Show More
@@ -1,222 +1,227 b''
1 """A base class session manager.
1 """A base class session manager.
2
2
3 Authors:
3 Authors:
4
4
5 * Zach Sailer
5 * Zach Sailer
6 """
6 """
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2013 The IPython Development Team
9 # Copyright (C) 2013 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import uuid
19 import uuid
20 import sqlite3
20 import sqlite3
21
21
22 from tornado import web
22 from tornado import web
23
23
24 from IPython.config.configurable import LoggingConfigurable
24 from IPython.config.configurable import LoggingConfigurable
25 from IPython.utils.py3compat import unicode_type
25 from IPython.utils.py3compat import unicode_type
26 from IPython.utils.traitlets import Instance
26 from IPython.utils.traitlets import Instance
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Classes
29 # Classes
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 class SessionManager(LoggingConfigurable):
32 class SessionManager(LoggingConfigurable):
33
33
34 kernel_manager = Instance('IPython.html.services.kernels.kernelmanager.MappingKernelManager')
34 kernel_manager = Instance('IPython.html.services.kernels.kernelmanager.MappingKernelManager')
35 contents_manager = Instance('IPython.html.services.contents.manager.ContentsManager', args=())
35 contents_manager = Instance('IPython.html.services.contents.manager.ContentsManager', args=())
36
36
37 # Session database initialized below
37 # Session database initialized below
38 _cursor = None
38 _cursor = None
39 _connection = None
39 _connection = None
40 _columns = {'session_id', 'name', 'path', 'kernel_id'}
40 _columns = {'session_id', 'name', 'path', 'kernel_id'}
41
41
42 @property
42 @property
43 def cursor(self):
43 def cursor(self):
44 """Start a cursor and create a database called 'session'"""
44 """Start a cursor and create a database called 'session'"""
45 if self._cursor is None:
45 if self._cursor is None:
46 self._cursor = self.connection.cursor()
46 self._cursor = self.connection.cursor()
47 self._cursor.execute("""CREATE TABLE session
47 self._cursor.execute("""CREATE TABLE session
48 (session_id, name, path, kernel_id)""")
48 (session_id, name, path, kernel_id)""")
49 return self._cursor
49 return self._cursor
50
50
51 @property
51 @property
52 def connection(self):
52 def connection(self):
53 """Start a database connection"""
53 """Start a database connection"""
54 if self._connection is None:
54 if self._connection is None:
55 self._connection = sqlite3.connect(':memory:')
55 self._connection = sqlite3.connect(':memory:')
56 self._connection.row_factory = sqlite3.Row
56 self._connection.row_factory = sqlite3.Row
57 return self._connection
57 return self._connection
58
58
59 def __del__(self):
59 def __del__(self):
60 """Close connection once SessionManager closes"""
60 """Close connection once SessionManager closes"""
61 self.cursor.close()
61 self.cursor.close()
62
62
63 def session_exists(self, name, path):
63 def session_exists(self, name, path):
64 """Check to see if the session for a given notebook exists"""
64 """Check to see if the session for a given notebook exists"""
65 self.cursor.execute("SELECT * FROM session WHERE name=? AND path=?", (name, path))
65 self.cursor.execute("SELECT * FROM session WHERE name=? AND path=?", (name, path))
66 reply = self.cursor.fetchone()
66 reply = self.cursor.fetchone()
67 if reply is None:
67 if reply is None:
68 return False
68 return False
69 else:
69 else:
70 return True
70 return True
71
71
72 def new_session_id(self):
72 def new_session_id(self):
73 "Create a uuid for a new session"
73 "Create a uuid for a new session"
74 return unicode_type(uuid.uuid4())
74 return unicode_type(uuid.uuid4())
75
75
76 def create_session(self, name=None, path=None, kernel_name='python'):
76 def create_session(self, name=None, path=None, kernel_name='python'):
77 """Creates a session and returns its model"""
77 """Creates a session and returns its model"""
78 session_id = self.new_session_id()
78 session_id = self.new_session_id()
79 # allow nbm to specify kernels cwd
79 # allow nbm to specify kernels cwd
80 kernel_path = self.contents_manager.get_kernel_path(name=name, path=path)
80 kernel_path = self.contents_manager.get_kernel_path(name=name, path=path)
81 kernel_id = self.kernel_manager.start_kernel(path=kernel_path,
81 kernel_id = self.kernel_manager.start_kernel(path=kernel_path,
82 kernel_name=kernel_name)
82 kernel_name=kernel_name)
83 return self.save_session(session_id, name=name, path=path,
83 return self.save_session(session_id, name=name, path=path,
84 kernel_id=kernel_id)
84 kernel_id=kernel_id)
85
85
86 def save_session(self, session_id, name=None, path=None, kernel_id=None):
86 def save_session(self, session_id, name=None, path=None, kernel_id=None):
87 """Saves the items for the session with the given session_id
87 """Saves the items for the session with the given session_id
88
88
89 Given a session_id (and any other of the arguments), this method
89 Given a session_id (and any other of the arguments), this method
90 creates a row in the sqlite session database that holds the information
90 creates a row in the sqlite session database that holds the information
91 for a session.
91 for a session.
92
92
93 Parameters
93 Parameters
94 ----------
94 ----------
95 session_id : str
95 session_id : str
96 uuid for the session; this method must be given a session_id
96 uuid for the session; this method must be given a session_id
97 name : str
97 name : str
98 the .ipynb notebook name that started the session
98 the .ipynb notebook name that started the session
99 path : str
99 path : str
100 the path to the named notebook
100 the path to the named notebook
101 kernel_id : str
101 kernel_id : str
102 a uuid for the kernel associated with this session
102 a uuid for the kernel associated with this session
103
103
104 Returns
104 Returns
105 -------
105 -------
106 model : dict
106 model : dict
107 a dictionary of the session model
107 a dictionary of the session model
108 """
108 """
109 self.cursor.execute("INSERT INTO session VALUES (?,?,?,?)",
109 self.cursor.execute("INSERT INTO session VALUES (?,?,?,?)",
110 (session_id, name, path, kernel_id)
110 (session_id, name, path, kernel_id)
111 )
111 )
112 return self.get_session(session_id=session_id)
112 return self.get_session(session_id=session_id)
113
113
114 def get_session(self, **kwargs):
114 def get_session(self, **kwargs):
115 """Returns the model for a particular session.
115 """Returns the model for a particular session.
116
116
117 Takes a keyword argument and searches for the value in the session
117 Takes a keyword argument and searches for the value in the session
118 database, then returns the rest of the session's info.
118 database, then returns the rest of the session's info.
119
119
120 Parameters
120 Parameters
121 ----------
121 ----------
122 **kwargs : keyword argument
122 **kwargs : keyword argument
123 must be given one of the keywords and values from the session database
123 must be given one of the keywords and values from the session database
124 (i.e. session_id, name, path, kernel_id)
124 (i.e. session_id, name, path, kernel_id)
125
125
126 Returns
126 Returns
127 -------
127 -------
128 model : dict
128 model : dict
129 returns a dictionary that includes all the information from the
129 returns a dictionary that includes all the information from the
130 session described by the kwarg.
130 session described by the kwarg.
131 """
131 """
132 if not kwargs:
132 if not kwargs:
133 raise TypeError("must specify a column to query")
133 raise TypeError("must specify a column to query")
134
134
135 conditions = []
135 conditions = []
136 for column in kwargs.keys():
136 for column in kwargs.keys():
137 if column not in self._columns:
137 if column not in self._columns:
138 raise TypeError("No such column: %r", column)
138 raise TypeError("No such column: %r", column)
139 conditions.append("%s=?" % column)
139 conditions.append("%s=?" % column)
140
140
141 query = "SELECT * FROM session WHERE %s" % (' AND '.join(conditions))
141 query = "SELECT * FROM session WHERE %s" % (' AND '.join(conditions))
142
142
143 self.cursor.execute(query, list(kwargs.values()))
143 self.cursor.execute(query, list(kwargs.values()))
144 try:
144 try:
145 row = self.cursor.fetchone()
145 row = self.cursor.fetchone()
146 except KeyError:
146 except KeyError:
147 # The kernel is missing, so the session just got deleted.
147 # The kernel is missing, so the session just got deleted.
148 row = None
148 row = None
149
149
150 if row is None:
150 if row is None:
151 q = []
151 q = []
152 for key, value in kwargs.items():
152 for key, value in kwargs.items():
153 q.append("%s=%r" % (key, value))
153 q.append("%s=%r" % (key, value))
154
154
155 raise web.HTTPError(404, u'Session not found: %s' % (', '.join(q)))
155 raise web.HTTPError(404, u'Session not found: %s' % (', '.join(q)))
156
156
157 return self.row_to_model(row)
157 return self.row_to_model(row)
158
158
159 def update_session(self, session_id, **kwargs):
159 def update_session(self, session_id, **kwargs):
160 """Updates the values in the session database.
160 """Updates the values in the session database.
161
161
162 Changes the values of the session with the given session_id
162 Changes the values of the session with the given session_id
163 with the values from the keyword arguments.
163 with the values from the keyword arguments.
164
164
165 Parameters
165 Parameters
166 ----------
166 ----------
167 session_id : str
167 session_id : str
168 a uuid that identifies a session in the sqlite3 database
168 a uuid that identifies a session in the sqlite3 database
169 **kwargs : str
169 **kwargs : str
170 the key must correspond to a column title in session database,
170 the key must correspond to a column title in session database,
171 and the value replaces the current value in the session
171 and the value replaces the current value in the session
172 with session_id.
172 with session_id.
173 """
173 """
174 self.get_session(session_id=session_id)
174 self.get_session(session_id=session_id)
175
175
176 if not kwargs:
176 if not kwargs:
177 # no changes
177 # no changes
178 return
178 return
179
179
180 sets = []
180 sets = []
181 for column in kwargs.keys():
181 for column in kwargs.keys():
182 if column not in self._columns:
182 if column not in self._columns:
183 raise TypeError("No such column: %r" % column)
183 raise TypeError("No such column: %r" % column)
184 sets.append("%s=?" % column)
184 sets.append("%s=?" % column)
185 query = "UPDATE session SET %s WHERE session_id=?" % (', '.join(sets))
185 query = "UPDATE session SET %s WHERE session_id=?" % (', '.join(sets))
186 self.cursor.execute(query, list(kwargs.values()) + [session_id])
186 self.cursor.execute(query, list(kwargs.values()) + [session_id])
187
187
188 def row_to_model(self, row):
188 def row_to_model(self, row):
189 """Takes sqlite database session row and turns it into a dictionary"""
189 """Takes sqlite database session row and turns it into a dictionary"""
190 if row['kernel_id'] not in self.kernel_manager:
190 if row['kernel_id'] not in self.kernel_manager:
191 # The kernel was killed or died without deleting the session.
191 # The kernel was killed or died without deleting the session.
192 self.delete_session(row['session_id'])
192 # We can't use delete_session here because that tries to find
193 # and shut down the kernel.
194 self.cursor.execute("DELETE FROM session WHERE session_id=?",
195 (row['session_id'],))
193 raise KeyError
196 raise KeyError
194
197
195 model = {
198 model = {
196 'id': row['session_id'],
199 'id': row['session_id'],
197 'notebook': {
200 'notebook': {
198 'name': row['name'],
201 'name': row['name'],
199 'path': row['path']
202 'path': row['path']
200 },
203 },
201 'kernel': self.kernel_manager.kernel_model(row['kernel_id'])
204 'kernel': self.kernel_manager.kernel_model(row['kernel_id'])
202 }
205 }
203 return model
206 return model
204
207
205 def list_sessions(self):
208 def list_sessions(self):
206 """Returns a list of dictionaries containing all the information from
209 """Returns a list of dictionaries containing all the information from
207 the session database"""
210 the session database"""
208 c = self.cursor.execute("SELECT * FROM session")
211 c = self.cursor.execute("SELECT * FROM session")
209 result = []
212 result = []
210 for row in c:
213 # We need to use fetchall() here, because row_to_model can delete rows,
214 # which messes up the cursor if we're iterating over rows.
215 for row in c.fetchall():
211 try:
216 try:
212 result.append(self.row_to_model(row))
217 result.append(self.row_to_model(row))
213 except KeyError:
218 except KeyError:
214 pass
219 pass
215 return result
220 return result
216
221
217 def delete_session(self, session_id):
222 def delete_session(self, session_id):
218 """Deletes the row in the session database with given session_id"""
223 """Deletes the row in the session database with given session_id"""
219 # Check that session exists before deleting
224 # Check that session exists before deleting
220 session = self.get_session(session_id=session_id)
225 session = self.get_session(session_id=session_id)
221 self.kernel_manager.shutdown_kernel(session['kernel']['id'])
226 self.kernel_manager.shutdown_kernel(session['kernel']['id'])
222 self.cursor.execute("DELETE FROM session WHERE session_id=?", (session_id,))
227 self.cursor.execute("DELETE FROM session WHERE session_id=?", (session_id,))
@@ -1,105 +1,140 b''
1 """Tests for the session manager."""
1 """Tests for the session manager."""
2
2
3 from unittest import TestCase
3 from unittest import TestCase
4
4
5 from tornado import web
5 from tornado import web
6
6
7 from ..sessionmanager import SessionManager
7 from ..sessionmanager import SessionManager
8 from IPython.html.services.kernels.kernelmanager import MappingKernelManager
8 from IPython.html.services.kernels.kernelmanager import MappingKernelManager
9
9
10 class DummyKernel(object):
10 class DummyKernel(object):
11 def __init__(self, kernel_name='python'):
11 def __init__(self, kernel_name='python'):
12 self.kernel_name = kernel_name
12 self.kernel_name = kernel_name
13
13
14 class DummyMKM(MappingKernelManager):
14 class DummyMKM(MappingKernelManager):
15 """MappingKernelManager interface that doesn't start kernels, for testing"""
15 """MappingKernelManager interface that doesn't start kernels, for testing"""
16 def __init__(self, *args, **kwargs):
16 def __init__(self, *args, **kwargs):
17 super(DummyMKM, self).__init__(*args, **kwargs)
17 super(DummyMKM, self).__init__(*args, **kwargs)
18 self.id_letters = iter(u'ABCDEFGHIJK')
18 self.id_letters = iter(u'ABCDEFGHIJK')
19
19
20 def _new_id(self):
20 def _new_id(self):
21 return next(self.id_letters)
21 return next(self.id_letters)
22
22
23 def start_kernel(self, kernel_id=None, path=None, kernel_name='python', **kwargs):
23 def start_kernel(self, kernel_id=None, path=None, kernel_name='python', **kwargs):
24 kernel_id = kernel_id or self._new_id()
24 kernel_id = kernel_id or self._new_id()
25 self._kernels[kernel_id] = DummyKernel(kernel_name=kernel_name)
25 self._kernels[kernel_id] = DummyKernel(kernel_name=kernel_name)
26 return kernel_id
26 return kernel_id
27
27
28 def shutdown_kernel(self, kernel_id, now=False):
28 def shutdown_kernel(self, kernel_id, now=False):
29 del self._kernels[kernel_id]
29 del self._kernels[kernel_id]
30
30
31 class TestSessionManager(TestCase):
31 class TestSessionManager(TestCase):
32
32
33 def test_get_session(self):
33 def test_get_session(self):
34 sm = SessionManager(kernel_manager=DummyMKM())
34 sm = SessionManager(kernel_manager=DummyMKM())
35 session_id = sm.create_session(name='test.ipynb', path='/path/to/',
35 session_id = sm.create_session(name='test.ipynb', path='/path/to/',
36 kernel_name='bar')['id']
36 kernel_name='bar')['id']
37 model = sm.get_session(session_id=session_id)
37 model = sm.get_session(session_id=session_id)
38 expected = {'id':session_id,
38 expected = {'id':session_id,
39 'notebook':{'name':u'test.ipynb', 'path': u'/path/to/'},
39 'notebook':{'name':u'test.ipynb', 'path': u'/path/to/'},
40 'kernel': {'id':u'A', 'name': 'bar'}}
40 'kernel': {'id':u'A', 'name': 'bar'}}
41 self.assertEqual(model, expected)
41 self.assertEqual(model, expected)
42
42
43 def test_bad_get_session(self):
43 def test_bad_get_session(self):
44 # Should raise error if a bad key is passed to the database.
44 # Should raise error if a bad key is passed to the database.
45 sm = SessionManager(kernel_manager=DummyMKM())
45 sm = SessionManager(kernel_manager=DummyMKM())
46 session_id = sm.create_session(name='test.ipynb', path='/path/to/',
46 session_id = sm.create_session(name='test.ipynb', path='/path/to/',
47 kernel_name='foo')['id']
47 kernel_name='foo')['id']
48 self.assertRaises(TypeError, sm.get_session, bad_id=session_id) # Bad keyword
48 self.assertRaises(TypeError, sm.get_session, bad_id=session_id) # Bad keyword
49
49
50 def test_get_session_dead_kernel(self):
51 sm = SessionManager(kernel_manager=DummyMKM())
52 session = sm.create_session(name='test1.ipynb', path='/path/to/1/', kernel_name='python')
53 # kill the kernel
54 sm.kernel_manager.shutdown_kernel(session['kernel']['id'])
55 with self.assertRaises(KeyError):
56 sm.get_session(session_id=session['id'])
57 # no sessions left
58 listed = sm.list_sessions()
59 self.assertEqual(listed, [])
60
50 def test_list_sessions(self):
61 def test_list_sessions(self):
51 sm = SessionManager(kernel_manager=DummyMKM())
62 sm = SessionManager(kernel_manager=DummyMKM())
52 sessions = [
63 sessions = [
53 sm.create_session(name='test1.ipynb', path='/path/to/1/', kernel_name='python'),
64 sm.create_session(name='test1.ipynb', path='/path/to/1/', kernel_name='python'),
54 sm.create_session(name='test2.ipynb', path='/path/to/2/', kernel_name='python'),
65 sm.create_session(name='test2.ipynb', path='/path/to/2/', kernel_name='python'),
55 sm.create_session(name='test3.ipynb', path='/path/to/3/', kernel_name='python'),
66 sm.create_session(name='test3.ipynb', path='/path/to/3/', kernel_name='python'),
56 ]
67 ]
57 sessions = sm.list_sessions()
68 sessions = sm.list_sessions()
58 expected = [{'id':sessions[0]['id'], 'notebook':{'name':u'test1.ipynb',
69 expected = [{'id':sessions[0]['id'], 'notebook':{'name':u'test1.ipynb',
59 'path': u'/path/to/1/'}, 'kernel':{'id':u'A', 'name':'python'}},
70 'path': u'/path/to/1/'}, 'kernel':{'id':u'A', 'name':'python'}},
60 {'id':sessions[1]['id'], 'notebook': {'name':u'test2.ipynb',
71 {'id':sessions[1]['id'], 'notebook': {'name':u'test2.ipynb',
61 'path': u'/path/to/2/'}, 'kernel':{'id':u'B', 'name':'python'}},
72 'path': u'/path/to/2/'}, 'kernel':{'id':u'B', 'name':'python'}},
62 {'id':sessions[2]['id'], 'notebook':{'name':u'test3.ipynb',
73 {'id':sessions[2]['id'], 'notebook':{'name':u'test3.ipynb',
63 'path': u'/path/to/3/'}, 'kernel':{'id':u'C', 'name':'python'}}]
74 'path': u'/path/to/3/'}, 'kernel':{'id':u'C', 'name':'python'}}]
64 self.assertEqual(sessions, expected)
75 self.assertEqual(sessions, expected)
65
76
77 def test_list_sessions_dead_kernel(self):
78 sm = SessionManager(kernel_manager=DummyMKM())
79 sessions = [
80 sm.create_session(name='test1.ipynb', path='/path/to/1/', kernel_name='python'),
81 sm.create_session(name='test2.ipynb', path='/path/to/2/', kernel_name='python'),
82 ]
83 # kill one of the kernels
84 sm.kernel_manager.shutdown_kernel(sessions[0]['kernel']['id'])
85 listed = sm.list_sessions()
86 expected = [
87 {
88 'id': sessions[1]['id'],
89 'notebook': {
90 'name': u'test2.ipynb',
91 'path': u'/path/to/2/',
92 },
93 'kernel': {
94 'id': u'B',
95 'name':'python',
96 }
97 }
98 ]
99 self.assertEqual(listed, expected)
100
66 def test_update_session(self):
101 def test_update_session(self):
67 sm = SessionManager(kernel_manager=DummyMKM())
102 sm = SessionManager(kernel_manager=DummyMKM())
68 session_id = sm.create_session(name='test.ipynb', path='/path/to/',
103 session_id = sm.create_session(name='test.ipynb', path='/path/to/',
69 kernel_name='julia')['id']
104 kernel_name='julia')['id']
70 sm.update_session(session_id, name='new_name.ipynb')
105 sm.update_session(session_id, name='new_name.ipynb')
71 model = sm.get_session(session_id=session_id)
106 model = sm.get_session(session_id=session_id)
72 expected = {'id':session_id,
107 expected = {'id':session_id,
73 'notebook':{'name':u'new_name.ipynb', 'path': u'/path/to/'},
108 'notebook':{'name':u'new_name.ipynb', 'path': u'/path/to/'},
74 'kernel':{'id':u'A', 'name':'julia'}}
109 'kernel':{'id':u'A', 'name':'julia'}}
75 self.assertEqual(model, expected)
110 self.assertEqual(model, expected)
76
111
77 def test_bad_update_session(self):
112 def test_bad_update_session(self):
78 # try to update a session with a bad keyword ~ raise error
113 # try to update a session with a bad keyword ~ raise error
79 sm = SessionManager(kernel_manager=DummyMKM())
114 sm = SessionManager(kernel_manager=DummyMKM())
80 session_id = sm.create_session(name='test.ipynb', path='/path/to/',
115 session_id = sm.create_session(name='test.ipynb', path='/path/to/',
81 kernel_name='ir')['id']
116 kernel_name='ir')['id']
82 self.assertRaises(TypeError, sm.update_session, session_id=session_id, bad_kw='test.ipynb') # Bad keyword
117 self.assertRaises(TypeError, sm.update_session, session_id=session_id, bad_kw='test.ipynb') # Bad keyword
83
118
84 def test_delete_session(self):
119 def test_delete_session(self):
85 sm = SessionManager(kernel_manager=DummyMKM())
120 sm = SessionManager(kernel_manager=DummyMKM())
86 sessions = [
121 sessions = [
87 sm.create_session(name='test1.ipynb', path='/path/to/1/', kernel_name='python'),
122 sm.create_session(name='test1.ipynb', path='/path/to/1/', kernel_name='python'),
88 sm.create_session(name='test2.ipynb', path='/path/to/2/', kernel_name='python'),
123 sm.create_session(name='test2.ipynb', path='/path/to/2/', kernel_name='python'),
89 sm.create_session(name='test3.ipynb', path='/path/to/3/', kernel_name='python'),
124 sm.create_session(name='test3.ipynb', path='/path/to/3/', kernel_name='python'),
90 ]
125 ]
91 sm.delete_session(sessions[1]['id'])
126 sm.delete_session(sessions[1]['id'])
92 new_sessions = sm.list_sessions()
127 new_sessions = sm.list_sessions()
93 expected = [{'id':sessions[0]['id'], 'notebook':{'name':u'test1.ipynb',
128 expected = [{'id':sessions[0]['id'], 'notebook':{'name':u'test1.ipynb',
94 'path': u'/path/to/1/'}, 'kernel':{'id':u'A', 'name':'python'}},
129 'path': u'/path/to/1/'}, 'kernel':{'id':u'A', 'name':'python'}},
95 {'id':sessions[2]['id'], 'notebook':{'name':u'test3.ipynb',
130 {'id':sessions[2]['id'], 'notebook':{'name':u'test3.ipynb',
96 'path': u'/path/to/3/'}, 'kernel':{'id':u'C', 'name':'python'}}]
131 'path': u'/path/to/3/'}, 'kernel':{'id':u'C', 'name':'python'}}]
97 self.assertEqual(new_sessions, expected)
132 self.assertEqual(new_sessions, expected)
98
133
99 def test_bad_delete_session(self):
134 def test_bad_delete_session(self):
100 # try to delete a session that doesn't exist ~ raise error
135 # try to delete a session that doesn't exist ~ raise error
101 sm = SessionManager(kernel_manager=DummyMKM())
136 sm = SessionManager(kernel_manager=DummyMKM())
102 sm.create_session(name='test.ipynb', path='/path/to/', kernel_name='python')
137 sm.create_session(name='test.ipynb', path='/path/to/', kernel_name='python')
103 self.assertRaises(TypeError, sm.delete_session, bad_kwarg='23424') # Bad keyword
138 self.assertRaises(TypeError, sm.delete_session, bad_kwarg='23424') # Bad keyword
104 self.assertRaises(web.HTTPError, sm.delete_session, session_id='23424') # nonexistant
139 self.assertRaises(web.HTTPError, sm.delete_session, session_id='23424') # nonexistant
105
140
General Comments 0
You need to be logged in to leave comments. Login now