Extra type annotations in `test_server` (#13124)
This commit is contained in:
parent
6b99a66fe0
commit
f1145563f6
|
@ -0,0 +1 @@
|
||||||
|
Add type annotations to `tests.test_server`.
|
3
mypy.ini
3
mypy.ini
|
@ -113,6 +113,9 @@ disallow_untyped_defs = False
|
||||||
[mypy-tests.handlers.test_user_directory]
|
[mypy-tests.handlers.test_user_directory]
|
||||||
disallow_untyped_defs = True
|
disallow_untyped_defs = True
|
||||||
|
|
||||||
|
[mypy-tests.test_server]
|
||||||
|
disallow_untyped_defs = True
|
||||||
|
|
||||||
[mypy-tests.state.test_profile]
|
[mypy-tests.state.test_profile]
|
||||||
disallow_untyped_defs = True
|
disallow_untyped_defs = True
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from typing import Tuple
|
from typing import Awaitable, Callable, Dict, NoReturn, Optional, Tuple
|
||||||
|
|
||||||
from twisted.internet.defer import Deferred
|
from twisted.internet.defer import Deferred
|
||||||
from twisted.web.resource import Resource
|
from twisted.web.resource import Resource
|
||||||
|
@ -36,6 +36,7 @@ from synapse.util import Clock
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
from tests.http.server._base import test_disconnect
|
from tests.http.server._base import test_disconnect
|
||||||
from tests.server import (
|
from tests.server import (
|
||||||
|
FakeChannel,
|
||||||
FakeSite,
|
FakeSite,
|
||||||
ThreadedMemoryReactorClock,
|
ThreadedMemoryReactorClock,
|
||||||
make_request,
|
make_request,
|
||||||
|
@ -44,7 +45,7 @@ from tests.server import (
|
||||||
|
|
||||||
|
|
||||||
class JsonResourceTests(unittest.TestCase):
|
class JsonResourceTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self) -> None:
|
||||||
self.reactor = ThreadedMemoryReactorClock()
|
self.reactor = ThreadedMemoryReactorClock()
|
||||||
self.hs_clock = Clock(self.reactor)
|
self.hs_clock = Clock(self.reactor)
|
||||||
self.homeserver = setup_test_homeserver(
|
self.homeserver = setup_test_homeserver(
|
||||||
|
@ -54,7 +55,7 @@ class JsonResourceTests(unittest.TestCase):
|
||||||
reactor=self.reactor,
|
reactor=self.reactor,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_handler_for_request(self):
|
def test_handler_for_request(self) -> None:
|
||||||
"""
|
"""
|
||||||
JsonResource.handler_for_request gives correctly decoded URL args to
|
JsonResource.handler_for_request gives correctly decoded URL args to
|
||||||
the callback, while Twisted will give the raw bytes of URL query
|
the callback, while Twisted will give the raw bytes of URL query
|
||||||
|
@ -62,7 +63,9 @@ class JsonResourceTests(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
got_kwargs = {}
|
got_kwargs = {}
|
||||||
|
|
||||||
def _callback(request, **kwargs):
|
def _callback(
|
||||||
|
request: SynapseRequest, **kwargs: object
|
||||||
|
) -> Tuple[int, Dict[str, object]]:
|
||||||
got_kwargs.update(kwargs)
|
got_kwargs.update(kwargs)
|
||||||
return 200, kwargs
|
return 200, kwargs
|
||||||
|
|
||||||
|
@ -83,13 +86,13 @@ class JsonResourceTests(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(got_kwargs, {"room_id": "\N{SNOWMAN}"})
|
self.assertEqual(got_kwargs, {"room_id": "\N{SNOWMAN}"})
|
||||||
|
|
||||||
def test_callback_direct_exception(self):
|
def test_callback_direct_exception(self) -> None:
|
||||||
"""
|
"""
|
||||||
If the web callback raises an uncaught exception, it will be translated
|
If the web callback raises an uncaught exception, it will be translated
|
||||||
into a 500.
|
into a 500.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _callback(request, **kwargs):
|
def _callback(request: SynapseRequest, **kwargs: object) -> NoReturn:
|
||||||
raise Exception("boo")
|
raise Exception("boo")
|
||||||
|
|
||||||
res = JsonResource(self.homeserver)
|
res = JsonResource(self.homeserver)
|
||||||
|
@ -103,17 +106,17 @@ class JsonResourceTests(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(channel.result["code"], b"500")
|
self.assertEqual(channel.result["code"], b"500")
|
||||||
|
|
||||||
def test_callback_indirect_exception(self):
|
def test_callback_indirect_exception(self) -> None:
|
||||||
"""
|
"""
|
||||||
If the web callback raises an uncaught exception in a Deferred, it will
|
If the web callback raises an uncaught exception in a Deferred, it will
|
||||||
be translated into a 500.
|
be translated into a 500.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _throw(*args):
|
def _throw(*args: object) -> NoReturn:
|
||||||
raise Exception("boo")
|
raise Exception("boo")
|
||||||
|
|
||||||
def _callback(request, **kwargs):
|
def _callback(request: SynapseRequest, **kwargs: object) -> "Deferred[None]":
|
||||||
d = Deferred()
|
d: "Deferred[None]" = Deferred()
|
||||||
d.addCallback(_throw)
|
d.addCallback(_throw)
|
||||||
self.reactor.callLater(0.5, d.callback, True)
|
self.reactor.callLater(0.5, d.callback, True)
|
||||||
return make_deferred_yieldable(d)
|
return make_deferred_yieldable(d)
|
||||||
|
@ -129,13 +132,13 @@ class JsonResourceTests(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(channel.result["code"], b"500")
|
self.assertEqual(channel.result["code"], b"500")
|
||||||
|
|
||||||
def test_callback_synapseerror(self):
|
def test_callback_synapseerror(self) -> None:
|
||||||
"""
|
"""
|
||||||
If the web callback raises a SynapseError, it returns the appropriate
|
If the web callback raises a SynapseError, it returns the appropriate
|
||||||
status code and message set in it.
|
status code and message set in it.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _callback(request, **kwargs):
|
def _callback(request: SynapseRequest, **kwargs: object) -> NoReturn:
|
||||||
raise SynapseError(403, "Forbidden!!one!", Codes.FORBIDDEN)
|
raise SynapseError(403, "Forbidden!!one!", Codes.FORBIDDEN)
|
||||||
|
|
||||||
res = JsonResource(self.homeserver)
|
res = JsonResource(self.homeserver)
|
||||||
|
@ -151,12 +154,12 @@ class JsonResourceTests(unittest.TestCase):
|
||||||
self.assertEqual(channel.json_body["error"], "Forbidden!!one!")
|
self.assertEqual(channel.json_body["error"], "Forbidden!!one!")
|
||||||
self.assertEqual(channel.json_body["errcode"], "M_FORBIDDEN")
|
self.assertEqual(channel.json_body["errcode"], "M_FORBIDDEN")
|
||||||
|
|
||||||
def test_no_handler(self):
|
def test_no_handler(self) -> None:
|
||||||
"""
|
"""
|
||||||
If there is no handler to process the request, Synapse will return 400.
|
If there is no handler to process the request, Synapse will return 400.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _callback(request, **kwargs):
|
def _callback(request: SynapseRequest, **kwargs: object) -> None:
|
||||||
"""
|
"""
|
||||||
Not ever actually called!
|
Not ever actually called!
|
||||||
"""
|
"""
|
||||||
|
@ -175,14 +178,16 @@ class JsonResourceTests(unittest.TestCase):
|
||||||
self.assertEqual(channel.json_body["error"], "Unrecognized request")
|
self.assertEqual(channel.json_body["error"], "Unrecognized request")
|
||||||
self.assertEqual(channel.json_body["errcode"], "M_UNRECOGNIZED")
|
self.assertEqual(channel.json_body["errcode"], "M_UNRECOGNIZED")
|
||||||
|
|
||||||
def test_head_request(self):
|
def test_head_request(self) -> None:
|
||||||
"""
|
"""
|
||||||
JsonResource.handler_for_request gives correctly decoded URL args to
|
JsonResource.handler_for_request gives correctly decoded URL args to
|
||||||
the callback, while Twisted will give the raw bytes of URL query
|
the callback, while Twisted will give the raw bytes of URL query
|
||||||
arguments.
|
arguments.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _callback(request, **kwargs):
|
def _callback(
|
||||||
|
request: SynapseRequest, **kwargs: object
|
||||||
|
) -> Tuple[int, Dict[str, object]]:
|
||||||
return 200, {"result": True}
|
return 200, {"result": True}
|
||||||
|
|
||||||
res = JsonResource(self.homeserver)
|
res = JsonResource(self.homeserver)
|
||||||
|
@ -203,20 +208,21 @@ class JsonResourceTests(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
class OptionsResourceTests(unittest.TestCase):
|
class OptionsResourceTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self) -> None:
|
||||||
self.reactor = ThreadedMemoryReactorClock()
|
self.reactor = ThreadedMemoryReactorClock()
|
||||||
|
|
||||||
class DummyResource(Resource):
|
class DummyResource(Resource):
|
||||||
isLeaf = True
|
isLeaf = True
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request: SynapseRequest) -> bytes:
|
||||||
return request.path
|
# Type-ignore: mypy thinks request.path is Optional[Any], not bytes.
|
||||||
|
return request.path # type: ignore[return-value]
|
||||||
|
|
||||||
# Setup a resource with some children.
|
# Setup a resource with some children.
|
||||||
self.resource = OptionsResource()
|
self.resource = OptionsResource()
|
||||||
self.resource.putChild(b"res", DummyResource())
|
self.resource.putChild(b"res", DummyResource())
|
||||||
|
|
||||||
def _make_request(self, method, path):
|
def _make_request(self, method: bytes, path: bytes) -> FakeChannel:
|
||||||
"""Create a request from the method/path and return a channel with the response."""
|
"""Create a request from the method/path and return a channel with the response."""
|
||||||
# Create a site and query for the resource.
|
# Create a site and query for the resource.
|
||||||
site = SynapseSite(
|
site = SynapseSite(
|
||||||
|
@ -233,7 +239,7 @@ class OptionsResourceTests(unittest.TestCase):
|
||||||
channel = make_request(self.reactor, site, method, path, shorthand=False)
|
channel = make_request(self.reactor, site, method, path, shorthand=False)
|
||||||
return channel
|
return channel
|
||||||
|
|
||||||
def test_unknown_options_request(self):
|
def test_unknown_options_request(self) -> None:
|
||||||
"""An OPTIONS requests to an unknown URL still returns 204 No Content."""
|
"""An OPTIONS requests to an unknown URL still returns 204 No Content."""
|
||||||
channel = self._make_request(b"OPTIONS", b"/foo/")
|
channel = self._make_request(b"OPTIONS", b"/foo/")
|
||||||
self.assertEqual(channel.result["code"], b"204")
|
self.assertEqual(channel.result["code"], b"204")
|
||||||
|
@ -253,7 +259,7 @@ class OptionsResourceTests(unittest.TestCase):
|
||||||
"has CORS Headers header",
|
"has CORS Headers header",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_known_options_request(self):
|
def test_known_options_request(self) -> None:
|
||||||
"""An OPTIONS requests to an known URL still returns 204 No Content."""
|
"""An OPTIONS requests to an known URL still returns 204 No Content."""
|
||||||
channel = self._make_request(b"OPTIONS", b"/res/")
|
channel = self._make_request(b"OPTIONS", b"/res/")
|
||||||
self.assertEqual(channel.result["code"], b"204")
|
self.assertEqual(channel.result["code"], b"204")
|
||||||
|
@ -273,12 +279,12 @@ class OptionsResourceTests(unittest.TestCase):
|
||||||
"has CORS Headers header",
|
"has CORS Headers header",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_unknown_request(self):
|
def test_unknown_request(self) -> None:
|
||||||
"""A non-OPTIONS request to an unknown URL should 404."""
|
"""A non-OPTIONS request to an unknown URL should 404."""
|
||||||
channel = self._make_request(b"GET", b"/foo/")
|
channel = self._make_request(b"GET", b"/foo/")
|
||||||
self.assertEqual(channel.result["code"], b"404")
|
self.assertEqual(channel.result["code"], b"404")
|
||||||
|
|
||||||
def test_known_request(self):
|
def test_known_request(self) -> None:
|
||||||
"""A non-OPTIONS request to an known URL should query the proper resource."""
|
"""A non-OPTIONS request to an known URL should query the proper resource."""
|
||||||
channel = self._make_request(b"GET", b"/res/")
|
channel = self._make_request(b"GET", b"/res/")
|
||||||
self.assertEqual(channel.result["code"], b"200")
|
self.assertEqual(channel.result["code"], b"200")
|
||||||
|
@ -287,16 +293,17 @@ class OptionsResourceTests(unittest.TestCase):
|
||||||
|
|
||||||
class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
||||||
class TestResource(DirectServeHtmlResource):
|
class TestResource(DirectServeHtmlResource):
|
||||||
callback = None
|
callback: Optional[Callable[..., Awaitable[None]]]
|
||||||
|
|
||||||
async def _async_render_GET(self, request):
|
async def _async_render_GET(self, request: SynapseRequest) -> None:
|
||||||
|
assert self.callback is not None
|
||||||
await self.callback(request)
|
await self.callback(request)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self) -> None:
|
||||||
self.reactor = ThreadedMemoryReactorClock()
|
self.reactor = ThreadedMemoryReactorClock()
|
||||||
|
|
||||||
def test_good_response(self):
|
def test_good_response(self) -> None:
|
||||||
async def callback(request):
|
async def callback(request: SynapseRequest) -> None:
|
||||||
request.write(b"response")
|
request.write(b"response")
|
||||||
request.finish()
|
request.finish()
|
||||||
|
|
||||||
|
@ -311,13 +318,13 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
||||||
body = channel.result["body"]
|
body = channel.result["body"]
|
||||||
self.assertEqual(body, b"response")
|
self.assertEqual(body, b"response")
|
||||||
|
|
||||||
def test_redirect_exception(self):
|
def test_redirect_exception(self) -> None:
|
||||||
"""
|
"""
|
||||||
If the callback raises a RedirectException, it is turned into a 30x
|
If the callback raises a RedirectException, it is turned into a 30x
|
||||||
with the right location.
|
with the right location.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def callback(request, **kwargs):
|
async def callback(request: SynapseRequest, **kwargs: object) -> None:
|
||||||
raise RedirectException(b"/look/an/eagle", 301)
|
raise RedirectException(b"/look/an/eagle", 301)
|
||||||
|
|
||||||
res = WrapHtmlRequestHandlerTests.TestResource()
|
res = WrapHtmlRequestHandlerTests.TestResource()
|
||||||
|
@ -332,13 +339,13 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
||||||
location_headers = [v for k, v in headers if k == b"Location"]
|
location_headers = [v for k, v in headers if k == b"Location"]
|
||||||
self.assertEqual(location_headers, [b"/look/an/eagle"])
|
self.assertEqual(location_headers, [b"/look/an/eagle"])
|
||||||
|
|
||||||
def test_redirect_exception_with_cookie(self):
|
def test_redirect_exception_with_cookie(self) -> None:
|
||||||
"""
|
"""
|
||||||
If the callback raises a RedirectException which sets a cookie, that is
|
If the callback raises a RedirectException which sets a cookie, that is
|
||||||
returned too
|
returned too
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def callback(request, **kwargs):
|
async def callback(request: SynapseRequest, **kwargs: object) -> NoReturn:
|
||||||
e = RedirectException(b"/no/over/there", 304)
|
e = RedirectException(b"/no/over/there", 304)
|
||||||
e.cookies.append(b"session=yespls")
|
e.cookies.append(b"session=yespls")
|
||||||
raise e
|
raise e
|
||||||
|
@ -357,10 +364,10 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
||||||
cookies_headers = [v for k, v in headers if k == b"Set-Cookie"]
|
cookies_headers = [v for k, v in headers if k == b"Set-Cookie"]
|
||||||
self.assertEqual(cookies_headers, [b"session=yespls"])
|
self.assertEqual(cookies_headers, [b"session=yespls"])
|
||||||
|
|
||||||
def test_head_request(self):
|
def test_head_request(self) -> None:
|
||||||
"""A head request should work by being turned into a GET request."""
|
"""A head request should work by being turned into a GET request."""
|
||||||
|
|
||||||
async def callback(request):
|
async def callback(request: SynapseRequest) -> None:
|
||||||
request.write(b"response")
|
request.write(b"response")
|
||||||
request.finish()
|
request.finish()
|
||||||
|
|
||||||
|
@ -410,7 +417,7 @@ class CancellableDirectServeHtmlResource(DirectServeHtmlResource):
|
||||||
class DirectServeJsonResourceCancellationTests(unittest.TestCase):
|
class DirectServeJsonResourceCancellationTests(unittest.TestCase):
|
||||||
"""Tests for `DirectServeJsonResource` cancellation."""
|
"""Tests for `DirectServeJsonResource` cancellation."""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self) -> None:
|
||||||
self.reactor = ThreadedMemoryReactorClock()
|
self.reactor = ThreadedMemoryReactorClock()
|
||||||
self.clock = Clock(self.reactor)
|
self.clock = Clock(self.reactor)
|
||||||
self.resource = CancellableDirectServeJsonResource(self.clock)
|
self.resource = CancellableDirectServeJsonResource(self.clock)
|
||||||
|
@ -444,7 +451,7 @@ class DirectServeJsonResourceCancellationTests(unittest.TestCase):
|
||||||
class DirectServeHtmlResourceCancellationTests(unittest.TestCase):
|
class DirectServeHtmlResourceCancellationTests(unittest.TestCase):
|
||||||
"""Tests for `DirectServeHtmlResource` cancellation."""
|
"""Tests for `DirectServeHtmlResource` cancellation."""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self) -> None:
|
||||||
self.reactor = ThreadedMemoryReactorClock()
|
self.reactor = ThreadedMemoryReactorClock()
|
||||||
self.clock = Clock(self.reactor)
|
self.clock = Clock(self.reactor)
|
||||||
self.resource = CancellableDirectServeHtmlResource(self.clock)
|
self.resource = CancellableDirectServeHtmlResource(self.clock)
|
||||||
|
|
Loading…
Reference in New Issue