test_sessions_api.py
124 lines
| 3.9 KiB
| text/x-python
|
PythonLexer
Zachary Sailer
|
r13044 | """Test the sessions web service API.""" | ||
Thomas Kluyver
|
r13401 | import errno | ||
Thomas Kluyver
|
r13093 | import io | ||
Zachary Sailer
|
r13044 | import os | ||
import json | ||||
import requests | ||||
Thomas Kluyver
|
r13093 | import shutil | ||
Thomas Kluyver
|
r19570 | import time | ||
Thomas Kluyver
|
r13093 | |||
pjoin = os.path.join | ||||
Zachary Sailer
|
r13044 | |||
Zachary Sailer
|
r13048 | from IPython.html.utils import url_path_join | ||
Thomas Kluyver
|
r13099 | from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error | ||
MinRK
|
r18607 | from IPython.nbformat.v4 import new_notebook | ||
from IPython.nbformat import write | ||||
Thomas Kluyver
|
r13093 | |||
class SessionAPI(object): | ||||
"""Wrapper for notebook API calls.""" | ||||
def __init__(self, base_url): | ||||
self.base_url = base_url | ||||
def _req(self, verb, path, body=None): | ||||
response = requests.request(verb, | ||||
url_path_join(self.base_url, 'api/sessions', path), data=body) | ||||
if 400 <= response.status_code < 600: | ||||
try: | ||||
response.reason = response.json()['message'] | ||||
except: | ||||
pass | ||||
response.raise_for_status() | ||||
return response | ||||
def list(self): | ||||
return self._req('GET', '') | ||||
def get(self, id): | ||||
return self._req('GET', id) | ||||
Min RK
|
r18751 | def create(self, path, kernel_name='python'): | ||
body = json.dumps({'notebook': {'path':path}, | ||||
Thomas Kluyver
|
r17222 | 'kernel': {'name': kernel_name}}) | ||
Thomas Kluyver
|
r13093 | return self._req('POST', '', body) | ||
Min RK
|
r18751 | def modify(self, id, path): | ||
body = json.dumps({'notebook': {'path':path}}) | ||||
Thomas Kluyver
|
r13093 | return self._req('PATCH', id, body) | ||
def delete(self, id): | ||||
return self._req('DELETE', id) | ||||
Zachary Sailer
|
r13044 | |||
class SessionAPITest(NotebookTestBase): | ||||
"""Test the sessions web service API""" | ||||
Thomas Kluyver
|
r13093 | def setUp(self): | ||
nbdir = self.notebook_dir.name | ||||
Thomas Kluyver
|
r13401 | try: | ||
os.mkdir(pjoin(nbdir, 'foo')) | ||||
except OSError as e: | ||||
# Deleting the folder in an earlier test may have failed | ||||
if e.errno != errno.EEXIST: | ||||
raise | ||||
Thomas Kluyver
|
r13093 | |||
Thomas Kluyver
|
r13657 | with io.open(pjoin(nbdir, 'foo', 'nb1.ipynb'), 'w', | ||
encoding='utf-8') as f: | ||||
MinRK
|
r18584 | nb = new_notebook() | ||
Min RK
|
r18613 | write(nb, f, version=4) | ||
Thomas Kluyver
|
r13093 | |||
self.sess_api = SessionAPI(self.base_url()) | ||||
def tearDown(self): | ||||
for session in self.sess_api.list().json(): | ||||
self.sess_api.delete(session['id']) | ||||
Thomas Kluyver
|
r19570 | # This is necessary in some situations on Windows: without it, it | ||
# fails to delete the directory because something is still using it. I | ||||
# think there is a brief period after the kernel terminates where | ||||
# Windows still treats its working directory as in use. On my Windows | ||||
# VM, 0.01s is not long enough, but 0.1s appears to work reliably. | ||||
# -- TK, 15 December 2014 | ||||
time.sleep(0.1) | ||||
Thomas Kluyver
|
r13401 | shutil.rmtree(pjoin(self.notebook_dir.name, 'foo'), | ||
ignore_errors=True) | ||||
Thomas Kluyver
|
r13093 | |||
def test_create(self): | ||||
sessions = self.sess_api.list().json() | ||||
self.assertEqual(len(sessions), 0) | ||||
Min RK
|
r18751 | resp = self.sess_api.create('foo/nb1.ipynb') | ||
Thomas Kluyver
|
r13093 | self.assertEqual(resp.status_code, 201) | ||
newsession = resp.json() | ||||
self.assertIn('id', newsession) | ||||
Min RK
|
r18751 | self.assertEqual(newsession['notebook']['path'], 'foo/nb1.ipynb') | ||
Brian E. Granger
|
r13116 | self.assertEqual(resp.headers['Location'], '/api/sessions/{0}'.format(newsession['id'])) | ||
Thomas Kluyver
|
r13093 | |||
sessions = self.sess_api.list().json() | ||||
self.assertEqual(sessions, [newsession]) | ||||
# Retrieve it | ||||
sid = newsession['id'] | ||||
Thomas Kluyver
|
r13094 | got = self.sess_api.get(sid).json() | ||
Thomas Kluyver
|
r13093 | self.assertEqual(got, newsession) | ||
def test_delete(self): | ||||
Min RK
|
r18751 | newsession = self.sess_api.create('foo/nb1.ipynb').json() | ||
Thomas Kluyver
|
r13093 | sid = newsession['id'] | ||
resp = self.sess_api.delete(sid) | ||||
self.assertEqual(resp.status_code, 204) | ||||
sessions = self.sess_api.list().json() | ||||
self.assertEqual(sessions, []) | ||||
Thomas Kluyver
|
r13099 | with assert_http_error(404): | ||
self.sess_api.get(sid) | ||||
Thomas Kluyver
|
r13093 | |||
def test_modify(self): | ||||
Min RK
|
r18751 | newsession = self.sess_api.create('foo/nb1.ipynb').json() | ||
Thomas Kluyver
|
r13093 | sid = newsession['id'] | ||
Min RK
|
r18751 | changed = self.sess_api.modify(sid, 'nb2.ipynb').json() | ||
Thomas Kluyver
|
r13093 | self.assertEqual(changed['id'], sid) | ||
Min RK
|
r18751 | self.assertEqual(changed['notebook']['path'], 'nb2.ipynb') | ||