test_kernelspecs_api.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # coding: utf-8
  2. """Test the kernel specs webservice API."""
  3. import errno
  4. import io
  5. import json
  6. import os
  7. import shutil
  8. pjoin = os.path.join
  9. import requests
  10. from jupyter_client.kernelspec import NATIVE_KERNEL_NAME
  11. from notebook.utils import url_path_join, url_escape
  12. from notebook.tests.launchnotebook import NotebookTestBase, assert_http_error
  13. # Copied from jupyter_client.tests.test_kernelspec so updating that doesn't
  14. # break these tests
  15. sample_kernel_json = {'argv':['cat', '{connection_file}'],
  16. 'display_name':'Test kernel',
  17. }
  18. some_resource = u"The very model of a modern major general"
  19. class KernelSpecAPI(object):
  20. """Wrapper for notebook API calls."""
  21. def __init__(self, request):
  22. self.request = request
  23. def _req(self, verb, path, body=None):
  24. response = self.request(verb,
  25. path,
  26. data=body,
  27. )
  28. response.raise_for_status()
  29. return response
  30. def list(self):
  31. return self._req('GET', 'api/kernelspecs')
  32. def kernel_spec_info(self, name):
  33. return self._req('GET', url_path_join('api/kernelspecs', name))
  34. def kernel_resource(self, name, path):
  35. return self._req('GET', url_path_join('kernelspecs', name, path))
  36. class APITest(NotebookTestBase):
  37. """Test the kernelspec web service API"""
  38. def setUp(self):
  39. self.create_spec('sample')
  40. self.create_spec('sample 2')
  41. self.ks_api = KernelSpecAPI(self.request)
  42. def create_spec(self, name):
  43. sample_kernel_dir = pjoin(self.data_dir, 'kernels', name)
  44. try:
  45. os.makedirs(sample_kernel_dir)
  46. except OSError as e:
  47. if e.errno != errno.EEXIST:
  48. raise
  49. with open(pjoin(sample_kernel_dir, 'kernel.json'), 'w') as f:
  50. json.dump(sample_kernel_json, f)
  51. with io.open(pjoin(sample_kernel_dir, 'resource.txt'), 'w',
  52. encoding='utf-8') as f:
  53. f.write(some_resource)
  54. def test_list_kernelspecs_bad(self):
  55. """Can list kernelspecs when one is invalid"""
  56. bad_kernel_dir = pjoin(self.data_dir, 'kernels', 'bad')
  57. try:
  58. os.makedirs(bad_kernel_dir)
  59. except OSError as e:
  60. if e.errno != errno.EEXIST:
  61. raise
  62. with open(pjoin(bad_kernel_dir, 'kernel.json'), 'w') as f:
  63. f.write("garbage")
  64. model = self.ks_api.list().json()
  65. assert isinstance(model, dict)
  66. self.assertEqual(model['default'], NATIVE_KERNEL_NAME)
  67. specs = model['kernelspecs']
  68. assert isinstance(specs, dict)
  69. # 2: the sample kernelspec created in setUp, and the native Python kernel
  70. self.assertGreaterEqual(len(specs), 2)
  71. shutil.rmtree(bad_kernel_dir)
  72. def test_list_kernelspecs(self):
  73. model = self.ks_api.list().json()
  74. assert isinstance(model, dict)
  75. self.assertEqual(model['default'], NATIVE_KERNEL_NAME)
  76. specs = model['kernelspecs']
  77. assert isinstance(specs, dict)
  78. # 2: the sample kernelspec created in setUp, and the native Python kernel
  79. self.assertGreaterEqual(len(specs), 2)
  80. def is_sample_kernelspec(s):
  81. return s['name'] == 'sample' and s['spec']['display_name'] == 'Test kernel'
  82. def is_default_kernelspec(s):
  83. return s['name'] == NATIVE_KERNEL_NAME and s['spec']['display_name'].startswith("Python")
  84. assert any(is_sample_kernelspec(s) for s in specs.values()), specs
  85. assert any(is_default_kernelspec(s) for s in specs.values()), specs
  86. def test_get_kernelspec(self):
  87. model = self.ks_api.kernel_spec_info('Sample').json() # Case insensitive
  88. self.assertEqual(model['name'].lower(), 'sample')
  89. self.assertIsInstance(model['spec'], dict)
  90. self.assertEqual(model['spec']['display_name'], 'Test kernel')
  91. self.assertIsInstance(model['resources'], dict)
  92. def test_get_kernelspec_spaces(self):
  93. model = self.ks_api.kernel_spec_info('sample%202').json()
  94. self.assertEqual(model['name'].lower(), 'sample 2')
  95. def test_get_nonexistant_kernelspec(self):
  96. with assert_http_error(404):
  97. self.ks_api.kernel_spec_info('nonexistant')
  98. def test_get_kernel_resource_file(self):
  99. res = self.ks_api.kernel_resource('sAmple', 'resource.txt')
  100. self.assertEqual(res.text, some_resource)
  101. def test_get_nonexistant_resource(self):
  102. with assert_http_error(404):
  103. self.ks_api.kernel_resource('nonexistant', 'resource.txt')
  104. with assert_http_error(404):
  105. self.ks_api.kernel_resource('sample', 'nonexistant.txt')