test_build_api.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # Copyright (c) Jupyter Development Team.
  2. # Distributed under the terms of the Modified BSD License.
  3. """Test the kernels service API."""
  4. import asyncio
  5. import json
  6. import os
  7. from tempfile import TemporaryDirectory
  8. import pytest
  9. import tornado
  10. def expected_http_error(error, expected_code, expected_message=None):
  11. """Check that the error matches the expected output error."""
  12. e = error.value
  13. if isinstance(e, tornado.web.HTTPError):
  14. if expected_code != e.status_code:
  15. return False
  16. return expected_message is None or expected_message == str(e)
  17. elif any(
  18. [
  19. isinstance(e, tornado.httpclient.HTTPClientError),
  20. isinstance(e, tornado.httpclient.HTTPError),
  21. ]
  22. ):
  23. if expected_code != e.code:
  24. return False
  25. if expected_message:
  26. message = json.loads(e.response.body.decode())["message"]
  27. if expected_message != message:
  28. return False
  29. return True
  30. @pytest.fixture
  31. def build_api_tester(jp_serverapp, labapp, fetch_long):
  32. return BuildAPITester(labapp, fetch_long)
  33. class BuildAPITester:
  34. """Wrapper for build REST API requests"""
  35. url = "lab/api/build"
  36. def __init__(self, labapp, fetch_long):
  37. self.labapp = labapp
  38. self.fetch = fetch_long
  39. async def _req(self, verb, path, body=None):
  40. return await self.fetch(self.url + path, method=verb, body=body)
  41. async def getStatus(self):
  42. return await self._req("GET", "")
  43. async def build(self):
  44. return await self._req("POST", "", json.dumps({}))
  45. async def clear(self):
  46. return await self._req("DELETE", "")
  47. @pytest.mark.slow
  48. class TestBuildAPI:
  49. def tempdir(self):
  50. td = TemporaryDirectory()
  51. self.tempdirs.append(td)
  52. return td.name
  53. def setUp(self):
  54. # Any TemporaryDirectory objects appended to this list will be cleaned
  55. # up at the end of the test run.
  56. self.tempdirs = []
  57. # TODO(@echarles) Move the cleanup in the fixture.
  58. @self.addCleanup
  59. def cleanup_tempdirs():
  60. for d in self.tempdirs:
  61. d.cleanup()
  62. # @pytest.mark.timeout(timeout=30)
  63. # @pytest.mark.gen_test(timeout=30)
  64. async def test_get_status(self, build_api_tester):
  65. """Make sure there are no kernels running at the start"""
  66. r = await build_api_tester.getStatus()
  67. res = r.body.decode()
  68. resp = json.loads(res)
  69. assert "status" in resp
  70. assert "message" in resp
  71. # @pytest.mark.gen_test(timeout=30)
  72. # FIXME
  73. @pytest.mark.skipif(os.name == "nt", reason="Currently failing on windows")
  74. async def test_build(self, build_api_tester):
  75. r = await build_api_tester.build()
  76. assert r.code == 200
  77. # @pytest.mark.gen_test(timeout=30)
  78. # FIXME
  79. @pytest.mark.skipif(os.name == "nt", reason="Currently failing on windows")
  80. async def test_clear(self, build_api_tester):
  81. with pytest.raises(tornado.httpclient.HTTPClientError) as e:
  82. r = await build_api_tester.clear()
  83. res = r.body.decode()
  84. assert expected_http_error(e, 500)
  85. loop = asyncio.get_event_loop()
  86. asyncio.ensure_future(build_api_tester.build(), loop=loop) # noqa RUF006
  87. while True:
  88. r = await build_api_tester.getStatus()
  89. res = r.body.decode()
  90. resp = json.loads(res)
  91. if resp["status"] == "building":
  92. break
  93. r = await build_api_tester.clear()
  94. assert r.code == 204